@daisforge/ui 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chunks/{AnalyticalWidget-Cdo6_s1Y.mjs → AnalyticalWidget-BtyWKJuu.mjs} +34 -34
- package/chunks/AnalyticalWidget-YytE3Rlw.cjs +43 -0
- package/chunks/{ApprovalCenter-DxcvzR8q.mjs → ApprovalCenter-DLKZP2AO.mjs} +2 -2
- package/chunks/{ApprovalCenter-CAcC43zn.cjs → ApprovalCenter-DdsLEipZ.cjs} +1 -1
- package/chunks/BlockTitle-DC1McGof.cjs +1 -0
- package/chunks/BlockTitle-DsXxImR6.mjs +86 -0
- package/chunks/{Container-CrB1jwqH.cjs → Container-DHnX1sHY.cjs} +1 -1
- package/chunks/{Container-Cy8w2JOq.mjs → Container-DbZwlfIM.mjs} +1 -1
- package/chunks/{EXTERNAL_PACKAGE_MODULE_sdds_finai_high_contrast__light_theme-B8FhA_zv.cjs → EXTERNAL_PACKAGE_MODULE_sdds_finai_high_contrast__light_theme-75fNjCa0.cjs} +1059 -1293
- package/chunks/{EXTERNAL_PACKAGE_MODULE_sdds_finai_high_contrast__light_theme-w2nh9o1i.mjs → EXTERNAL_PACKAGE_MODULE_sdds_finai_high_contrast__light_theme-DjDujEzF.mjs} +1060 -1294
- package/chunks/{EmptyState-B205JfZA.mjs → EmptyState-CUCseg9M.mjs} +1 -1
- package/chunks/{EmptyState-CcxlsZm0.cjs → EmptyState-DH1xawxg.cjs} +1 -1
- package/chunks/{FiltersActions-BKJJH6Mu.cjs → FiltersActions-Cw_JG2O2.cjs} +1 -1
- package/chunks/{FiltersActions-CFStLRsU.mjs → FiltersActions-UayfdMLv.mjs} +4 -4
- package/chunks/{FormSegmentGroup-CCCqRgCG.cjs → FormSegmentGroup-BYQ6yMK1.cjs} +1 -1
- package/chunks/{FormSegmentGroup-E1JurEt7.mjs → FormSegmentGroup-C9qYxYT9.mjs} +1 -1
- package/chunks/{GridDND-UMUi8M_Q.mjs → GridDND-CqvpXgCY.mjs} +2 -2
- package/chunks/{GridDND-DV-1g1sI.cjs → GridDND-DK6SAO8q.cjs} +1 -1
- package/chunks/LeftPanel-AyuV7bGS.cjs +1 -0
- package/chunks/{LeftPanel-HZu3ECqD.mjs → LeftPanel-C5SsoRJS.mjs} +47 -45
- package/chunks/{ListOfFilters-DJvnT9kw.cjs → ListOfFilters-8rHTfUXT.cjs} +1 -1
- package/chunks/{ListOfFilters-DTAZ3wfQ.mjs → ListOfFilters-B3CA32OD.mjs} +3 -3
- package/chunks/{MassActions-Z-48g81T.cjs → MassActions-5p7to0R5.cjs} +1 -1
- package/chunks/{MassActions-DSAaO1-u.mjs → MassActions-BJxR4H1S.mjs} +3 -3
- package/chunks/PageTitle-CrBeieoq.cjs +9 -0
- package/chunks/PageTitle-DkfAiZM4.mjs +133 -0
- package/chunks/{SplitView-DYHeCnl9.mjs → SplitView-BqS1Jbo4.mjs} +1 -1
- package/chunks/{SplitView-UKIBuvTi.cjs → SplitView-DNmd4sJe.cjs} +1 -1
- package/chunks/{Stories-Dlwle-SM.mjs → Stories-BnHxMCEZ.mjs} +3 -3
- package/chunks/{Stories-CZXv_Ves.cjs → Stories-UYVANawW.cjs} +1 -1
- package/chunks/Table--NExtXRi.cjs +31 -0
- package/chunks/{Table-B9OAyWAW.mjs → Table-bmvWLH9o.mjs} +2682 -2608
- package/chunks/TableCanvas-DTm2pu0r.cjs +30 -0
- package/chunks/{TableCanvas-DcoUBrgC.mjs → TableCanvas-DxcB4WOJ.mjs} +7982 -7663
- package/chunks/{TableGlide-Ch-gaROR.mjs → TableGlide-BMBq6g4-.mjs} +2297 -2198
- package/chunks/TableGlide-DtosQrHB.cjs +1 -0
- package/chunks/styles-CJ5y9FKW.mjs +132 -0
- package/chunks/styles-kUWPuNSD.cjs +2 -0
- package/chunks/utils-ChDQGRjv.cjs +25 -0
- package/chunks/{utils-YKicAHp0.mjs → utils-u1KJ37g3.mjs} +120 -108
- package/chunks/{vendor-BzEO8Fvp.cjs → vendor-BSEdLAmZ.cjs} +1049 -1309
- package/chunks/{vendor-DBRfVjyT.mjs → vendor-CA3z7N_7.mjs} +1053 -1313
- package/components/AiAgentPopover/index.cjs +1 -1
- package/components/AiAgentPopover/index.mjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetButtons/index.cjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetButtons/index.mjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetChips/index.cjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetChips/index.mjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetHeader/index.cjs +1 -1
- package/components/AnalyticalWidget/components/AnalyticalWidgetHeader/index.mjs +1 -1
- package/components/AnalyticalWidget/index.cjs +1 -1
- package/components/AnalyticalWidget/index.mjs +1 -1
- package/components/ApprovalCenter/components/index.cjs +1 -1
- package/components/ApprovalCenter/components/index.mjs +1 -1
- package/components/ApprovalCenter/index.cjs +1 -1
- package/components/ApprovalCenter/index.mjs +1 -1
- package/components/AutocompleteSearch/index.cjs +1 -1
- package/components/AutocompleteSearch/index.mjs +2 -2
- package/components/BlockGradientScroll/index.cjs +1 -1
- package/components/BlockGradientScroll/index.mjs +1 -1
- package/components/BlockTitle/BlockTitle.d.ts +1 -1
- package/components/BlockTitle/BlockTitle.types.d.ts +2 -1
- package/components/BlockTitle/index.cjs +1 -1
- package/components/BlockTitle/index.mjs +1 -1
- package/components/BlockTitle/utils/index.cjs +1 -1
- package/components/BlockTitle/utils/index.mjs +1 -1
- package/components/Collapse/index.cjs +1 -1
- package/components/Collapse/index.mjs +1 -1
- package/components/Combobox/index.cjs +1 -1
- package/components/Combobox/index.mjs +1 -1
- package/components/DrawerDF/components/styled.d.ts +1 -1
- package/components/EmptyState/components/index.cjs +1 -1
- package/components/EmptyState/components/index.mjs +1 -1
- package/components/EmptyState/index.cjs +1 -1
- package/components/EmptyState/index.mjs +1 -1
- package/components/GridDND/index.cjs +1 -1
- package/components/GridDND/index.mjs +1 -1
- package/components/GridDND/utils/index.cjs +1 -1
- package/components/GridDND/utils/index.mjs +1 -1
- package/components/IconButton/index.cjs +1 -1
- package/components/IconButton/index.mjs +1 -1
- package/components/LeftPanel/components/index.cjs +1 -1
- package/components/LeftPanel/components/index.mjs +1 -1
- package/components/LeftPanel/hooks/index.cjs +1 -1
- package/components/LeftPanel/hooks/index.mjs +1 -1
- package/components/LeftPanel/index.cjs +1 -1
- package/components/LeftPanel/index.mjs +1 -1
- package/components/LeftPanel/styled.d.ts +1 -0
- package/components/LeftPanel/utils/index.cjs +1 -1
- package/components/LeftPanel/utils/index.mjs +1 -1
- package/components/ListOfFilters/index.cjs +1 -1
- package/components/ListOfFilters/index.mjs +1 -1
- package/components/MassActions/hooks/index.cjs +1 -1
- package/components/MassActions/hooks/index.mjs +1 -1
- package/components/MassActions/index.cjs +1 -1
- package/components/MassActions/index.mjs +1 -1
- package/components/ModalDF/index.cjs +1 -1
- package/components/ModalDF/index.mjs +1 -1
- package/components/Notification/index.cjs +1 -1
- package/components/Notification/index.mjs +2 -2
- package/components/NumberFormat/NumberFormat.d.ts +48 -0
- package/components/NumberFormatAmount/NumberFormatAmount.styled.d.ts +48 -0
- package/components/PageTitle/PageTitle.styled.d.ts +3 -1
- package/components/PageTitle/index.cjs +1 -1
- package/components/PageTitle/index.mjs +1 -1
- package/components/PageTitle/utils/index.cjs +1 -1
- package/components/PageTitle/utils/index.mjs +1 -1
- package/components/PopoverDF/index.cjs +1 -1
- package/components/PopoverDF/index.mjs +1 -1
- package/components/PopupDF/index.cjs +1 -1
- package/components/PopupDF/index.mjs +1 -1
- package/components/SplitView/index.cjs +1 -1
- package/components/SplitView/index.mjs +1 -1
- package/components/SplitView/utils/index.cjs +1 -1
- package/components/SplitView/utils/index.mjs +1 -1
- package/components/Stories/components/StoriesBanner/index.cjs +1 -1
- package/components/Stories/components/StoriesBanner/index.mjs +1 -1
- package/components/Stories/components/StoriesContent/index.cjs +1 -1
- package/components/Stories/components/StoriesContent/index.mjs +1 -1
- package/components/Stories/components/StoriesPreview/index.cjs +1 -1
- package/components/Stories/components/StoriesPreview/index.mjs +1 -1
- package/components/Stories/components/StoriesProgress/index.cjs +1 -1
- package/components/Stories/components/StoriesProgress/index.mjs +1 -1
- package/components/Stories/components/StoriesViewer/index.cjs +1 -1
- package/components/Stories/components/StoriesViewer/index.mjs +1 -1
- package/components/Stories/index.cjs +1 -1
- package/components/Stories/index.mjs +1 -1
- package/components/Table/components/TableDropdown/index.cjs +1 -1
- package/components/Table/components/TableDropdown/index.mjs +1 -1
- package/components/Table/feature-collapse-table/index.cjs +1 -1
- package/components/Table/feature-collapse-table/index.mjs +2 -2
- package/components/Table/feature-column-control/ColumnsList/index.cjs +1 -1
- package/components/Table/feature-column-control/ColumnsList/index.mjs +2 -2
- package/components/Table/feature-column-control/index.cjs +1 -1
- package/components/Table/feature-column-control/index.mjs +3 -3
- package/components/Table/feature-columns-grouping/index.cjs +1 -1
- package/components/Table/feature-columns-grouping/index.mjs +1 -1
- package/components/Table/feature-context-menu/index.cjs +1 -1
- package/components/Table/feature-context-menu/index.mjs +1 -1
- package/components/Table/feature-edit/index.cjs +1 -1
- package/components/Table/feature-edit/index.mjs +1 -1
- package/components/Table/feature-edit/textEditor.styled.d.ts +48 -0
- package/components/Table/feature-filtering/combobox/combobox.d.ts +3 -2
- package/components/Table/feature-filtering/combobox/index.cjs +1 -1
- package/components/Table/feature-filtering/combobox/index.d.ts +4 -2
- package/components/Table/feature-filtering/combobox/index.mjs +7 -3
- package/components/Table/feature-filtering/filter-list-block/index.cjs +1 -1
- package/components/Table/feature-filtering/filter-list-block/index.mjs +1 -1
- package/components/Table/feature-filtering/header-filter-button/filter-component-in-popover.d.ts +1 -2
- package/components/Table/feature-filtering/header-filter-button/index.cjs +1 -1
- package/components/Table/feature-filtering/header-filter-button/index.mjs +1 -1
- package/components/Table/feature-filtering/index.cjs +1 -1
- package/components/Table/feature-filtering/index.d.ts +1 -1
- package/components/Table/feature-filtering/index.mjs +13 -9
- package/components/Table/feature-filtering/render-slot.d.ts +5 -0
- package/components/Table/feature-filtering/sidebar-filter-block/index.cjs +1 -1
- package/components/Table/feature-filtering/sidebar-filter-block/index.mjs +2 -2
- package/components/Table/feature-filtering/use-focus-search-input.d.ts +2 -0
- package/components/Table/feature-infinity-scroll/index.cjs +1 -1
- package/components/Table/feature-infinity-scroll/index.mjs +1 -1
- package/components/Table/feature-key-text/index.cjs +1 -1
- package/components/Table/feature-key-text/index.mjs +3 -3
- package/components/Table/feature-pagination/index.cjs +1 -1
- package/components/Table/feature-pagination/index.mjs +3 -3
- package/components/Table/feature-reorder-columns/handlers.d.ts +4 -0
- package/components/Table/feature-right-sidebar/index.cjs +1 -1
- package/components/Table/feature-right-sidebar/index.mjs +1 -1
- package/components/Table/feature-row-detail/index.cjs +1 -1
- package/components/Table/feature-row-detail/index.mjs +1 -1
- package/components/Table/feature-row-instruments/index.cjs +1 -1
- package/components/Table/feature-row-instruments/index.mjs +5 -5
- package/components/Table/feature-row-size/index.cjs +1 -1
- package/components/Table/feature-row-size/index.mjs +2 -2
- package/components/Table/feature-rows-grouping/index.cjs +1 -1
- package/components/Table/feature-rows-grouping/index.mjs +1 -1
- package/components/Table/feature-searching/index.cjs +1 -1
- package/components/Table/feature-searching/index.mjs +1 -1
- package/components/Table/feature-select-row/index.cjs +1 -1
- package/components/Table/feature-select-row/index.mjs +1 -1
- package/components/Table/feature-sorting/index.cjs +1 -1
- package/components/Table/feature-sorting/index.mjs +1 -1
- package/components/Table/feature-table-settings/index.cjs +1 -1
- package/components/Table/feature-table-settings/index.mjs +1 -1
- package/components/Table/feature-tree/index.cjs +1 -1
- package/components/Table/feature-tree/index.mjs +2 -2
- package/components/Table/index.cjs +1 -1
- package/components/Table/index.d.ts +1 -1
- package/components/Table/index.mjs +43 -39
- package/components/Table/renders/formatCell/index.cjs +1 -1
- package/components/Table/renders/formatCell/index.mjs +3 -3
- package/components/Table/styles/index.cjs +1 -1
- package/components/Table/styles/index.mjs +9 -9
- package/components/Table/table-hooks/index.cjs +1 -1
- package/components/Table/table-hooks/index.mjs +3 -3
- package/components/Table/types/column-config.type.d.ts +1 -0
- package/components/Table/types/index.cjs +1 -1
- package/components/Table/types/index.mjs +1 -1
- package/components/Table/utils/index.cjs +1 -1
- package/components/Table/utils/index.mjs +4 -4
- package/components/Table/widgets/control-block/index.cjs +1 -1
- package/components/Table/widgets/control-block/index.mjs +1 -1
- package/components/Table/widgets/control-block/right-side/index.cjs +1 -1
- package/components/Table/widgets/control-block/right-side/index.mjs +1 -1
- package/components/Table/widgets/index.cjs +1 -1
- package/components/Table/widgets/index.mjs +1 -1
- package/components/Table/widgets/mass-actions/index.cjs +1 -1
- package/components/Table/widgets/mass-actions/index.mjs +1 -1
- package/components/TableCanvas/TableGlideInstance/adapters/column/index.cjs +1 -1
- package/components/TableCanvas/TableGlideInstance/adapters/column/index.mjs +1 -1
- package/components/TableCanvas/TableGlideInstance/adapters/index.cjs +1 -1
- package/components/TableCanvas/TableGlideInstance/adapters/index.mjs +1 -1
- package/components/TableCanvas/TableGlideInstance/index.cjs +1 -1
- package/components/TableCanvas/TableGlideInstance/index.mjs +2 -2
- package/components/TableCanvas/TableGlideInstance/utils/column/index.cjs +1 -1
- package/components/TableCanvas/TableGlideInstance/utils/column/index.mjs +1 -1
- package/components/TableCanvas/TableGlideInstance/utils/index.cjs +1 -1
- package/components/TableCanvas/TableGlideInstance/utils/index.mjs +1 -1
- package/components/TableCanvas/components/SplitIconButton/index.cjs +1 -1
- package/components/TableCanvas/components/SplitIconButton/index.mjs +1 -1
- package/components/TableCanvas/components/TableDropdown/index.cjs +1 -1
- package/components/TableCanvas/components/TableDropdown/index.mjs +1 -1
- package/components/TableCanvas/feature-borders/buildBorderCallbacks.d.ts +16 -0
- package/components/TableCanvas/feature-borders/useBorders.d.ts +14 -0
- package/components/TableCanvas/feature-cell-transfer/index.cjs +1 -1
- package/components/TableCanvas/feature-cell-transfer/index.mjs +1 -1
- package/components/TableCanvas/feature-collapse-table/index.cjs +1 -1
- package/components/TableCanvas/feature-collapse-table/index.mjs +1 -1
- package/components/TableCanvas/feature-column-control/ColumnsList/index.cjs +1 -1
- package/components/TableCanvas/feature-column-control/ColumnsList/index.mjs +1 -1
- package/components/TableCanvas/feature-column-control/columnsRenderOrder.d.ts +1 -0
- package/components/TableCanvas/feature-column-control/groupDepth.d.ts +14 -0
- package/components/TableCanvas/feature-column-control/hiddenBoundaries.d.ts +4 -0
- package/components/TableCanvas/feature-column-control/index.cjs +1 -1
- package/components/TableCanvas/feature-column-control/index.d.ts +2 -0
- package/components/TableCanvas/feature-column-control/index.mjs +4 -2
- package/components/TableCanvas/feature-column-control/types.d.ts +7 -0
- package/components/TableCanvas/feature-column-control/useHiddenColumnsIndicator.d.ts +19 -0
- package/components/TableCanvas/feature-columns-grouping/index.cjs +1 -1
- package/components/TableCanvas/feature-columns-grouping/index.mjs +1 -1
- package/components/TableCanvas/feature-columns-grouping/useLastLvlColumnConfig.d.ts +1 -0
- package/components/TableCanvas/feature-content-state/index.cjs +1 -1
- package/components/TableCanvas/feature-content-state/index.mjs +1 -1
- package/components/TableCanvas/feature-context-menu/index.cjs +1 -1
- package/components/TableCanvas/feature-context-menu/index.mjs +1 -1
- package/components/TableCanvas/feature-edit/index.cjs +1 -1
- package/components/TableCanvas/feature-edit/index.mjs +3 -3
- package/components/TableCanvas/feature-filtering/combobox/combobox.d.ts +3 -2
- package/components/TableCanvas/feature-filtering/combobox/index.cjs +1 -1
- package/components/TableCanvas/feature-filtering/combobox/index.d.ts +4 -2
- package/components/TableCanvas/feature-filtering/combobox/index.mjs +7 -3
- package/components/TableCanvas/feature-filtering/filter-list-block/index.cjs +1 -1
- package/components/TableCanvas/feature-filtering/filter-list-block/index.mjs +1 -1
- package/components/TableCanvas/feature-filtering/header-filter-button/filter-component-in-popover.d.ts +1 -2
- package/components/TableCanvas/feature-filtering/header-filter-button/index.cjs +1 -1
- package/components/TableCanvas/feature-filtering/header-filter-button/index.mjs +2 -2
- package/components/TableCanvas/feature-filtering/index.cjs +1 -1
- package/components/TableCanvas/feature-filtering/index.d.ts +1 -1
- package/components/TableCanvas/feature-filtering/index.mjs +12 -8
- package/components/TableCanvas/feature-filtering/render-slot.d.ts +5 -0
- package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.cjs +1 -1
- package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.mjs +1 -1
- package/components/TableCanvas/feature-infinity-scroll/index.cjs +1 -1
- package/components/TableCanvas/feature-infinity-scroll/index.mjs +1 -1
- package/components/TableCanvas/feature-key-text/index.cjs +1 -1
- package/components/TableCanvas/feature-key-text/index.mjs +1 -1
- package/components/TableCanvas/feature-notifications/index.cjs +1 -1
- package/components/TableCanvas/feature-notifications/index.mjs +1 -1
- package/components/TableCanvas/feature-pagination/index.cjs +1 -1
- package/components/TableCanvas/feature-pagination/index.mjs +2 -2
- package/components/TableCanvas/feature-popover-table/context/index.cjs +1 -1
- package/components/TableCanvas/feature-popover-table/context/index.mjs +1 -1
- package/components/TableCanvas/feature-popover-table/hooks/index.cjs +1 -1
- package/components/TableCanvas/feature-popover-table/hooks/index.mjs +1 -1
- package/components/TableCanvas/feature-popover-table/index.cjs +1 -1
- package/components/TableCanvas/feature-popover-table/index.mjs +8 -8
- package/components/TableCanvas/feature-popover-table/utils/index.cjs +1 -1
- package/components/TableCanvas/feature-popover-table/utils/index.mjs +1 -1
- package/components/TableCanvas/feature-reorder-columns/handlers.d.ts +4 -0
- package/components/TableCanvas/feature-right-sidebar/index.cjs +1 -1
- package/components/TableCanvas/feature-right-sidebar/index.mjs +1 -1
- package/components/TableCanvas/feature-row-detail/index.cjs +1 -1
- package/components/TableCanvas/feature-row-detail/index.mjs +1 -1
- package/components/TableCanvas/feature-row-instruments/index.cjs +1 -1
- package/components/TableCanvas/feature-row-instruments/index.mjs +1 -1
- package/components/TableCanvas/feature-row-markers/index.cjs +1 -1
- package/components/TableCanvas/feature-row-markers/index.mjs +1 -1
- package/components/TableCanvas/feature-row-size/index.cjs +1 -1
- package/components/TableCanvas/feature-row-size/index.mjs +3 -3
- package/components/TableCanvas/feature-rows-grouping/index.cjs +1 -1
- package/components/TableCanvas/feature-rows-grouping/index.mjs +1 -1
- package/components/TableCanvas/feature-searching/index.cjs +1 -1
- package/components/TableCanvas/feature-searching/index.mjs +1 -1
- package/components/TableCanvas/feature-select-row/index.cjs +1 -1
- package/components/TableCanvas/feature-select-row/index.mjs +1 -1
- package/components/TableCanvas/feature-sorting/index.cjs +1 -1
- package/components/TableCanvas/feature-sorting/index.mjs +1 -1
- package/components/TableCanvas/feature-table-settings/index.cjs +1 -1
- package/components/TableCanvas/feature-table-settings/index.mjs +1 -1
- package/components/TableCanvas/feature-tooltip/constants.d.ts +1 -0
- package/components/TableCanvas/feature-tooltip/index.cjs +1 -1
- package/components/TableCanvas/feature-tooltip/index.mjs +2 -2
- package/components/TableCanvas/feature-tooltip/types.d.ts +2 -0
- package/components/TableCanvas/feature-tooltip/utils/index.cjs +1 -1
- package/components/TableCanvas/feature-tooltip/utils/index.mjs +5 -5
- package/components/TableCanvas/feature-tree/handlers.d.ts +1 -0
- package/components/TableCanvas/feature-tree/index.cjs +1 -1
- package/components/TableCanvas/feature-tree/index.mjs +1 -1
- package/components/TableCanvas/feature-tree/tree-disclosure-icons.d.ts +65 -0
- package/components/TableCanvas/index.cjs +1 -1
- package/components/TableCanvas/index.d.ts +1 -1
- package/components/TableCanvas/index.mjs +64 -60
- package/components/TableCanvas/renders/formatCell/index.cjs +1 -1
- package/components/TableCanvas/renders/formatCell/index.mjs +1 -1
- package/components/TableCanvas/renders/rowIconConfig.d.ts +6 -0
- package/components/TableCanvas/renders/styleConstants.d.ts +3 -1
- package/components/TableCanvas/renders/styled.d.ts +0 -1
- package/components/TableCanvas/styles/index.cjs +1 -1
- package/components/TableCanvas/styles/index.mjs +1 -1
- package/components/TableCanvas/table-hooks/index.cjs +1 -1
- package/components/TableCanvas/table-hooks/index.mjs +11 -11
- package/components/TableCanvas/table-hooks/useColumns.d.ts +1 -0
- package/components/TableCanvas/types/column-config.type.d.ts +1 -0
- package/components/TableCanvas/types/index.cjs +1 -1
- package/components/TableCanvas/types/index.mjs +2 -2
- package/components/TableCanvas/types/table-config.type.d.ts +29 -0
- package/components/TableCanvas/utils/index.cjs +1 -1
- package/components/TableCanvas/utils/index.mjs +2 -2
- package/components/TableCanvas/widgets/control-block/compression/index.cjs +1 -1
- package/components/TableCanvas/widgets/control-block/compression/index.mjs +2 -2
- package/components/TableCanvas/widgets/control-block/index.cjs +1 -1
- package/components/TableCanvas/widgets/control-block/index.mjs +2 -2
- package/components/TableCanvas/widgets/control-block/right-side/index.cjs +1 -1
- package/components/TableCanvas/widgets/control-block/right-side/index.mjs +1 -1
- package/components/TableCanvas/widgets/index.cjs +1 -1
- package/components/TableCanvas/widgets/index.mjs +5 -5
- package/components/TableCanvas/widgets/mass-actions/hooks/index.cjs +1 -1
- package/components/TableCanvas/widgets/mass-actions/hooks/index.mjs +8 -8
- package/components/TableCanvas/widgets/mass-actions/index.cjs +1 -1
- package/components/TableCanvas/widgets/mass-actions/index.mjs +1 -1
- package/components/TableCanvasSharedConstants/index.cjs +1 -1
- package/components/TableCanvasSharedConstants/index.d.ts +1 -0
- package/components/TableCanvasSharedConstants/index.mjs +4 -3
- package/components/TableContract/index.cjs +1 -1
- package/components/TableContract/index.mjs +2 -2
- package/components/TableGlide/constants.d.ts +1 -1
- package/components/TableGlide/hooks/selection/index.cjs +1 -1
- package/components/TableGlide/hooks/selection/index.d.ts +1 -2
- package/components/TableGlide/hooks/selection/index.mjs +6 -7
- package/components/TableGlide/hooks/selection/useColoringLayers.d.ts +25 -0
- package/components/TableGlide/hooks/useHoverState.d.ts +18 -0
- package/components/TableGlide/hooks/useItemHoveredHandler.d.ts +4 -1
- package/components/TableGlide/index.cjs +1 -1
- package/components/TableGlide/index.mjs +9 -9
- package/components/TableGlide/lib/canvas/cells/buttons/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/cells/buttons/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/cells/iconSprites/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/cells/iconSprites/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/cells/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/cells/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/cells/renderer/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/cells/renderer/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/components/index.d.ts +1 -0
- package/components/TableGlide/lib/canvas/core/helpers/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/core/helpers/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/core/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/core/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/hooks/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/hooks/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/miniflex/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/miniflex/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/primitives/CanvasEmbedIconButton.d.ts +2 -0
- package/components/TableGlide/lib/canvas/primitives/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/primitives/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/utils/index.cjs +1 -1
- package/components/TableGlide/lib/canvas/utils/index.mjs +1 -1
- package/components/TableGlide/lib/canvas/utils/portalHoverEvents.d.ts +1 -0
- package/components/TableGlide/theming/custom-colors.d.ts +1 -1
- package/components/TableGlide/theming/glide-colors.d.ts +1 -0
- package/components/TableGlide/theming/index.cjs +1 -1
- package/components/TableGlide/theming/index.mjs +3 -3
- package/components/TableGlide/theming/size-tokens.d.ts +1 -1
- package/components/TableGlide/theming/sizes.d.ts +2 -2
- package/components/TableGlide/types.d.ts +1 -3
- package/components/TableTabs/index.cjs +1 -1
- package/components/TableTabs/index.mjs +1 -1
- package/components/Tooltip/index.cjs +1 -1
- package/components/Tooltip/index.mjs +1 -1
- package/components/TourWidget/index.cjs +2 -2
- package/components/TourWidget/index.mjs +4 -4
- package/components/Typography/index.cjs +1 -1
- package/components/Typography/index.mjs +1 -1
- package/components/Widget/index.cjs +1 -1
- package/components/Widget/index.mjs +2 -2
- package/formComponents/FormCombobox/index.cjs +1 -1
- package/formComponents/FormCombobox/index.mjs +1 -1
- package/formComponents/FormRadioGroupBox/index.cjs +1 -1
- package/formComponents/FormRadioGroupBox/index.mjs +1 -1
- package/formComponents/FormSegments/index.cjs +1 -1
- package/formComponents/FormSegments/index.mjs +1 -1
- package/formComponents/FormSwitch/index.cjs +1 -1
- package/formComponents/FormSwitch/index.mjs +1 -1
- package/index.cjs +1 -1
- package/index.mjs +1778 -1773
- package/layouts/Container/index.cjs +1 -1
- package/layouts/Container/index.mjs +1 -1
- package/layouts/Container/lib/utils/index.cjs +1 -1
- package/layouts/Container/lib/utils/index.mjs +1 -1
- package/layouts/ErrorPage/index.cjs +1 -1
- package/layouts/ErrorPage/index.mjs +1 -1
- package/layouts/FiltersActions/hooks/index.cjs +1 -1
- package/layouts/FiltersActions/hooks/index.mjs +1 -1
- package/layouts/FiltersActions/index.cjs +1 -1
- package/layouts/FiltersActions/index.mjs +1 -1
- package/layouts/Layout/index.cjs +1 -1
- package/layouts/Layout/index.mjs +1 -1
- package/layouts/PageLayout/index.cjs +1 -1
- package/layouts/PageLayout/index.mjs +1 -1
- package/mcp-data/component-index.json +945 -137
- package/mixins/index.cjs +1 -1
- package/mixins/index.mjs +1 -1
- package/package.json +10 -10
- package/styles/index.cjs +1 -1
- package/styles/index.mjs +1 -1
- package/themes/index.cjs +1 -1
- package/themes/index.mjs +2 -2
- package/utils/breakpoint/index.cjs +1 -1
- package/utils/breakpoint/index.mjs +1 -1
- package/utils/clickStream/index.cjs +1 -1
- package/utils/clickStream/index.mjs +1 -1
- package/utils/eventBus/index.cjs +1 -1
- package/utils/eventBus/index.mjs +1 -1
- package/utils/hooks/index.cjs +1 -1
- package/utils/hooks/index.mjs +1 -1
- package/utils/index.cjs +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.mjs +30 -29
- package/utils/react/getMFReactDOMClient.d.ts +7 -0
- package/utils/react/index.cjs +1 -0
- package/utils/react/index.d.ts +1 -0
- package/utils/react/index.mjs +4 -0
- package/utils/styles/index.cjs +1 -1
- package/utils/styles/index.mjs +1 -1
- package/chunks/AnalyticalWidget-wke3Jm3X.cjs +0 -43
- package/chunks/BlockTitle-BEIxiECX.cjs +0 -1
- package/chunks/BlockTitle-BZxOEdTc.mjs +0 -85
- package/chunks/LeftPanel-B3-ySDMW.cjs +0 -1
- package/chunks/PageTitle-Bh3g6FUT.cjs +0 -1
- package/chunks/PageTitle-CaqXfrrQ.mjs +0 -123
- package/chunks/Table-BwhzcFX1.cjs +0 -31
- package/chunks/TableCanvas-MMWMrYiV.cjs +0 -30
- package/chunks/TableGlide-TYzM2bEB.cjs +0 -1
- package/chunks/styles-BBVEBDDw.mjs +0 -132
- package/chunks/styles-C-pJNMSQ.cjs +0 -2
- package/chunks/utils-CUW5bd8S.cjs +0 -25
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-09-
|
|
3
|
-
"libVersion": "1.
|
|
2
|
+
"generatedAt": "2026-09-21T13:53:31.646Z",
|
|
3
|
+
"libVersion": "1.20.0",
|
|
4
4
|
"components": {
|
|
5
5
|
"Accordion": {
|
|
6
6
|
"name": "Accordion",
|
|
@@ -128,6 +128,18 @@
|
|
|
128
128
|
"required": false,
|
|
129
129
|
"description": ""
|
|
130
130
|
},
|
|
131
|
+
{
|
|
132
|
+
"name": "defaultIconContent",
|
|
133
|
+
"type": "AccordionItemDefaultIconContent | undefined",
|
|
134
|
+
"required": false,
|
|
135
|
+
"description": ""
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "defaultIconPlacement",
|
|
139
|
+
"type": "AccordionItemDefaultIconPlacement | undefined",
|
|
140
|
+
"required": false,
|
|
141
|
+
"description": ""
|
|
142
|
+
},
|
|
131
143
|
{
|
|
132
144
|
"name": "eventKey",
|
|
133
145
|
"type": "number | undefined",
|
|
@@ -393,6 +405,12 @@
|
|
|
393
405
|
"required": false,
|
|
394
406
|
"description": "Предотвратить автоматическое изменение положения."
|
|
395
407
|
},
|
|
408
|
+
{
|
|
409
|
+
"name": "stretchHeight",
|
|
410
|
+
"type": "boolean | undefined",
|
|
411
|
+
"required": false,
|
|
412
|
+
"description": "Растянуть Popover до границы доступной области по вертикали."
|
|
413
|
+
},
|
|
396
414
|
{
|
|
397
415
|
"name": "target",
|
|
398
416
|
"type": "string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | ((instance: HTMLElement | null) => void) | React.RefObject<HTMLElement> | null | undefined",
|
|
@@ -863,7 +881,7 @@
|
|
|
863
881
|
"type": "\"default\" | \"secondary\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | \"info\" | undefined",
|
|
864
882
|
"required": false,
|
|
865
883
|
"description": "",
|
|
866
|
-
"default": "'
|
|
884
|
+
"default": "'default'"
|
|
867
885
|
}
|
|
868
886
|
]
|
|
869
887
|
},
|
|
@@ -2904,6 +2922,12 @@
|
|
|
2904
2922
|
"description": "Размер заголовка",
|
|
2905
2923
|
"default": "'H2'"
|
|
2906
2924
|
},
|
|
2925
|
+
{
|
|
2926
|
+
"name": "titleTooltipProps",
|
|
2927
|
+
"type": "Omit<TooltipProps, \"text\" | \"target\" | \"trigger\" | \"opened\"> | undefined",
|
|
2928
|
+
"required": false,
|
|
2929
|
+
"description": "Пропсы тултипа, которым оборачивается обрезанный `title`."
|
|
2930
|
+
},
|
|
2907
2931
|
{
|
|
2908
2932
|
"name": "topSlot",
|
|
2909
2933
|
"type": "BlockTitleAdaptiveSlot",
|
|
@@ -2928,8 +2952,8 @@
|
|
|
2928
2952
|
"page heading",
|
|
2929
2953
|
"шапка блока"
|
|
2930
2954
|
],
|
|
2931
|
-
"docs": "# BlockTitle\n\nКомпонент заголовка блока с поддержкой слотов для дополнительных элементов и кнопки «назад».\n\n## Ключевые особенности\n\n- Настраиваемый размер заголовка через вариант типографики (`titleSize`)\n- Описание под заголовком (`description`)\n- Слоты: `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot`\n- Кнопка «назад» через `onBackButtonClick`\n- Кастомизация контейнера через `containerProps` (Box с `$css`)\n\n## Особенности\n\n- Компонент можно стилизовать: обернув в `styled`, используя `$css` в `containerProps`, или используя объект `blockTitleClassNames` для обращения к подэлементам\n- Слоты `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<BlockTitle title=\"Title\" titleRightSlot={<IconPlasma size=\"s\" />} />\n```\n\nЕсли в слоте есть иконка, Badge или кнопки, передавайте callback и используйте размеры из аргумента:\n\n```tsx\n<BlockTitle\n title=\"Страница\"\n titleSize=\"H4\"\n titleRightSlot={({ titleBadgeSize }) => (\n <Badge size={titleBadgeSize} view=\"default\" text=\"Label\" />\n )}\n rightSlot={({ buttonSize, actionIconSize }) => (\n <div style={{ display: 'flex', gap: s.x4 }}>\n <IconButton size={buttonSize} view=\"secondary\">\n <IconDotsVerticalCenteredOutline\n size={actionIconSize}\n color=\"inherit\"\n />\n </IconButton>\n <Button size={buttonSize} view=\"secondary\">\n Label\n </Button>\n <Button size={buttonSize} view=\"accent\">\n Label\n </Button>\n </div>\n )}\n/>\n```\n\nРазмеры, которые приходят в callback (в зависимости от viewport):\n\n```\n| Поле | <= 1280px | > 1280px |\n| -------------------------------------------- | --------- | -------- |\n| buttonSize | xs | s |\n| actionIconSize | xs | s |\n| titleIconSize (для H4/H5) | xs | s |\n| titleBadgeSize (для H4/H5) | s | m |\n| titleIconSize (для остальных) | s | s |\n| titleBadgeSize (для остальных) | m | m |\n```\n\n> Подробнее о типах и пропсах — [BlockTitle API](?path=/docs/композиции-blocktitle-api--docs)",
|
|
2932
|
-
"apiDocs": "# BlockTitle API\n\n## BlockTitleProps\n\n```typescript\ntype BlockTitleProps = {\n /**\n * Текст заголовка\n */\n title?: string;\n /**\n * Размер заголовка\n */\n titleSize?: ComponentProps<typeof Typography>['variant'];\n /**\n * Иконка слева от заголовка (обычно используется иконка)\n */\n titleLeftSlot?: BlockTitleAdaptiveSlot;\n /**\n * Иконка справа от заголовка (обычно используется иконка)\n */\n titleRightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Текст Заголовка\n */\n description?: string;\n /**\n * Слот для верхней части\n */\n topSlot?: BlockTitleAdaptiveSlot;\n /**\n * Слот для правой части\n */\n rightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Отключает принудительный адаптив компонента на viewport <= 1280px.\n *\n * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n *\n * @remarks\n * При `true` компонент использует desktop-размеры для слотов и кнопки назад даже на viewport <= 1280px.\n * Это временный escape hatch, не основной сценарий использования.\n *\n * @default false\n */\n disableMediaAdaptive?: boolean;\n /**\n * Передача props в контейнер\n */\n containerProps?: ComponentProps<typeof Box>;\n /**\n * Callback при клике на кнопку со стрелкой назад слева от заголовка\n */\n onBackButtonClick?: () => void;\n};\n```\n\n## BlockTitleSlotSizesProps\n\n```typescript\ntype BlockTitleSlotSizesProps = {\n /**\n * Размер иконки рядом с заголовком\n */\n titleIconSize: 's' | 'xs';\n /**\n * Размер Badge рядом с заголовком\n */\n titleBadgeSize: 'm' | 's';\n /**\n * Размер кнопок в правом слоте\n */\n buttonSize: 's' | 'xs';\n /**\n * Размер иконок внутри кнопок в правом слоте\n */\n actionIconSize: 's' | 'xs';\n};\n```\n\n## BlockTitleAdaptiveSlot\n\n```typescript\ntype BlockTitleAdaptiveSlot =\n | ReactNode\n | ((props: BlockTitleSlotSizesProps) => ReactNode);\n```",
|
|
2955
|
+
"docs": "# BlockTitle\n\nКомпонент заголовка блока с поддержкой слотов для дополнительных элементов и кнопки «назад».\n\n## Ключевые особенности\n\n- Настраиваемый размер заголовка через вариант типографики (`titleSize`)\n- Описание под заголовком (`description`)\n- Слоты: `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot`\n- Настройка тултипа обрезанного заголовка (ширина, позиция) через `titleTooltipProps`\n- Кнопка «назад» через `onBackButtonClick`\n- Кастомизация контейнера через `containerProps` (Box с `$css`)\n\n## Особенности\n\n- Компонент можно стилизовать: обернув в `styled`, используя `$css` в `containerProps`, или используя объект `blockTitleClassNames` для обращения к подэлементам\n- Слоты `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Тултип заголовка\n\n`title` оборачивается в `TypographyWithAutoTooltip`: если текст не помещается в две строки, при наведении показывается тултип с полным заголовком. По умолчанию ширина тултипа не ограничена, поэтому длинный заголовок вытягивается в одну строку. Ограничить ширину и задать позицию можно через `titleTooltipProps`:\n\n```tsx\n<BlockTitle\n title=\"Очень длинный заголовок страницы\"\n titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n/>\n```\n\n`titleTooltipProps` принимает пропсы `Tooltip` (кроме `text`, `target`, `trigger`, `opened`, которыми управляет сам компонент): `maxWidth`, `minWidth`, `placement`, `view`, `offset`, `mouseEnterDelay` и другие.\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<BlockTitle title=\"Title\" titleRightSlot={<IconPlasma size=\"s\" />} />\n```\n\nЕсли в слоте есть иконка, Badge или кнопки, передавайте callback и используйте размеры из аргумента:\n\n```tsx\n<BlockTitle\n title=\"Страница\"\n titleSize=\"H4\"\n titleRightSlot={({ titleBadgeSize }) => (\n <Badge size={titleBadgeSize} view=\"default\" text=\"Label\" />\n )}\n rightSlot={({ buttonSize, actionIconSize }) => (\n <div style={{ display: 'flex', gap: s.x4 }}>\n <IconButton size={buttonSize} view=\"secondary\">\n <IconDotsVerticalCenteredOutline\n size={actionIconSize}\n color=\"inherit\"\n />\n </IconButton>\n <Button size={buttonSize} view=\"secondary\">\n Label\n </Button>\n <Button size={buttonSize} view=\"accent\">\n Label\n </Button>\n </div>\n )}\n/>\n```\n\nРазмеры, которые приходят в callback (в зависимости от viewport):\n\n```\n| Поле | <= 1280px | > 1280px |\n| -------------------------------------------- | --------- | -------- |\n| buttonSize | xs | s |\n| actionIconSize | xs | s |\n| titleIconSize (для H4/H5) | xs | s |\n| titleBadgeSize (для H4/H5) | s | m |\n| titleIconSize (для остальных) | s | s |\n| titleBadgeSize (для остальных) | m | m |\n```\n\n> Подробнее о типах и пропсах — [BlockTitle API](?path=/docs/композиции-blocktitle-api--docs)",
|
|
2956
|
+
"apiDocs": "# BlockTitle API\n\n## BlockTitleProps\n\n```typescript\ntype BlockTitleProps = {\n /**\n * Текст заголовка\n */\n title?: string;\n /**\n * Размер заголовка\n */\n titleSize?: ComponentProps<typeof Typography>['variant'];\n /**\n * Пропсы тултипа, которым оборачивается обрезанный `title`.\n *\n * @remarks\n * Тултип показывается автоматически, когда `title` не помещается в две строки.\n * По умолчанию ширина тултипа не ограничена, из-за чего длинный заголовок\n * растягивается в одну строку — ограничьте её через `maxWidth`.\n *\n * @example\n * ```tsx\n * <BlockTitle\n * title=\"Очень длинный заголовок\"\n * titleTooltipProps={{ maxWidth: '300px', placement: 'auto-start' }}\n * />\n * ```\n */\n titleTooltipProps?: TypographyWithAutoTooltipProps<'H2'>['tooltipProps'];\n /**\n * Иконка слева от заголовка (обычно используется иконка)\n */\n titleLeftSlot?: BlockTitleAdaptiveSlot;\n /**\n * Иконка справа от заголовка (обычно используется иконка)\n */\n titleRightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Текст Заголовка\n */\n description?: string;\n /**\n * Слот для верхней части\n */\n topSlot?: BlockTitleAdaptiveSlot;\n /**\n * Слот для правой части\n */\n rightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Отключает принудительный адаптив компонента на viewport <= 1280px.\n *\n * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n *\n * @remarks\n * При `true` компонент использует desktop-размеры для слотов и кнопки назад даже на viewport <= 1280px.\n * Это временный escape hatch, не основной сценарий использования.\n *\n * @default false\n */\n disableMediaAdaptive?: boolean;\n /**\n * Передача props в контейнер\n */\n containerProps?: ComponentProps<typeof Box>;\n /**\n * Callback при клике на кнопку со стрелкой назад слева от заголовка\n */\n onBackButtonClick?: () => void;\n};\n```\n\n## BlockTitleSlotSizesProps\n\n```typescript\ntype BlockTitleSlotSizesProps = {\n /**\n * Размер иконки рядом с заголовком\n */\n titleIconSize: 's' | 'xs';\n /**\n * Размер Badge рядом с заголовком\n */\n titleBadgeSize: 'm' | 's';\n /**\n * Размер кнопок в правом слоте\n */\n buttonSize: 's' | 'xs';\n /**\n * Размер иконок внутри кнопок в правом слоте\n */\n actionIconSize: 's' | 'xs';\n};\n```\n\n## BlockTitleAdaptiveSlot\n\n```typescript\ntype BlockTitleAdaptiveSlot =\n | ReactNode\n | ((props: BlockTitleSlotSizesProps) => ReactNode);\n```",
|
|
2933
2957
|
"curatedStories": [
|
|
2934
2958
|
{
|
|
2935
2959
|
"exportName": "BlockTitleSlots",
|
|
@@ -2960,6 +2984,12 @@
|
|
|
2960
2984
|
"displayName": "BlockTitle с кнопкой назад и иконкой",
|
|
2961
2985
|
"type": "full-code",
|
|
2962
2986
|
"code": "import { useState } from 'react';\n import {\n Box,\n Button,\n IconButton,\n BlockTitle,\n type BlockTitleSlotSizesProps\n } from '@daisforge/ui';\n import { br, s } from '@daisforge/ui/constants';\n\n() => (\n <div\n style={{\n height: '100vh',\n padding: '20px',\n display: 'flex',\n backgroundColor: lightBackgroundPrimary,\n }}\n >\n <LeftPanelBlock />\n <div\n style={{\n flex: 1,\n padding: s.x8,\n boxShadow: shadowDownSoftS,\n backgroundColor: surfaceSolidCard,\n borderRadius: s.x8,\n }}\n >\n <BlockTitle\n title=\"Title\"\n description=\"Description\"\n // eslint-disable-next-line no-alert\n onBackButtonClick={() => alert('onBackClick')}\n titleRightSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n <IconPlasma size={titleIconSize} />\n )}\n rightSlot={renderRightActionsSlot}\n />\n </div>\n </div>\n )"
|
|
2987
|
+
},
|
|
2988
|
+
{
|
|
2989
|
+
"exportName": "BlockTitleWithTooltipProps",
|
|
2990
|
+
"displayName": "BlockTitle с настройкой тултипа заголовка",
|
|
2991
|
+
"type": "full-code",
|
|
2992
|
+
"code": "import { useState } from 'react';\n import {\n Box,\n Button,\n IconButton,\n BlockTitle,\n type BlockTitleSlotSizesProps\n } from '@daisforge/ui';\n import { br, s } from '@daisforge/ui/constants';\n\n() => (\n <div\n style={{\n height: '100vh',\n padding: '20px',\n display: 'flex',\n backgroundColor: lightBackgroundPrimary,\n }}\n >\n <LeftPanelBlock />\n <div\n style={{\n flex: 1,\n padding: s.x8,\n boxShadow: shadowDownSoftS,\n backgroundColor: surfaceSolidCard,\n borderRadius: s.x8,\n }}\n >\n <BlockTitle\n title={longTitle}\n description=\"Наведите на заголовок — тултип ограничен по ширине и раскрывается вниз\"\n /* Ограничиваем ширину тултипа и задаём его позицию */\n titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n rightSlot={renderRightActionsSlot}\n />\n </div>\n </div>\n )"
|
|
2963
2993
|
}
|
|
2964
2994
|
],
|
|
2965
2995
|
"hasCuratedMeta": true,
|
|
@@ -3774,7 +3804,14 @@
|
|
|
3774
3804
|
"folderName": "Calendar",
|
|
3775
3805
|
"role": "primary",
|
|
3776
3806
|
"description": "Календарь для выбора одной даты или диапазона дат с отметкой событий",
|
|
3777
|
-
"props": [
|
|
3807
|
+
"props": [
|
|
3808
|
+
{
|
|
3809
|
+
"name": "onChangeVisibleDate",
|
|
3810
|
+
"type": "((date: Date) => void) | undefined",
|
|
3811
|
+
"required": false,
|
|
3812
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
3813
|
+
}
|
|
3814
|
+
],
|
|
3778
3815
|
"propsTypeName": "CalendarProps",
|
|
3779
3816
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
|
|
3780
3817
|
"type": "wrapper",
|
|
@@ -4129,6 +4166,12 @@
|
|
|
4129
4166
|
"required": false,
|
|
4130
4167
|
"description": "Минимальное значение даты."
|
|
4131
4168
|
},
|
|
4169
|
+
{
|
|
4170
|
+
"name": "onChangeVisibleDate",
|
|
4171
|
+
"type": "((date: Date) => void) | undefined",
|
|
4172
|
+
"required": false,
|
|
4173
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
4174
|
+
},
|
|
4132
4175
|
{
|
|
4133
4176
|
"name": "renderFromDate",
|
|
4134
4177
|
"type": "Date | undefined",
|
|
@@ -4311,6 +4354,12 @@
|
|
|
4311
4354
|
"required": false,
|
|
4312
4355
|
"description": "Обработчик для выбора стартового значения в диапазоне."
|
|
4313
4356
|
},
|
|
4357
|
+
{
|
|
4358
|
+
"name": "onChangeVisibleDate",
|
|
4359
|
+
"type": "((date: Date) => void) | undefined",
|
|
4360
|
+
"required": false,
|
|
4361
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
4362
|
+
},
|
|
4314
4363
|
{
|
|
4315
4364
|
"name": "renderFromDate",
|
|
4316
4365
|
"type": "Date | undefined",
|
|
@@ -4475,6 +4524,12 @@
|
|
|
4475
4524
|
"required": false,
|
|
4476
4525
|
"description": "Минимальное значение даты."
|
|
4477
4526
|
},
|
|
4527
|
+
{
|
|
4528
|
+
"name": "onChangeVisibleDate",
|
|
4529
|
+
"type": "((date: Date) => void) | undefined",
|
|
4530
|
+
"required": false,
|
|
4531
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
4532
|
+
},
|
|
4478
4533
|
{
|
|
4479
4534
|
"name": "renderFromDate",
|
|
4480
4535
|
"type": "Date | undefined",
|
|
@@ -4651,6 +4706,12 @@
|
|
|
4651
4706
|
"required": false,
|
|
4652
4707
|
"description": "Обработчик для выбора стартового значения в диапазоне."
|
|
4653
4708
|
},
|
|
4709
|
+
{
|
|
4710
|
+
"name": "onChangeVisibleDate",
|
|
4711
|
+
"type": "((date: Date) => void) | undefined",
|
|
4712
|
+
"required": false,
|
|
4713
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
4714
|
+
},
|
|
4654
4715
|
{
|
|
4655
4716
|
"name": "renderFromDate",
|
|
4656
4717
|
"type": "Date | undefined",
|
|
@@ -5617,7 +5678,15 @@
|
|
|
5617
5678
|
"type": "boolean",
|
|
5618
5679
|
"required": false,
|
|
5619
5680
|
"description": "Компонент c округлым border-radius",
|
|
5620
|
-
"default": "false",
|
|
5681
|
+
"default": "'false'",
|
|
5682
|
+
"inheritedFrom": "Chip",
|
|
5683
|
+
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5684
|
+
},
|
|
5685
|
+
{
|
|
5686
|
+
"name": "pin",
|
|
5687
|
+
"type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
|
|
5688
|
+
"required": false,
|
|
5689
|
+
"description": "Свойство задает скругление border-radius",
|
|
5621
5690
|
"inheritedFrom": "Chip",
|
|
5622
5691
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5623
5692
|
},
|
|
@@ -5661,13 +5730,6 @@
|
|
|
5661
5730
|
"inheritedFrom": "Chip",
|
|
5662
5731
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5663
5732
|
},
|
|
5664
|
-
{
|
|
5665
|
-
"name": "pin",
|
|
5666
|
-
"type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
|
|
5667
|
-
"required": false,
|
|
5668
|
-
"inheritedFrom": "Chip",
|
|
5669
|
-
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5670
|
-
},
|
|
5671
5733
|
{
|
|
5672
5734
|
"name": "readOnly",
|
|
5673
5735
|
"type": "boolean",
|
|
@@ -5742,7 +5804,7 @@
|
|
|
5742
5804
|
"type": "boolean",
|
|
5743
5805
|
"required": false,
|
|
5744
5806
|
"description": "Группа будет переопределять view и size для всех элементов внутри",
|
|
5745
|
-
"default": "true",
|
|
5807
|
+
"default": "'true'",
|
|
5746
5808
|
"inheritedFrom": "ChipGroup",
|
|
5747
5809
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5748
5810
|
},
|
|
@@ -5754,6 +5816,15 @@
|
|
|
5754
5816
|
"inheritedFrom": "ChipGroup",
|
|
5755
5817
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5756
5818
|
},
|
|
5819
|
+
{
|
|
5820
|
+
"name": "shape",
|
|
5821
|
+
"type": "\"default\" | \"segmented\"",
|
|
5822
|
+
"required": false,
|
|
5823
|
+
"description": "Скругления для чипов внутри группы",
|
|
5824
|
+
"default": "default",
|
|
5825
|
+
"inheritedFrom": "ChipGroup",
|
|
5826
|
+
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5827
|
+
},
|
|
5757
5828
|
{
|
|
5758
5829
|
"name": "size",
|
|
5759
5830
|
"type": "\"s\" | \"m\" | \"xs\"",
|
|
@@ -5769,13 +5840,6 @@
|
|
|
5769
5840
|
"description": "Вид группы",
|
|
5770
5841
|
"inheritedFrom": "ChipGroup",
|
|
5771
5842
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5772
|
-
},
|
|
5773
|
-
{
|
|
5774
|
-
"name": "shape",
|
|
5775
|
-
"type": "\"default\" | \"segmented\"",
|
|
5776
|
-
"required": false,
|
|
5777
|
-
"inheritedFrom": "ChipGroup",
|
|
5778
|
-
"inheritedPackage": "@salutejs/sdds-finai"
|
|
5779
5843
|
}
|
|
5780
5844
|
],
|
|
5781
5845
|
"atomicMcpVersion": "0.355.0",
|
|
@@ -5804,6 +5868,12 @@
|
|
|
5804
5868
|
"role": "primary",
|
|
5805
5869
|
"description": "Поле ввода одноразового OTP-кода с подписью и обработкой ошибок",
|
|
5806
5870
|
"props": [
|
|
5871
|
+
{
|
|
5872
|
+
"name": "enableWebOTP",
|
|
5873
|
+
"type": "boolean | undefined",
|
|
5874
|
+
"required": false,
|
|
5875
|
+
"description": ""
|
|
5876
|
+
},
|
|
5807
5877
|
{
|
|
5808
5878
|
"name": "autoComplete",
|
|
5809
5879
|
"type": "React.HTMLInputAutoCompleteAttribute | undefined",
|
|
@@ -6894,10 +6964,10 @@
|
|
|
6894
6964
|
},
|
|
6895
6965
|
{
|
|
6896
6966
|
"exportName": "Usage2",
|
|
6897
|
-
"displayName": "Использование в
|
|
6967
|
+
"displayName": "Использование в TableCanvas.filtering.stories.tsx",
|
|
6898
6968
|
"type": "usage",
|
|
6899
|
-
"code": "<Combobox\n
|
|
6900
|
-
"sourceFile": "packages/storybook/src/stories/
|
|
6969
|
+
"code": "<Combobox\n multiple\n size=\"s\"\n items={sidebarIssueTypeOptions}\n value={draftValue}\n onChange={(next: string[]) => setDraftValue(next)}\n closeAfterSelect={false}\n placeholder=\"Выберите Issue Type\"\n afterList={\n <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n <Divider />\n <Button\n size=\"xs\"\n view=\"accent\"\n style={{ marginLeft: 'auto' }}\n onClick={() =>\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }))\n }\n >\n Применить\n </Button>\n </Box>\n }\n />",
|
|
6970
|
+
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
|
|
6901
6971
|
},
|
|
6902
6972
|
{
|
|
6903
6973
|
"exportName": "Vendor1",
|
|
@@ -6999,7 +7069,14 @@
|
|
|
6999
7069
|
"folderName": "DatePicker",
|
|
7000
7070
|
"role": "primary",
|
|
7001
7071
|
"description": "Поле выбора одной даты со встроенным календарём и иконкой",
|
|
7002
|
-
"props": [
|
|
7072
|
+
"props": [
|
|
7073
|
+
{
|
|
7074
|
+
"name": "onChangeVisibleDate",
|
|
7075
|
+
"type": "((date: Date) => void) | undefined",
|
|
7076
|
+
"required": false,
|
|
7077
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
7078
|
+
}
|
|
7079
|
+
],
|
|
7003
7080
|
"propsTypeName": "DatePickerProps",
|
|
7004
7081
|
"sourceFile": "packages/ui-kit/src/components/DatePicker/DatePicker.tsx",
|
|
7005
7082
|
"type": "wrapper",
|
|
@@ -7493,7 +7570,7 @@
|
|
|
7493
7570
|
"name": "stretched",
|
|
7494
7571
|
"type": "boolean",
|
|
7495
7572
|
"required": false,
|
|
7496
|
-
"description": "Растянуть поле ввода на всю доступную ширину",
|
|
7573
|
+
"description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту",
|
|
7497
7574
|
"inheritedFrom": "DatePicker",
|
|
7498
7575
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
7499
7576
|
},
|
|
@@ -7701,6 +7778,13 @@
|
|
|
7701
7778
|
"description": "Флаг наличия индикатора обязательности поля",
|
|
7702
7779
|
"default": "false"
|
|
7703
7780
|
},
|
|
7781
|
+
{
|
|
7782
|
+
"name": "isCalendarPositionedByInput",
|
|
7783
|
+
"type": "boolean | undefined",
|
|
7784
|
+
"required": false,
|
|
7785
|
+
"description": "Позиционировать одиночный календарь относительно активного поля ввода",
|
|
7786
|
+
"default": "false"
|
|
7787
|
+
},
|
|
7704
7788
|
{
|
|
7705
7789
|
"name": "isDoubleCalendar",
|
|
7706
7790
|
"type": "boolean | undefined",
|
|
@@ -8016,6 +8100,12 @@
|
|
|
8016
8100
|
"required": false,
|
|
8017
8101
|
"description": "Должны ли значения минимального и максимального дня включаться в диапазон."
|
|
8018
8102
|
},
|
|
8103
|
+
{
|
|
8104
|
+
"name": "inputWrapperRef",
|
|
8105
|
+
"type": "React.Ref<HTMLDivElement> | undefined",
|
|
8106
|
+
"required": false,
|
|
8107
|
+
"description": "Ссылка на обертку полей ввода"
|
|
8108
|
+
},
|
|
8019
8109
|
{
|
|
8020
8110
|
"name": "lang",
|
|
8021
8111
|
"type": "\"ru\" | \"en\" | undefined",
|
|
@@ -8065,6 +8155,12 @@
|
|
|
8065
8155
|
"required": false,
|
|
8066
8156
|
"description": "Коллбэк, вызываемый при потере фокуса вторым полем ввода"
|
|
8067
8157
|
},
|
|
8158
|
+
{
|
|
8159
|
+
"name": "onChangeVisibleDate",
|
|
8160
|
+
"type": "((date: Date) => void) | undefined",
|
|
8161
|
+
"required": false,
|
|
8162
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
8163
|
+
},
|
|
8068
8164
|
{
|
|
8069
8165
|
"name": "onFocusFirstTextfield",
|
|
8070
8166
|
"type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
|
|
@@ -8154,7 +8250,7 @@
|
|
|
8154
8250
|
"name": "stretched",
|
|
8155
8251
|
"type": "boolean | undefined",
|
|
8156
8252
|
"required": false,
|
|
8157
|
-
"description": "Растянуть поле ввода на всю доступную ширину"
|
|
8253
|
+
"description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
|
|
8158
8254
|
},
|
|
8159
8255
|
{
|
|
8160
8256
|
"name": "titleCaption",
|
|
@@ -8265,6 +8361,18 @@
|
|
|
8265
8361
|
"role": "primary",
|
|
8266
8362
|
"description": "Поле для ввода даты и времени одновременно в одном контроле",
|
|
8267
8363
|
"props": [
|
|
8364
|
+
{
|
|
8365
|
+
"name": "onChangeVisibleDate",
|
|
8366
|
+
"type": "((date: Date) => void) | undefined",
|
|
8367
|
+
"required": false,
|
|
8368
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
8369
|
+
},
|
|
8370
|
+
{
|
|
8371
|
+
"name": "hasTimeFormat",
|
|
8372
|
+
"type": "boolean | undefined",
|
|
8373
|
+
"required": false,
|
|
8374
|
+
"description": ""
|
|
8375
|
+
},
|
|
8268
8376
|
{
|
|
8269
8377
|
"name": "enterKeyHint",
|
|
8270
8378
|
"type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
|
|
@@ -8588,7 +8696,7 @@
|
|
|
8588
8696
|
"name": "stretched",
|
|
8589
8697
|
"type": "boolean",
|
|
8590
8698
|
"required": false,
|
|
8591
|
-
"description": "Растянуть поле ввода на всю доступную ширину",
|
|
8699
|
+
"description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту",
|
|
8592
8700
|
"inheritedFrom": "DateTimePicker",
|
|
8593
8701
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
8594
8702
|
},
|
|
@@ -8998,7 +9106,14 @@
|
|
|
8998
9106
|
"folderName": "Drawer",
|
|
8999
9107
|
"role": "primary",
|
|
9000
9108
|
"description": "Базовая выезжающая боковая панель поверх контента страницы",
|
|
9001
|
-
"props": [
|
|
9109
|
+
"props": [
|
|
9110
|
+
{
|
|
9111
|
+
"name": "overlayProps",
|
|
9112
|
+
"type": "DrawerOverlayProps | undefined",
|
|
9113
|
+
"required": false,
|
|
9114
|
+
"description": "Настройки подложки.\nПо умолчанию `position` равен `fixed` для document и `absolute` для остальных frame."
|
|
9115
|
+
}
|
|
9116
|
+
],
|
|
9002
9117
|
"propsTypeName": "DrawerProps",
|
|
9003
9118
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Drawer/Drawer.d.ts",
|
|
9004
9119
|
"type": "wrapper",
|
|
@@ -9599,7 +9714,7 @@
|
|
|
9599
9714
|
},
|
|
9600
9715
|
{
|
|
9601
9716
|
"name": "overlayProps",
|
|
9602
|
-
"type": "
|
|
9717
|
+
"type": "DrawerOverlayProps | undefined",
|
|
9603
9718
|
"required": false,
|
|
9604
9719
|
"description": ""
|
|
9605
9720
|
},
|
|
@@ -16244,7 +16359,14 @@
|
|
|
16244
16359
|
"folderName": "Modal",
|
|
16245
16360
|
"role": "primary",
|
|
16246
16361
|
"description": "Базовое модальное окно поверх контента без готовых layout-слотов",
|
|
16247
|
-
"props": [
|
|
16362
|
+
"props": [
|
|
16363
|
+
{
|
|
16364
|
+
"name": "focusTrapSelectors",
|
|
16365
|
+
"type": "string[] | undefined",
|
|
16366
|
+
"required": false,
|
|
16367
|
+
"description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
|
|
16368
|
+
}
|
|
16369
|
+
],
|
|
16248
16370
|
"propsTypeName": "ModalProps",
|
|
16249
16371
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Modal/Modal.d.ts",
|
|
16250
16372
|
"type": "wrapper",
|
|
@@ -17412,6 +17534,12 @@
|
|
|
17412
17534
|
"role": "primary",
|
|
17413
17535
|
"description": "Расширенное модальное окно с compound-слотами: шапка, контент, футер, Left/Main",
|
|
17414
17536
|
"props": [
|
|
17537
|
+
{
|
|
17538
|
+
"name": "focusTrapSelectors",
|
|
17539
|
+
"type": "string[] | undefined",
|
|
17540
|
+
"required": false,
|
|
17541
|
+
"description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
|
|
17542
|
+
},
|
|
17415
17543
|
{
|
|
17416
17544
|
"name": "contentContainerProps",
|
|
17417
17545
|
"type": "Partial<ContainerProps> | undefined",
|
|
@@ -18321,6 +18449,12 @@
|
|
|
18321
18449
|
"required": false,
|
|
18322
18450
|
"description": "Иконка в верхней части модального окна"
|
|
18323
18451
|
},
|
|
18452
|
+
{
|
|
18453
|
+
"name": "focusTrapSelectors",
|
|
18454
|
+
"type": "string[] | undefined",
|
|
18455
|
+
"required": false,
|
|
18456
|
+
"description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
|
|
18457
|
+
},
|
|
18324
18458
|
{
|
|
18325
18459
|
"name": "contentContainerProps",
|
|
18326
18460
|
"type": "Partial<ContainerProps> | undefined",
|
|
@@ -19290,6 +19424,12 @@
|
|
|
19290
19424
|
"role": "primary",
|
|
19291
19425
|
"description": "Поле ввода с форматированием чисел (разделители, десятичные) и кнопкой очистки",
|
|
19292
19426
|
"props": [
|
|
19427
|
+
{
|
|
19428
|
+
"name": "suffix",
|
|
19429
|
+
"type": "string | undefined",
|
|
19430
|
+
"required": false,
|
|
19431
|
+
"description": "Суффикс текста в поле ввода."
|
|
19432
|
+
},
|
|
19293
19433
|
{
|
|
19294
19434
|
"name": "onClear",
|
|
19295
19435
|
"type": "(() => void) | undefined",
|
|
@@ -19803,6 +19943,12 @@
|
|
|
19803
19943
|
"description": "Задает выравнивание индикатора обязательности поля",
|
|
19804
19944
|
"default": "right"
|
|
19805
19945
|
},
|
|
19946
|
+
{
|
|
19947
|
+
"name": "suffix",
|
|
19948
|
+
"type": "string | undefined",
|
|
19949
|
+
"required": false,
|
|
19950
|
+
"description": "Суффикс текста в поле ввода."
|
|
19951
|
+
},
|
|
19806
19952
|
{
|
|
19807
19953
|
"name": "thousandSeparator",
|
|
19808
19954
|
"type": "string | boolean | undefined",
|
|
@@ -20865,7 +21011,14 @@
|
|
|
20865
21011
|
"folderName": "Popover",
|
|
20866
21012
|
"role": "primary",
|
|
20867
21013
|
"description": "Всплывающая панель у элемента-триггера для доп. контента, меню или подсказок",
|
|
20868
|
-
"props": [
|
|
21014
|
+
"props": [
|
|
21015
|
+
{
|
|
21016
|
+
"name": "stretchHeight",
|
|
21017
|
+
"type": "boolean | undefined",
|
|
21018
|
+
"required": false,
|
|
21019
|
+
"description": "Растянуть Popover до границы доступной области по вертикали."
|
|
21020
|
+
}
|
|
21021
|
+
],
|
|
20869
21022
|
"propsTypeName": "PopoverProps",
|
|
20870
21023
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Popover/Popover.d.ts",
|
|
20871
21024
|
"type": "wrapper",
|
|
@@ -25022,11 +25175,29 @@
|
|
|
25022
25175
|
"description": "Стиль для UI конфигурации\nВлияет на выбор предустановленого набора токенов",
|
|
25023
25176
|
"default": "default"
|
|
25024
25177
|
},
|
|
25178
|
+
{
|
|
25179
|
+
"name": "firstTextfieldInputWrapperRef",
|
|
25180
|
+
"type": "React.Ref<HTMLDivElement> | undefined",
|
|
25181
|
+
"required": false,
|
|
25182
|
+
"description": "Ссылка на обертку первого поля ввода"
|
|
25183
|
+
},
|
|
25025
25184
|
{
|
|
25026
25185
|
"name": "hasClearDivider",
|
|
25027
25186
|
"type": "boolean | undefined",
|
|
25028
25187
|
"required": false,
|
|
25029
25188
|
"description": "Отображение разделителя для `appearance='clear'`"
|
|
25189
|
+
},
|
|
25190
|
+
{
|
|
25191
|
+
"name": "inputWrapperRef",
|
|
25192
|
+
"type": "React.Ref<HTMLDivElement> | undefined",
|
|
25193
|
+
"required": false,
|
|
25194
|
+
"description": "Ссылка на обертку полей ввода"
|
|
25195
|
+
},
|
|
25196
|
+
{
|
|
25197
|
+
"name": "secondTextfieldInputWrapperRef",
|
|
25198
|
+
"type": "React.Ref<HTMLDivElement> | undefined",
|
|
25199
|
+
"required": false,
|
|
25200
|
+
"description": "Ссылка на обертку второго поля ввода"
|
|
25030
25201
|
}
|
|
25031
25202
|
],
|
|
25032
25203
|
"propsTypeName": "RangeProps",
|
|
@@ -26645,7 +26816,45 @@
|
|
|
26645
26816
|
"folderName": "Sheet",
|
|
26646
26817
|
"role": "primary",
|
|
26647
26818
|
"description": "Шторка (bottom sheet), выезжающая поверх экрана снизу с шапкой и футером",
|
|
26648
|
-
"props": [
|
|
26819
|
+
"props": [
|
|
26820
|
+
{
|
|
26821
|
+
"name": "closeOnEsc",
|
|
26822
|
+
"type": "boolean | undefined",
|
|
26823
|
+
"required": false,
|
|
26824
|
+
"description": "Закрывать шторку при нажатии на ESC.",
|
|
26825
|
+
"default": "true"
|
|
26826
|
+
},
|
|
26827
|
+
{
|
|
26828
|
+
"name": "initialSnapPoint",
|
|
26829
|
+
"type": "string | undefined",
|
|
26830
|
+
"required": false,
|
|
26831
|
+
"description": "Начальная точка остановки.\nПо умолчанию — первая из `snapPoints`."
|
|
26832
|
+
},
|
|
26833
|
+
{
|
|
26834
|
+
"name": "onEscKeyDown",
|
|
26835
|
+
"type": "((event: KeyboardEvent) => void) | undefined",
|
|
26836
|
+
"required": false,
|
|
26837
|
+
"description": "Обработчик нажатия ESC (если не передан, используется onClose)."
|
|
26838
|
+
},
|
|
26839
|
+
{
|
|
26840
|
+
"name": "onOverlayClick",
|
|
26841
|
+
"type": "((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void) | undefined",
|
|
26842
|
+
"required": false,
|
|
26843
|
+
"description": "Обработчик клика по оверлею (если не передан, используется onClose)."
|
|
26844
|
+
},
|
|
26845
|
+
{
|
|
26846
|
+
"name": "onSnapPointChange",
|
|
26847
|
+
"type": "((snapPoint: string) => void) | undefined",
|
|
26848
|
+
"required": false,
|
|
26849
|
+
"description": "Обработчик смены активной точки остановки."
|
|
26850
|
+
},
|
|
26851
|
+
{
|
|
26852
|
+
"name": "snapPoints",
|
|
26853
|
+
"type": "SheetSnapPoints | undefined",
|
|
26854
|
+
"required": false,
|
|
26855
|
+
"description": "Точки остановки шторки.\nCSS-размеры: '320px', '50%', '40dvh'.\nЕсли не передано или массив пуст — snap-points отключены."
|
|
26856
|
+
}
|
|
26857
|
+
],
|
|
26649
26858
|
"propsTypeName": "SheetProps",
|
|
26650
26859
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Sheet/Sheet.d.ts",
|
|
26651
26860
|
"type": "wrapper",
|
|
@@ -26662,7 +26871,7 @@
|
|
|
26662
26871
|
"name": "onClose",
|
|
26663
26872
|
"type": "() => void",
|
|
26664
26873
|
"required": true,
|
|
26665
|
-
"description": "Обработчик закрытия шторки. Вызывается при клике по оверлею
|
|
26874
|
+
"description": "Обработчик закрытия шторки. Вызывается при смахивании шторки вниз,\nпри клике по оверлею (если не передан onOverlayClick)\nи при нажатии ESC (если не передан onEscKeyDown).",
|
|
26666
26875
|
"inheritedFrom": "Sheet",
|
|
26667
26876
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
26668
26877
|
},
|
|
@@ -26802,7 +27011,14 @@
|
|
|
26802
27011
|
"folderName": "Skeleton",
|
|
26803
27012
|
"role": "primary",
|
|
26804
27013
|
"description": "Плейсхолдер-линия для имитации загрузки текстовой строки",
|
|
26805
|
-
"props": [
|
|
27014
|
+
"props": [
|
|
27015
|
+
{
|
|
27016
|
+
"name": "animationDuration",
|
|
27017
|
+
"type": "number | undefined",
|
|
27018
|
+
"required": false,
|
|
27019
|
+
"description": "Длительность одного цикла анимации в миллисекундах"
|
|
27020
|
+
}
|
|
27021
|
+
],
|
|
26806
27022
|
"propsTypeName": "ComponentProps<typeof LineSkeleton>",
|
|
26807
27023
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Skeleton/Skeleton.d.ts",
|
|
26808
27024
|
"type": "wrapper",
|
|
@@ -26819,7 +27035,8 @@
|
|
|
26819
27035
|
"name": "animationType",
|
|
26820
27036
|
"type": "\"shimmer\" | \"pulse\"",
|
|
26821
27037
|
"required": false,
|
|
26822
|
-
"description": "
|
|
27038
|
+
"description": "Тип анимации",
|
|
27039
|
+
"default": "'shimmer'",
|
|
26823
27040
|
"inheritedFrom": "LineSkeleton",
|
|
26824
27041
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
26825
27042
|
},
|
|
@@ -26835,7 +27052,7 @@
|
|
|
26835
27052
|
"name": "customFadeOutColor",
|
|
26836
27053
|
"type": "string",
|
|
26837
27054
|
"required": false,
|
|
26838
|
-
"description": "Значение цвета фона в
|
|
27055
|
+
"description": "Значение цвета фона в конце анимации `pulse`",
|
|
26839
27056
|
"inheritedFrom": "LineSkeleton",
|
|
26840
27057
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
26841
27058
|
},
|
|
@@ -26917,11 +27134,18 @@
|
|
|
26917
27134
|
"role": "primary",
|
|
26918
27135
|
"description": "Прямоугольный плейсхолдер для блоков и изображений на время загрузки",
|
|
26919
27136
|
"props": [
|
|
27137
|
+
{
|
|
27138
|
+
"name": "animationDuration",
|
|
27139
|
+
"type": "number | undefined",
|
|
27140
|
+
"required": false,
|
|
27141
|
+
"description": "Длительность одного цикла анимации в миллисекундах"
|
|
27142
|
+
},
|
|
26920
27143
|
{
|
|
26921
27144
|
"name": "animationType",
|
|
26922
27145
|
"type": "\"shimmer\" | \"pulse\" | undefined",
|
|
26923
27146
|
"required": false,
|
|
26924
|
-
"description": "
|
|
27147
|
+
"description": "Тип анимации",
|
|
27148
|
+
"default": "'shimmer'"
|
|
26925
27149
|
},
|
|
26926
27150
|
{
|
|
26927
27151
|
"name": "customFadeInColor",
|
|
@@ -26933,7 +27157,7 @@
|
|
|
26933
27157
|
"name": "customFadeOutColor",
|
|
26934
27158
|
"type": "string | undefined",
|
|
26935
27159
|
"required": false,
|
|
26936
|
-
"description": "Значение цвета фона в
|
|
27160
|
+
"description": "Значение цвета фона в конце анимации `pulse`"
|
|
26937
27161
|
},
|
|
26938
27162
|
{
|
|
26939
27163
|
"name": "customGradientColor",
|
|
@@ -27010,11 +27234,18 @@
|
|
|
27010
27234
|
"required": true,
|
|
27011
27235
|
"description": ""
|
|
27012
27236
|
},
|
|
27237
|
+
{
|
|
27238
|
+
"name": "animationDuration",
|
|
27239
|
+
"type": "number | undefined",
|
|
27240
|
+
"required": false,
|
|
27241
|
+
"description": "Длительность одного цикла анимации в миллисекундах"
|
|
27242
|
+
},
|
|
27013
27243
|
{
|
|
27014
27244
|
"name": "animationType",
|
|
27015
27245
|
"type": "\"shimmer\" | \"pulse\" | undefined",
|
|
27016
27246
|
"required": false,
|
|
27017
|
-
"description": "
|
|
27247
|
+
"description": "Тип анимации",
|
|
27248
|
+
"default": "'shimmer'"
|
|
27018
27249
|
},
|
|
27019
27250
|
{
|
|
27020
27251
|
"name": "customFadeInColor",
|
|
@@ -27026,7 +27257,7 @@
|
|
|
27026
27257
|
"name": "customFadeOutColor",
|
|
27027
27258
|
"type": "string | undefined",
|
|
27028
27259
|
"required": false,
|
|
27029
|
-
"description": "Значение цвета фона в
|
|
27260
|
+
"description": "Значение цвета фона в конце анимации `pulse`"
|
|
27030
27261
|
},
|
|
27031
27262
|
{
|
|
27032
27263
|
"name": "customGradientColor",
|
|
@@ -27153,7 +27384,7 @@
|
|
|
27153
27384
|
"type": "\"outer\" | \"inner\"",
|
|
27154
27385
|
"required": false,
|
|
27155
27386
|
"description": "Расположение подписи.",
|
|
27156
|
-
"default": "top",
|
|
27387
|
+
"default": "`top`",
|
|
27157
27388
|
"inheritedFrom": "Slider",
|
|
27158
27389
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
27159
27390
|
},
|
|
@@ -28325,6 +28556,133 @@
|
|
|
28325
28556
|
}
|
|
28326
28557
|
]
|
|
28327
28558
|
},
|
|
28559
|
+
"TableFilterSelect": {
|
|
28560
|
+
"name": "TableFilterSelect",
|
|
28561
|
+
"group": "components",
|
|
28562
|
+
"folderName": "TableCanvas",
|
|
28563
|
+
"role": "primary",
|
|
28564
|
+
"description": "",
|
|
28565
|
+
"props": [
|
|
28566
|
+
{
|
|
28567
|
+
"name": "onChange",
|
|
28568
|
+
"type": "((v: string) => void) | ((v: string[]) => void)",
|
|
28569
|
+
"required": true,
|
|
28570
|
+
"description": ""
|
|
28571
|
+
},
|
|
28572
|
+
{
|
|
28573
|
+
"name": "options",
|
|
28574
|
+
"type": "{ text: string; value: string; }[]",
|
|
28575
|
+
"required": true,
|
|
28576
|
+
"description": ""
|
|
28577
|
+
},
|
|
28578
|
+
{
|
|
28579
|
+
"name": "value",
|
|
28580
|
+
"type": "string | string[]",
|
|
28581
|
+
"required": true,
|
|
28582
|
+
"description": ""
|
|
28583
|
+
},
|
|
28584
|
+
{
|
|
28585
|
+
"name": "afterList",
|
|
28586
|
+
"type": "React.ReactNode",
|
|
28587
|
+
"required": false,
|
|
28588
|
+
"description": ""
|
|
28589
|
+
},
|
|
28590
|
+
{
|
|
28591
|
+
"name": "beforeList",
|
|
28592
|
+
"type": "React.ReactNode",
|
|
28593
|
+
"required": false,
|
|
28594
|
+
"description": ""
|
|
28595
|
+
},
|
|
28596
|
+
{
|
|
28597
|
+
"name": "listMaxHeight",
|
|
28598
|
+
"type": "string | undefined",
|
|
28599
|
+
"required": false,
|
|
28600
|
+
"description": "",
|
|
28601
|
+
"default": "'360px'"
|
|
28602
|
+
},
|
|
28603
|
+
{
|
|
28604
|
+
"name": "mode",
|
|
28605
|
+
"type": "\"multiple\" | \"single\" | undefined",
|
|
28606
|
+
"required": false,
|
|
28607
|
+
"description": "",
|
|
28608
|
+
"default": "'single'"
|
|
28609
|
+
},
|
|
28610
|
+
{
|
|
28611
|
+
"name": "size",
|
|
28612
|
+
"type": "\"big\" | \"small\" | \"medium\" | undefined",
|
|
28613
|
+
"required": false,
|
|
28614
|
+
"description": "",
|
|
28615
|
+
"default": "'medium'"
|
|
28616
|
+
},
|
|
28617
|
+
{
|
|
28618
|
+
"name": "width",
|
|
28619
|
+
"type": "string | undefined",
|
|
28620
|
+
"required": false,
|
|
28621
|
+
"description": ""
|
|
28622
|
+
}
|
|
28623
|
+
],
|
|
28624
|
+
"propsTypeName": "TableFilterSelectProps",
|
|
28625
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx",
|
|
28626
|
+
"type": "composition",
|
|
28627
|
+
"relatedExports": [
|
|
28628
|
+
"SplitIconButton",
|
|
28629
|
+
"CellEditorCombobox",
|
|
28630
|
+
"CellEditorNumberFormat",
|
|
28631
|
+
"CellEditorTextArea",
|
|
28632
|
+
"TableFilterSelectListItem",
|
|
28633
|
+
"ContainerStyled",
|
|
28634
|
+
"TextCellEntry",
|
|
28635
|
+
"Canvas",
|
|
28636
|
+
"TextCellEntryType"
|
|
28637
|
+
],
|
|
28638
|
+
"atomicMcpVersion": "0.355.0",
|
|
28639
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
28640
|
+
"importStatement": "import { TableFilterSelect } from '@daisforge/ui/components/TableCanvas';",
|
|
28641
|
+
"minimalUsage": "<TableFilterSelect onChange={() => {}} options={[]} value={[]} />",
|
|
28642
|
+
"examples": [
|
|
28643
|
+
{
|
|
28644
|
+
"exportName": "Usage",
|
|
28645
|
+
"displayName": "Использование в TableCanvas.filtering.stories.tsx",
|
|
28646
|
+
"type": "usage",
|
|
28647
|
+
"code": "<TableFilterSelect\n mode=\"multiple\"\n value={draftValue}\n onChange={setDraftValue}\n options={issueTypeOptions}\n size={rowSize}\n width=\"232px\"\n beforeList={\n <TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>\n }\n afterList={\n <Box\n $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n rowSize === 'big' ? '4px' : '4px'\n }; margin-top: 4px;`}\n >\n <Divider />\n <Button\n size={rowSize === 'small' ? 'xxs' : 's'}\n style={{ marginLeft: 'auto ' }}\n view=\"accent\"\n onClick={apply}\n >\n Применить\n </Button>\n </Box>\n }\n />",
|
|
28648
|
+
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
|
|
28649
|
+
}
|
|
28650
|
+
]
|
|
28651
|
+
},
|
|
28652
|
+
"TableFilterSelectList": {
|
|
28653
|
+
"name": "TableFilterSelectList",
|
|
28654
|
+
"group": "components",
|
|
28655
|
+
"folderName": "TableCanvas",
|
|
28656
|
+
"role": "primary",
|
|
28657
|
+
"description": "",
|
|
28658
|
+
"props": [
|
|
28659
|
+
{
|
|
28660
|
+
"name": "as",
|
|
28661
|
+
"type": "string | React.ComponentType<any> | undefined",
|
|
28662
|
+
"required": false,
|
|
28663
|
+
"description": ""
|
|
28664
|
+
}
|
|
28665
|
+
],
|
|
28666
|
+
"propsTypeName": "ComponentProps<typeof TableFilterSelectList>",
|
|
28667
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
|
|
28668
|
+
"type": "composition",
|
|
28669
|
+
"relatedExports": [
|
|
28670
|
+
"SplitIconButton",
|
|
28671
|
+
"CellEditorCombobox",
|
|
28672
|
+
"CellEditorNumberFormat",
|
|
28673
|
+
"CellEditorTextArea",
|
|
28674
|
+
"TableFilterSelectListItem",
|
|
28675
|
+
"ContainerStyled",
|
|
28676
|
+
"TextCellEntry",
|
|
28677
|
+
"Canvas",
|
|
28678
|
+
"TextCellEntryType"
|
|
28679
|
+
],
|
|
28680
|
+
"atomicMcpVersion": "0.355.0",
|
|
28681
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
28682
|
+
"importStatement": "import { TableFilterSelectList } from '@daisforge/ui/components/TableCanvas';",
|
|
28683
|
+
"minimalUsage": "<TableFilterSelectList />",
|
|
28684
|
+
"examples": []
|
|
28685
|
+
},
|
|
28328
28686
|
"TableFilterSelectListItem": {
|
|
28329
28687
|
"name": "TableFilterSelectListItem",
|
|
28330
28688
|
"group": "components",
|
|
@@ -28356,14 +28714,89 @@
|
|
|
28356
28714
|
"minimalUsage": "<TableFilterSelectListItem />",
|
|
28357
28715
|
"examples": [
|
|
28358
28716
|
{
|
|
28359
|
-
"exportName": "
|
|
28717
|
+
"exportName": "Usage1",
|
|
28360
28718
|
"displayName": "Использование в TableCanvas.multipleFeatures.stories.tsx",
|
|
28361
28719
|
"type": "usage",
|
|
28362
28720
|
"code": "<TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n custom beforeList\n </TableFilterSelectListItem>",
|
|
28363
28721
|
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.MultipleFeatures/TableCanvas.multipleFeatures.stories.tsx"
|
|
28722
|
+
},
|
|
28723
|
+
{
|
|
28724
|
+
"exportName": "Usage2",
|
|
28725
|
+
"displayName": "Использование в TableCanvas.filtering.stories.tsx",
|
|
28726
|
+
"type": "usage",
|
|
28727
|
+
"code": "<TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>",
|
|
28728
|
+
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
|
|
28364
28729
|
}
|
|
28365
28730
|
]
|
|
28366
28731
|
},
|
|
28732
|
+
"TableFilterSelectSearchTextfield": {
|
|
28733
|
+
"name": "TableFilterSelectSearchTextfield",
|
|
28734
|
+
"group": "components",
|
|
28735
|
+
"folderName": "TableCanvas",
|
|
28736
|
+
"role": "primary",
|
|
28737
|
+
"description": "",
|
|
28738
|
+
"props": [
|
|
28739
|
+
{
|
|
28740
|
+
"name": "as",
|
|
28741
|
+
"type": "string | React.ComponentType<any> | undefined",
|
|
28742
|
+
"required": false,
|
|
28743
|
+
"description": ""
|
|
28744
|
+
}
|
|
28745
|
+
],
|
|
28746
|
+
"propsTypeName": "ComponentProps<typeof TableFilterSelectSearchTextfield>",
|
|
28747
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
|
|
28748
|
+
"type": "composition",
|
|
28749
|
+
"relatedExports": [
|
|
28750
|
+
"SplitIconButton",
|
|
28751
|
+
"CellEditorCombobox",
|
|
28752
|
+
"CellEditorNumberFormat",
|
|
28753
|
+
"CellEditorTextArea",
|
|
28754
|
+
"TableFilterSelectListItem",
|
|
28755
|
+
"ContainerStyled",
|
|
28756
|
+
"TextCellEntry",
|
|
28757
|
+
"Canvas",
|
|
28758
|
+
"TextCellEntryType"
|
|
28759
|
+
],
|
|
28760
|
+
"atomicMcpVersion": "0.355.0",
|
|
28761
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
28762
|
+
"importStatement": "import { TableFilterSelectSearchTextfield } from '@daisforge/ui/components/TableCanvas';",
|
|
28763
|
+
"minimalUsage": "<TableFilterSelectSearchTextfield />",
|
|
28764
|
+
"examples": []
|
|
28765
|
+
},
|
|
28766
|
+
"TableFilterSelectTotalListItemContainer": {
|
|
28767
|
+
"name": "TableFilterSelectTotalListItemContainer",
|
|
28768
|
+
"group": "components",
|
|
28769
|
+
"folderName": "TableCanvas",
|
|
28770
|
+
"role": "primary",
|
|
28771
|
+
"description": "",
|
|
28772
|
+
"props": [
|
|
28773
|
+
{
|
|
28774
|
+
"name": "as",
|
|
28775
|
+
"type": "string | React.ComponentType<any> | undefined",
|
|
28776
|
+
"required": false,
|
|
28777
|
+
"description": ""
|
|
28778
|
+
}
|
|
28779
|
+
],
|
|
28780
|
+
"propsTypeName": "ComponentProps<typeof TableFilterSelectTotalListItemContainer>",
|
|
28781
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
|
|
28782
|
+
"type": "composition",
|
|
28783
|
+
"relatedExports": [
|
|
28784
|
+
"SplitIconButton",
|
|
28785
|
+
"CellEditorCombobox",
|
|
28786
|
+
"CellEditorNumberFormat",
|
|
28787
|
+
"CellEditorTextArea",
|
|
28788
|
+
"TableFilterSelectListItem",
|
|
28789
|
+
"ContainerStyled",
|
|
28790
|
+
"TextCellEntry",
|
|
28791
|
+
"Canvas",
|
|
28792
|
+
"TextCellEntryType"
|
|
28793
|
+
],
|
|
28794
|
+
"atomicMcpVersion": "0.355.0",
|
|
28795
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
28796
|
+
"importStatement": "import { TableFilterSelectTotalListItemContainer } from '@daisforge/ui/components/TableCanvas';",
|
|
28797
|
+
"minimalUsage": "<TableFilterSelectTotalListItemContainer />",
|
|
28798
|
+
"examples": []
|
|
28799
|
+
},
|
|
28367
28800
|
"Table": {
|
|
28368
28801
|
"name": "Table",
|
|
28369
28802
|
"group": "components",
|
|
@@ -28440,7 +28873,7 @@
|
|
|
28440
28873
|
"react-data-grid"
|
|
28441
28874
|
],
|
|
28442
28875
|
"docs": "# Table\n\n`Table` - legacy HTML-таблица на базе `react-data-grid` и `react-table`-подходов, которая поддерживается для существующих продуктов. Для новых таблиц по умолчанию используйте `TableCanvas`.\n\n## Ключевые особенности\n\n- Отображение строк и колонок через `rows`, `columnConfig` и `tableConfig`\n- Сортировка, фильтрация, поиск, пагинация и infinity scroll\n- Выбор строк, вложенные строки, группировка строк и группировка колонок\n- Настройка колонок, изменение ширины, кастомный render ячеек и итоговые строки\n- ControlBlock, sidebar, context menu, row instruments и состояния загрузки/пустых данных\n\n## Legacy-статус\n\n`Table` оставлен для поддержки проектов, которые уже используют HTML-таблицу. Если задача не требует совместимости с legacy API, выбирайте `TableCanvas`: он является основной таблицей библиотеки и лучше подходит для больших данных, canvas-render и новых сценариев.\n\n## Основные сущности\n\n- `TableProps` - публичные props компонента\n- `TableConfig` - конфигурация фич таблицы\n- `ColumnConfig` - конфигурация колонок, render-ов, сортировки, фильтрации и редактирования\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-api--docs).",
|
|
28443
|
-
"apiDocs": "# Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
28876
|
+
"apiDocs": "# Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
28444
28877
|
"curatedStories": [
|
|
28445
28878
|
{
|
|
28446
28879
|
"exportName": "Docs",
|
|
@@ -29458,6 +29891,12 @@
|
|
|
29458
29891
|
"required": true,
|
|
29459
29892
|
"description": ""
|
|
29460
29893
|
},
|
|
29894
|
+
{
|
|
29895
|
+
"name": "suffix",
|
|
29896
|
+
"type": "string | undefined",
|
|
29897
|
+
"required": false,
|
|
29898
|
+
"description": "Суффикс текста в поле ввода."
|
|
29899
|
+
},
|
|
29461
29900
|
{
|
|
29462
29901
|
"name": "align",
|
|
29463
29902
|
"type": "\"center\" | \"right\" | \"left\" | undefined",
|
|
@@ -30299,6 +30738,12 @@
|
|
|
30299
30738
|
"required": false,
|
|
30300
30739
|
"description": "Флаг fullscreen - пересканирование DOM при переключении"
|
|
30301
30740
|
},
|
|
30741
|
+
{
|
|
30742
|
+
"name": "getCellBorder",
|
|
30743
|
+
"type": "CellBorderResolver | undefined",
|
|
30744
|
+
"required": false,
|
|
30745
|
+
"description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
|
|
30746
|
+
},
|
|
30302
30747
|
{
|
|
30303
30748
|
"name": "getCellsForSelection",
|
|
30304
30749
|
"type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
|
|
@@ -30342,6 +30787,12 @@
|
|
|
30342
30787
|
"required": false,
|
|
30343
30788
|
"description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
|
|
30344
30789
|
},
|
|
30790
|
+
{
|
|
30791
|
+
"name": "hiddenColumnsIndicator",
|
|
30792
|
+
"type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
|
|
30793
|
+
"required": false,
|
|
30794
|
+
"description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
|
|
30795
|
+
},
|
|
30345
30796
|
{
|
|
30346
30797
|
"name": "hideGrid",
|
|
30347
30798
|
"type": "boolean | undefined",
|
|
@@ -30372,6 +30823,12 @@
|
|
|
30372
30823
|
"required": false,
|
|
30373
30824
|
"description": "Highlight regions provide hints to users about relations between cells and selections."
|
|
30374
30825
|
},
|
|
30826
|
+
{
|
|
30827
|
+
"name": "horizontalBorder",
|
|
30828
|
+
"type": "boolean | ((row: number) => boolean) | undefined",
|
|
30829
|
+
"required": false,
|
|
30830
|
+
"description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
|
|
30831
|
+
},
|
|
30375
30832
|
{
|
|
30376
30833
|
"name": "hoverEffects",
|
|
30377
30834
|
"type": "HoverEffectsConfig | undefined",
|
|
@@ -30570,6 +31027,12 @@
|
|
|
30570
31027
|
"required": false,
|
|
30571
31028
|
"description": "Emitted when a header menu disclosure indicator is clicked."
|
|
30572
31029
|
},
|
|
31030
|
+
{
|
|
31031
|
+
"name": "onHiddenColumnsIndicatorClicked",
|
|
31032
|
+
"type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
|
|
31033
|
+
"required": false,
|
|
31034
|
+
"description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
|
|
31035
|
+
},
|
|
30573
31036
|
{
|
|
30574
31037
|
"name": "onHighlightActiveRowChange",
|
|
30575
31038
|
"type": "((row: number | undefined, rowData?: R | undefined) => void) | undefined",
|
|
@@ -31095,6 +31558,13 @@
|
|
|
31095
31558
|
"role": "internal",
|
|
31096
31559
|
"description": "JSX-набор примитивов (Container, Text, Icon, Button…) для кастомного контента ячеек TableGlide",
|
|
31097
31560
|
"props": [
|
|
31561
|
+
{
|
|
31562
|
+
"name": "offsetX",
|
|
31563
|
+
"type": "number | undefined",
|
|
31564
|
+
"required": false,
|
|
31565
|
+
"description": "Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\nчасть ноды смещена внутри неё (например, иконка прижата к краю кнопки).",
|
|
31566
|
+
"default": "0"
|
|
31567
|
+
},
|
|
31098
31568
|
{
|
|
31099
31569
|
"name": "preserveLineBreaks",
|
|
31100
31570
|
"type": "boolean | undefined",
|
|
@@ -31681,6 +32151,12 @@
|
|
|
31681
32151
|
"required": false,
|
|
31682
32152
|
"description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
|
|
31683
32153
|
},
|
|
32154
|
+
{
|
|
32155
|
+
"name": "getCellBorder",
|
|
32156
|
+
"type": "CellBorderResolver | undefined",
|
|
32157
|
+
"required": false,
|
|
32158
|
+
"description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
|
|
32159
|
+
},
|
|
31684
32160
|
{
|
|
31685
32161
|
"name": "getCellsForSelection",
|
|
31686
32162
|
"type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
|
|
@@ -31717,12 +32193,24 @@
|
|
|
31717
32193
|
"required": false,
|
|
31718
32194
|
"description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
|
|
31719
32195
|
},
|
|
32196
|
+
{
|
|
32197
|
+
"name": "hiddenColumnsIndicator",
|
|
32198
|
+
"type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
|
|
32199
|
+
"required": false,
|
|
32200
|
+
"description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
|
|
32201
|
+
},
|
|
31720
32202
|
{
|
|
31721
32203
|
"name": "highlightRegions",
|
|
31722
32204
|
"type": "readonly Highlight[] | undefined",
|
|
31723
32205
|
"required": false,
|
|
31724
32206
|
"description": "Highlight regions provide hints to users about relations between cells and selections."
|
|
31725
32207
|
},
|
|
32208
|
+
{
|
|
32209
|
+
"name": "horizontalBorder",
|
|
32210
|
+
"type": "boolean | ((row: number) => boolean) | undefined",
|
|
32211
|
+
"required": false,
|
|
32212
|
+
"description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
|
|
32213
|
+
},
|
|
31726
32214
|
{
|
|
31727
32215
|
"name": "imageEditorOverride",
|
|
31728
32216
|
"type": "ImageEditorType | undefined",
|
|
@@ -31922,6 +32410,12 @@
|
|
|
31922
32410
|
"required": false,
|
|
31923
32411
|
"description": "Emitted when a header menu disclosure indicator is clicked."
|
|
31924
32412
|
},
|
|
32413
|
+
{
|
|
32414
|
+
"name": "onHiddenColumnsIndicatorClicked",
|
|
32415
|
+
"type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
|
|
32416
|
+
"required": false,
|
|
32417
|
+
"description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
|
|
32418
|
+
},
|
|
31925
32419
|
{
|
|
31926
32420
|
"name": "onItemHovered",
|
|
31927
32421
|
"type": "((args: GridMouseEventArgs) => void) | undefined",
|
|
@@ -32542,6 +33036,13 @@
|
|
|
32542
33036
|
"role": "internal",
|
|
32543
33037
|
"description": "Базовый класс узла canvas-сцены TableGlide: layout, hit-test, отрисовка, события",
|
|
32544
33038
|
"props": [
|
|
33039
|
+
{
|
|
33040
|
+
"name": "offsetX",
|
|
33041
|
+
"type": "number | undefined",
|
|
33042
|
+
"required": false,
|
|
33043
|
+
"description": "Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\nчасть ноды смещена внутри неё (например, иконка прижата к краю кнопки).",
|
|
33044
|
+
"default": "0"
|
|
33045
|
+
},
|
|
32545
33046
|
{
|
|
32546
33047
|
"name": "preserveLineBreaks",
|
|
32547
33048
|
"type": "boolean | undefined",
|
|
@@ -32943,6 +33444,12 @@
|
|
|
32943
33444
|
"required": false,
|
|
32944
33445
|
"description": "Переопределяет размер квадратной кнопки (px), приоритет над SIZE_CONFIG"
|
|
32945
33446
|
},
|
|
33447
|
+
{
|
|
33448
|
+
"name": "overrideWidth",
|
|
33449
|
+
"type": "number | undefined",
|
|
33450
|
+
"required": false,
|
|
33451
|
+
"description": "Только EmbedIconButton: ширина кнопки в раскладке и hit-area (px),\nпо умолчанию — сторона квадрата. Иконка рисуется в квадрате от левого края."
|
|
33452
|
+
},
|
|
32946
33453
|
{
|
|
32947
33454
|
"name": "view",
|
|
32948
33455
|
"type": "ButtonView | undefined",
|
|
@@ -33553,10 +34060,10 @@
|
|
|
33553
34060
|
},
|
|
33554
34061
|
{
|
|
33555
34062
|
"exportName": "Usage2",
|
|
33556
|
-
"displayName": "Использование в
|
|
34063
|
+
"displayName": "Использование в TableCanvasTooltip.stories.tsx",
|
|
33557
34064
|
"type": "usage",
|
|
33558
|
-
"code": "<Canvas.Text\n
|
|
33559
|
-
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.
|
|
34065
|
+
"code": "<Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip\n style={{ flexGrow: 1 }}\n >\n {`${row.task}: ${longText}`}\n </Canvas.Text>",
|
|
34066
|
+
"sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx"
|
|
33560
34067
|
}
|
|
33561
34068
|
]
|
|
33562
34069
|
},
|
|
@@ -33928,6 +34435,12 @@
|
|
|
33928
34435
|
"required": false,
|
|
33929
34436
|
"description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
|
|
33930
34437
|
},
|
|
34438
|
+
{
|
|
34439
|
+
"name": "getCellBorder",
|
|
34440
|
+
"type": "CellBorderResolver | undefined",
|
|
34441
|
+
"required": false,
|
|
34442
|
+
"description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
|
|
34443
|
+
},
|
|
33931
34444
|
{
|
|
33932
34445
|
"name": "getCellsForSelection",
|
|
33933
34446
|
"type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
|
|
@@ -33970,12 +34483,24 @@
|
|
|
33970
34483
|
"required": false,
|
|
33971
34484
|
"description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
|
|
33972
34485
|
},
|
|
34486
|
+
{
|
|
34487
|
+
"name": "hiddenColumnsIndicator",
|
|
34488
|
+
"type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
|
|
34489
|
+
"required": false,
|
|
34490
|
+
"description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
|
|
34491
|
+
},
|
|
33973
34492
|
{
|
|
33974
34493
|
"name": "highlightRegions",
|
|
33975
34494
|
"type": "readonly Highlight[] | undefined",
|
|
33976
34495
|
"required": false,
|
|
33977
34496
|
"description": "Highlight regions provide hints to users about relations between cells and selections."
|
|
33978
34497
|
},
|
|
34498
|
+
{
|
|
34499
|
+
"name": "horizontalBorder",
|
|
34500
|
+
"type": "boolean | ((row: number) => boolean) | undefined",
|
|
34501
|
+
"required": false,
|
|
34502
|
+
"description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
|
|
34503
|
+
},
|
|
33979
34504
|
{
|
|
33980
34505
|
"name": "imageEditorOverride",
|
|
33981
34506
|
"type": "ImageEditorType | undefined",
|
|
@@ -34174,6 +34699,12 @@
|
|
|
34174
34699
|
"required": false,
|
|
34175
34700
|
"description": "Emitted when a header menu disclosure indicator is clicked."
|
|
34176
34701
|
},
|
|
34702
|
+
{
|
|
34703
|
+
"name": "onHiddenColumnsIndicatorClicked",
|
|
34704
|
+
"type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
|
|
34705
|
+
"required": false,
|
|
34706
|
+
"description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
|
|
34707
|
+
},
|
|
34177
34708
|
{
|
|
34178
34709
|
"name": "onItemHovered",
|
|
34179
34710
|
"type": "((args: GridMouseEventArgs) => void) | undefined",
|
|
@@ -35267,6 +35798,13 @@
|
|
|
35267
35798
|
"required": false,
|
|
35268
35799
|
"description": "Сменить рендер на другой тип компонента."
|
|
35269
35800
|
},
|
|
35801
|
+
{
|
|
35802
|
+
"name": "disableScroll",
|
|
35803
|
+
"type": "boolean | undefined",
|
|
35804
|
+
"required": false,
|
|
35805
|
+
"description": "Отключает скролл к TabItem при его выборе",
|
|
35806
|
+
"default": "false"
|
|
35807
|
+
},
|
|
35270
35808
|
{
|
|
35271
35809
|
"name": "itemIndex",
|
|
35272
35810
|
"type": "number | undefined",
|
|
@@ -35348,6 +35886,13 @@
|
|
|
35348
35886
|
"required": false,
|
|
35349
35887
|
"description": "Контент справа"
|
|
35350
35888
|
},
|
|
35889
|
+
{
|
|
35890
|
+
"name": "disableScroll",
|
|
35891
|
+
"type": "boolean | undefined",
|
|
35892
|
+
"required": false,
|
|
35893
|
+
"description": "Отключает скролл к TabItem при его выборе",
|
|
35894
|
+
"default": "false"
|
|
35895
|
+
},
|
|
35351
35896
|
{
|
|
35352
35897
|
"name": "itemIndex",
|
|
35353
35898
|
"type": "number | undefined",
|
|
@@ -35520,6 +36065,15 @@
|
|
|
35520
36065
|
"inheritedFrom": "Tabs",
|
|
35521
36066
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
35522
36067
|
},
|
|
36068
|
+
{
|
|
36069
|
+
"name": "pilled",
|
|
36070
|
+
"type": "boolean",
|
|
36071
|
+
"required": false,
|
|
36072
|
+
"description": "Табы c округлым border-radius",
|
|
36073
|
+
"default": "false",
|
|
36074
|
+
"inheritedFrom": "Tabs",
|
|
36075
|
+
"inheritedPackage": "@salutejs/sdds-finai"
|
|
36076
|
+
},
|
|
35523
36077
|
{
|
|
35524
36078
|
"name": "size",
|
|
35525
36079
|
"type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"s\" | \"l\" | \"m\" | \"xs\"",
|
|
@@ -35557,13 +36111,6 @@
|
|
|
35557
36111
|
"inheritedFrom": "Tabs",
|
|
35558
36112
|
"inheritedPackage": "@salutejs/sdds-finai"
|
|
35559
36113
|
},
|
|
35560
|
-
{
|
|
35561
|
-
"name": "pilled",
|
|
35562
|
-
"type": "boolean",
|
|
35563
|
-
"required": false,
|
|
35564
|
-
"inheritedFrom": "Tabs",
|
|
35565
|
-
"inheritedPackage": "@salutejs/sdds-finai"
|
|
35566
|
-
},
|
|
35567
36114
|
{
|
|
35568
36115
|
"name": "stretch",
|
|
35569
36116
|
"type": "boolean",
|
|
@@ -35658,7 +36205,7 @@
|
|
|
35658
36205
|
},
|
|
35659
36206
|
{
|
|
35660
36207
|
"name": "size",
|
|
35661
|
-
"type": "
|
|
36208
|
+
"type": "string | undefined",
|
|
35662
36209
|
"required": false,
|
|
35663
36210
|
"description": "Размер табов"
|
|
35664
36211
|
},
|
|
@@ -36900,7 +37447,14 @@
|
|
|
36900
37447
|
"folderName": "TimePicker",
|
|
36901
37448
|
"role": "primary",
|
|
36902
37449
|
"description": "Поле ввода времени с масками часов/минут/секунд и ограничением диапазона.",
|
|
36903
|
-
"props": [
|
|
37450
|
+
"props": [
|
|
37451
|
+
{
|
|
37452
|
+
"name": "hasTimeFormat",
|
|
37453
|
+
"type": "boolean | undefined",
|
|
37454
|
+
"required": false,
|
|
37455
|
+
"description": ""
|
|
37456
|
+
}
|
|
37457
|
+
],
|
|
36904
37458
|
"propsTypeName": "TimePickerProps",
|
|
36905
37459
|
"sourceFile": "node_modules/@salutejs/sdds-finai/types/components/TimePicker/TimePicker.d.ts",
|
|
36906
37460
|
"type": "wrapper",
|
|
@@ -38782,7 +39336,7 @@
|
|
|
38782
39336
|
"exportName": "Usage2",
|
|
38783
39337
|
"displayName": "Использование в TourWidget.examples.tsx",
|
|
38784
39338
|
"type": "usage",
|
|
38785
|
-
"code": "<TourWidget.Header
|
|
39339
|
+
"code": "<TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />",
|
|
38786
39340
|
"sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
|
|
38787
39341
|
}
|
|
38788
39342
|
]
|
|
@@ -38915,7 +39469,7 @@
|
|
|
38915
39469
|
"онбординг",
|
|
38916
39470
|
"степ-виджет"
|
|
38917
39471
|
],
|
|
38918
|
-
"docs": "# TourWidget\n\n`TourWidget` — локальная compound-обертка для карточки тура. Компонент отвечает за внешний вид, раскладку, фон, буллеты и пульсацию через mixin, но не управляет сценарием тура, переходами между шагами и позиционированием относительно target-элемента.\n\n## Ключевые особенности\n\n- Две ориентации: `vertical` и `horizontal`.\n- Compound API: `TourWidget.Header`, `TourWidget.Content`, `TourWidget.Footer`, `TourWidget.Bullets`, `TourWidget.Bullet`.\n- Активный шаг передается в `TourWidget` через `activeStepIndex`, а `Bullet` читает его автоматически.\n- `Content` не фиксирует размер вложенного элемента и дает ему занять `100%`.\n- `$css` есть у корневого компонента и compound-частей для локального переопределения стилей.\n- Пульсация вынесена в `tourPulseMixin` и применяется отдельно к target-элементу.\n\n## Использование\n\n```tsx\n\n```\n\nБазовая схема работы:\n\n```tsx\nconst [activeStepIndex, setActiveStepIndex] = useState(0);\n\n<ViewContainer view=\"onDark\">\n <TourWidget\n activeStepIndex={activeStepIndex}\n $css={{ width: '286px', height: '480px' }}\n >\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>;\n```\n\n## Compound-компоненты\n\n- `TourWidget.Header` — выводит `title`, `description` и дополнительные `children`.\n- `TourWidget.Content` — область под изображение, видео, иллюстрацию или любой ReactNode.\n- `TourWidget.Footer` — произвольная зона для кнопок, ссылки пропуска и буллетов.\n- `TourWidget.Bullets` — контейнер, который рисует массив буллетов по `count`; если буллетов больше семи, отображает окно максимум на 7 точек, прокручивает его по `activeStepIndex`, а крайние видимые точки уменьшаются до `6px`, когда за ними есть скрытые шаги.\n- `TourWidget.Bullet` — низкоуровневый визуальный индикатор шага. Активность считается как `active ?? index === activeStepIndex`.\n\n## Правильная композиция\n\n`TourWidget.Header`, `TourWidget.Content` и `TourWidget.Footer` нужно вкладывать напрямую в `TourWidget`. Компонент использует эти части как слоты: так он понимает, есть ли в туре медиа-зона, и выбирает корректную раскладку для `horizontal` и `vertical`.\n\nПравильно:\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужен свой wrapper для картинки, кнопок или текста, размещайте его внутри соответствующего slot-компонента.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <MyImageWrapper>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </MyImageWrapper>\n </TourWidget.Content>\n <TourWidget.Header>\n <MyHeaderContent />\n </TourWidget.Header>\n <TourWidget.Footer>\n <MyFooterContent />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nНе оборачивайте сам `TourWidget.Content` во внешний компонент. В таком случае `TourWidget` не сможет определить медиа-зону как свой прямой slot и горизонтальная раскладка будет работать как вариант без `Content`.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <MyContentWrapper>\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </TourWidget.Content>\n </MyContentWrapper>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer />\n</TourWidget>\n```\n\n## Активный шаг\n\n`activeStepIndex` хранится на корневом `TourWidget`. Внутри компонент создает локальный context, поэтому не нужно импортировать `Provider` или прокидывать `active` в каждый буллет.\n\n```tsx\n<TourWidget activeStepIndex={5}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nДля переключения шагов используйте свои кнопки или другой внешний контрол. `TourWidget.Bullets` не кликабельный и только отображает `activeStepIndex`.\n\n```tsx\n<TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужна полностью ручная раскладка или состояние отдельной точки, используйте низкоуровневый `TourWidget.Bullet` и передайте `active`.\n\n## Content\n\n`TourWidget.Content` не задает жесткий размер медиа. Размер определяет вложенная нода или стиль самого `Content`.\n\n```tsx\n<TourWidget.Content>\n <Box\n as=\"img\"\n src={imageSrc}\n alt=\"\"\n $css={{ width: '270px', height: '270px' }}\n />\n</TourWidget.Content>\n```\n\n## Пульсация\n\nПульсация не встроена в `TourWidget`, потому что target-элемент и позиционирование тура контролируются снаружи. Для target используется `tourPulseMixin`.\n\n```tsx\n\nconst Target = styled(Box)`\n position: relative;\n\n &::after {\n content: '';\n position: absolute;\n ${tourPulseMixin()}\n }\n`;\n```\n\nПо умолчанию `tourPulseMixin` сам задает `inset: -4px` и `border-radius: 16px` и не добавляет заливку на target.\n\n## Темная тема\n\n`TourWidget` всегда используется на темной поверхности. Если внутри футера есть SDDS-кнопки или ссылки, оборачивайте композицию в `ViewContainer view=\"onDark\"`, чтобы вложенные controls взяли on-dark токены без ручных переопределений цвета.\n\n```tsx\n<ViewContainer view=\"onDark\">\n <TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <Button view=\"secondary\">Назад</Button>\n <Button view=\"white\">Далее</Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>\n```\n\n## CSS-переменные\n\nКорневой `$css` можно использовать для точечной настройки внешнего вида.\n\n```tsx\n<TourWidget\n $css={{\n '--tour-widget-min-width': '0',\n '--tour-widget-border-radius': '16px',\n '--tour-widget-gradient-frame-height': '34%',\n '--tour-widget-gradient-frame-fade': '56%',\n }}\n/>\n```\n\n## Особенности\n\n- `TourWidget` не содержит positioner и не добавляет зависимость на `floating-ui`.\n- Компонент не хранит шаги и не переключает их сам, только отображает `activeStepIndex`.\n- `TourWidget.Bullet` — это span-индикатор, а не интерактивная кнопка.\n- `TourWidget.Bullets` — это div-viewport со сдвигающимся треком точек; при `count > 7` видны максимум семь буллетов.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tourwidget-api--docs).",
|
|
39472
|
+
"docs": "# TourWidget\n\n`TourWidget` — локальная compound-обертка для карточки тура. Компонент отвечает за внешний вид, раскладку, фон, буллеты и пульсацию через mixin, но не управляет сценарием тура, переходами между шагами и позиционированием относительно target-элемента.\n\n## Ключевые особенности\n\n- Две ориентации: `vertical` и `horizontal`.\n- Compound API: `TourWidget.Header`, `TourWidget.Content`, `TourWidget.Footer`, `TourWidget.Bullets`, `TourWidget.Bullet`.\n- Заголовок и описание сохраняют переводы строк `\\n` (`white-space: pre-line`); повторяющиеся пробелы схлопываются, автоматический перенос по ширине сохраняется.\n- Активный шаг передается в `TourWidget` через `activeStepIndex`, а `Bullet` читает его автоматически.\n- `Content` не фиксирует размер вложенного элемента и дает ему занять `100%`.\n- `$css` есть у корневого компонента и compound-частей для локального переопределения стилей.\n- Пульсация вынесена в `tourPulseMixin` и применяется отдельно к target-элементу.\n\n## Использование\n\n```tsx\n\n```\n\nБазовая схема работы:\n\n```tsx\nconst [activeStepIndex, setActiveStepIndex] = useState(0);\n\n<ViewContainer view=\"onDark\">\n <TourWidget\n activeStepIndex={activeStepIndex}\n $css={{ width: '286px', height: '480px' }}\n >\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>;\n```\n\n## Compound-компоненты\n\n- `TourWidget.Header` — выводит `title`, `description` и дополнительные `children`.\n- `TourWidget.Content` — область под изображение, видео, иллюстрацию или любой ReactNode.\n- `TourWidget.Footer` — произвольная зона для кнопок, ссылки пропуска и буллетов.\n- `TourWidget.Bullets` — контейнер, который рисует массив буллетов по `count`; если буллетов больше семи, отображает окно максимум на 7 точек, прокручивает его по `activeStepIndex`, а крайние видимые точки уменьшаются до `6px`, когда за ними есть скрытые шаги.\n- `TourWidget.Bullet` — низкоуровневый визуальный индикатор шага. Активность считается как `active ?? index === activeStepIndex`.\n\n## Правильная композиция\n\n`TourWidget.Header`, `TourWidget.Content` и `TourWidget.Footer` нужно вкладывать напрямую в `TourWidget`. Компонент использует эти части как слоты: так он понимает, есть ли в туре медиа-зона, и выбирает корректную раскладку для `horizontal` и `vertical`.\n\nПравильно:\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужен свой wrapper для картинки, кнопок или текста, размещайте его внутри соответствующего slot-компонента.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <MyImageWrapper>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </MyImageWrapper>\n </TourWidget.Content>\n <TourWidget.Header>\n <MyHeaderContent />\n </TourWidget.Header>\n <TourWidget.Footer>\n <MyFooterContent />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nНе оборачивайте сам `TourWidget.Content` во внешний компонент. В таком случае `TourWidget` не сможет определить медиа-зону как свой прямой slot и горизонтальная раскладка будет работать как вариант без `Content`.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <MyContentWrapper>\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </TourWidget.Content>\n </MyContentWrapper>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer />\n</TourWidget>\n```\n\n## Активный шаг\n\n`activeStepIndex` хранится на корневом `TourWidget`. Внутри компонент создает локальный context, поэтому не нужно импортировать `Provider` или прокидывать `active` в каждый буллет.\n\n```tsx\n<TourWidget activeStepIndex={5}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nДля переключения шагов используйте свои кнопки или другой внешний контрол. `TourWidget.Bullets` не кликабельный и только отображает `activeStepIndex`.\n\n```tsx\n<TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужна полностью ручная раскладка или состояние отдельной точки, используйте низкоуровневый `TourWidget.Bullet` и передайте `active`.\n\n## Content\n\n`TourWidget.Content` не задает жесткий размер медиа. Размер определяет вложенная нода или стиль самого `Content`.\n\n```tsx\n<TourWidget.Content>\n <Box\n as=\"img\"\n src={imageSrc}\n alt=\"\"\n $css={{ width: '270px', height: '270px' }}\n />\n</TourWidget.Content>\n```\n\n## Пульсация\n\nПульсация не встроена в `TourWidget`, потому что target-элемент и позиционирование тура контролируются снаружи. Для target используется `tourPulseMixin`.\n\n```tsx\n\nconst Target = styled(Box)`\n position: relative;\n\n &::after {\n content: '';\n position: absolute;\n ${tourPulseMixin()}\n }\n`;\n```\n\nПо умолчанию `tourPulseMixin` сам задает `inset: -4px` и `border-radius: 16px` и не добавляет заливку на target.\n\n## Темная тема\n\n`TourWidget` всегда используется на темной поверхности. Если внутри футера есть SDDS-кнопки или ссылки, оборачивайте композицию в `ViewContainer view=\"onDark\"`, чтобы вложенные controls взяли on-dark токены без ручных переопределений цвета.\n\n```tsx\n<ViewContainer view=\"onDark\">\n <TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <Button view=\"secondary\">Назад</Button>\n <Button view=\"white\">Далее</Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>\n```\n\n## CSS-переменные\n\nКорневой `$css` можно использовать для точечной настройки внешнего вида.\n\n```tsx\n<TourWidget\n $css={{\n '--tour-widget-min-width': '0',\n '--tour-widget-border-radius': '16px',\n '--tour-widget-gradient-frame-height': '34%',\n '--tour-widget-gradient-frame-fade': '56%',\n }}\n/>\n```\n\n## Особенности\n\n- `TourWidget` не содержит positioner и не добавляет зависимость на `floating-ui`.\n- Компонент не хранит шаги и не переключает их сам, только отображает `activeStepIndex`.\n- `TourWidget.Bullet` — это span-индикатор, а не интерактивная кнопка.\n- `TourWidget.Bullets` — это div-viewport со сдвигающимся треком точек; при `count > 7` видны максимум семь буллетов.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tourwidget-api--docs).",
|
|
38919
39473
|
"apiDocs": "# TourWidget API\n\n## TourWidgetOrientation\n\n```typescript\ntype TourWidgetOrientation = 'vertical' | 'horizontal';\n```\n\n## TourWidgetCss\n\n```typescript\ntype TourWidgetCss = string | CSSObject | FlattenSimpleInterpolation;\n```\n\n## TourWidgetProps\n\n```typescript\ntype TourWidgetProps = ComponentPropsWithoutRef<'div'> & {\n /**\n * @default 'vertical'\n */\n orientation?: TourWidgetOrientation;\n /**\n * Активный шаг тура. Нумерация с нуля.\n */\n activeStepIndex?: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Header\n\n```typescript\ntype TourWidgetHeaderProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'title'\n> & {\n title?: ReactNode;\n description?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Content\n\n```typescript\ntype TourWidgetContentProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Footer\n\n```typescript\ntype TourWidgetFooterProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullets\n\n```typescript\ntype TourWidgetBulletsProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children' | 'onClick'\n> & {\n count: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullet\n\n```typescript\ntype TourWidgetBulletProps = Omit<\n ComponentPropsWithoutRef<'span'>,\n 'onClick'\n> & {\n /**\n * Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`.\n */\n index?: number;\n /**\n * Ручное переопределение активного состояния.\n */\n active?: boolean;\n $css?: TourWidgetCss;\n};\n```",
|
|
38920
39474
|
"curatedStories": [
|
|
38921
39475
|
{
|
|
@@ -38930,6 +39484,12 @@
|
|
|
38930
39484
|
"type": "full-code",
|
|
38931
39485
|
"code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourView>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '260px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
|
|
38932
39486
|
},
|
|
39487
|
+
{
|
|
39488
|
+
"exportName": "LineBreaks",
|
|
39489
|
+
"displayName": "Переносы строк",
|
|
39490
|
+
"type": "full-code",
|
|
39491
|
+
"code": "function LineBreaksExample() {\n return (\n <TourView>\n <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n </TourView>\n );\n};"
|
|
39492
|
+
},
|
|
38933
39493
|
{
|
|
38934
39494
|
"exportName": "TourWithPulse",
|
|
38935
39495
|
"displayName": "Тур рядом с пульсацией",
|
|
@@ -38975,16 +39535,16 @@
|
|
|
38975
39535
|
"code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourView>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '260px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
|
|
38976
39536
|
},
|
|
38977
39537
|
{
|
|
38978
|
-
"exportName": "
|
|
38979
|
-
"displayName": "
|
|
39538
|
+
"exportName": "LineBreaks",
|
|
39539
|
+
"displayName": "Переносы строк",
|
|
38980
39540
|
"type": "full-code",
|
|
38981
|
-
"code": "function
|
|
39541
|
+
"code": "function LineBreaksExample() {\n return (\n <TourView>\n <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n </TourView>\n );\n};"
|
|
38982
39542
|
},
|
|
38983
39543
|
{
|
|
38984
|
-
"exportName": "
|
|
38985
|
-
"displayName": "
|
|
39544
|
+
"exportName": "TourWithPulse",
|
|
39545
|
+
"displayName": "Тур рядом с пульсацией",
|
|
38986
39546
|
"type": "full-code",
|
|
38987
|
-
"code": "function
|
|
39547
|
+
"code": "function TourWithPulseExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <TourView>\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '264px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n </TourView>\n );\n};"
|
|
38988
39548
|
}
|
|
38989
39549
|
]
|
|
38990
39550
|
},
|
|
@@ -45223,6 +45783,12 @@
|
|
|
45223
45783
|
"description": "Отступ календаря относительно поля ввода.",
|
|
45224
45784
|
"default": "[0, 2]"
|
|
45225
45785
|
},
|
|
45786
|
+
{
|
|
45787
|
+
"name": "onChangeVisibleDate",
|
|
45788
|
+
"type": "((date: Date) => void) | undefined",
|
|
45789
|
+
"required": false,
|
|
45790
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
45791
|
+
},
|
|
45226
45792
|
{
|
|
45227
45793
|
"name": "onToggle",
|
|
45228
45794
|
"type": "((isOpen: boolean, event?: Event | React.SyntheticEvent<Element, Event> | undefined) => void) | undefined",
|
|
@@ -45259,7 +45825,7 @@
|
|
|
45259
45825
|
"name": "stretched",
|
|
45260
45826
|
"type": "boolean | undefined",
|
|
45261
45827
|
"required": false,
|
|
45262
|
-
"description": "Растянуть поле ввода на всю доступную ширину"
|
|
45828
|
+
"description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
|
|
45263
45829
|
},
|
|
45264
45830
|
{
|
|
45265
45831
|
"name": "type",
|
|
@@ -45710,6 +46276,12 @@
|
|
|
45710
46276
|
"description": "Отступ календаря относительно поля ввода.",
|
|
45711
46277
|
"default": "[0, 0]"
|
|
45712
46278
|
},
|
|
46279
|
+
{
|
|
46280
|
+
"name": "onChangeVisibleDate",
|
|
46281
|
+
"type": "((date: Date) => void) | undefined",
|
|
46282
|
+
"required": false,
|
|
46283
|
+
"description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
|
|
46284
|
+
},
|
|
45713
46285
|
{
|
|
45714
46286
|
"name": "onToggle",
|
|
45715
46287
|
"type": "((isOpen: boolean, event?: Event | React.SyntheticEvent<Element, Event> | undefined) => void) | undefined",
|
|
@@ -45738,7 +46310,7 @@
|
|
|
45738
46310
|
"name": "stretched",
|
|
45739
46311
|
"type": "boolean | undefined",
|
|
45740
46312
|
"required": false,
|
|
45741
|
-
"description": "Растянуть поле ввода на всю доступную ширину"
|
|
46313
|
+
"description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
|
|
45742
46314
|
},
|
|
45743
46315
|
{
|
|
45744
46316
|
"name": "type",
|
|
@@ -46615,6 +47187,12 @@
|
|
|
46615
47187
|
"description": "Задает выравнивание индикатора обязательности поля",
|
|
46616
47188
|
"default": "right"
|
|
46617
47189
|
},
|
|
47190
|
+
{
|
|
47191
|
+
"name": "suffix",
|
|
47192
|
+
"type": "string | undefined",
|
|
47193
|
+
"required": false,
|
|
47194
|
+
"description": "Суффикс текста в поле ввода."
|
|
47195
|
+
},
|
|
46618
47196
|
{
|
|
46619
47197
|
"name": "thousandSeparator",
|
|
46620
47198
|
"type": "string | boolean | undefined",
|
|
@@ -47124,6 +47702,13 @@
|
|
|
47124
47702
|
"required": true,
|
|
47125
47703
|
"description": ""
|
|
47126
47704
|
},
|
|
47705
|
+
{
|
|
47706
|
+
"name": "clip",
|
|
47707
|
+
"type": "boolean | undefined",
|
|
47708
|
+
"required": false,
|
|
47709
|
+
"description": "При ограничении ширины разрешает скролл и отображает дополнительные элементы со стрелками",
|
|
47710
|
+
"default": "true"
|
|
47711
|
+
},
|
|
47127
47712
|
{
|
|
47128
47713
|
"name": "filledBackground",
|
|
47129
47714
|
"type": "boolean | undefined",
|
|
@@ -47225,14 +47810,6 @@
|
|
|
47225
47810
|
"type": "React.ReactNode",
|
|
47226
47811
|
"required": false,
|
|
47227
47812
|
"description": ""
|
|
47228
|
-
},
|
|
47229
|
-
{
|
|
47230
|
-
"name": "clip",
|
|
47231
|
-
"type": "boolean | undefined",
|
|
47232
|
-
"required": false,
|
|
47233
|
-
"description": "При ограничении ширины разрешает скролл и отображает дополнительные элементы со стрелками",
|
|
47234
|
-
"deprecated": true,
|
|
47235
|
-
"default": "true"
|
|
47236
47813
|
}
|
|
47237
47814
|
],
|
|
47238
47815
|
"propsTypeName": "FormSegmentGroupProps",
|
|
@@ -49600,6 +50177,13 @@
|
|
|
49600
50177
|
"required": false,
|
|
49601
50178
|
"description": "Контент справа"
|
|
49602
50179
|
},
|
|
50180
|
+
{
|
|
50181
|
+
"name": "disableScroll",
|
|
50182
|
+
"type": "boolean | undefined",
|
|
50183
|
+
"required": false,
|
|
50184
|
+
"description": "Отключает скролл к TabItem при его выборе",
|
|
50185
|
+
"default": "false"
|
|
50186
|
+
},
|
|
49603
50187
|
{
|
|
49604
50188
|
"name": "itemIndex",
|
|
49605
50189
|
"type": "number | undefined",
|
|
@@ -49639,7 +50223,7 @@
|
|
|
49639
50223
|
},
|
|
49640
50224
|
{
|
|
49641
50225
|
"name": "size",
|
|
49642
|
-
"type": "\"s\" | \"xs\" | \"m\" | \"
|
|
50226
|
+
"type": "\"s\" | \"xs\" | \"m\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | \"l\" | undefined",
|
|
49643
50227
|
"required": false,
|
|
49644
50228
|
"description": ""
|
|
49645
50229
|
},
|
|
@@ -49747,6 +50331,14 @@
|
|
|
49747
50331
|
"type": "string | undefined",
|
|
49748
50332
|
"required": false,
|
|
49749
50333
|
"description": "Вид табов"
|
|
50334
|
+
},
|
|
50335
|
+
{
|
|
50336
|
+
"name": "pilled",
|
|
50337
|
+
"type": "boolean | undefined",
|
|
50338
|
+
"required": false,
|
|
50339
|
+
"description": "Табы c округлым border-radius",
|
|
50340
|
+
"deprecated": true,
|
|
50341
|
+
"default": "false"
|
|
49750
50342
|
}
|
|
49751
50343
|
],
|
|
49752
50344
|
"propsTypeName": "ComponentProps<typeof FiltersActionsTabs>",
|
|
@@ -50577,6 +51169,14 @@
|
|
|
50577
51169
|
"type": "string | undefined",
|
|
50578
51170
|
"required": false,
|
|
50579
51171
|
"description": "Вид табов"
|
|
51172
|
+
},
|
|
51173
|
+
{
|
|
51174
|
+
"name": "pilled",
|
|
51175
|
+
"type": "boolean | undefined",
|
|
51176
|
+
"required": false,
|
|
51177
|
+
"description": "Табы c округлым border-radius",
|
|
51178
|
+
"deprecated": true,
|
|
51179
|
+
"default": "false"
|
|
50580
51180
|
}
|
|
50581
51181
|
]
|
|
50582
51182
|
},
|
|
@@ -50608,6 +51208,13 @@
|
|
|
50608
51208
|
"required": false,
|
|
50609
51209
|
"description": "Контент справа"
|
|
50610
51210
|
},
|
|
51211
|
+
{
|
|
51212
|
+
"name": "disableScroll",
|
|
51213
|
+
"type": "boolean | undefined",
|
|
51214
|
+
"required": false,
|
|
51215
|
+
"description": "Отключает скролл к TabItem при его выборе",
|
|
51216
|
+
"default": "false"
|
|
51217
|
+
},
|
|
50611
51218
|
{
|
|
50612
51219
|
"name": "itemIndex",
|
|
50613
51220
|
"type": "number | undefined",
|
|
@@ -50647,7 +51254,7 @@
|
|
|
50647
51254
|
},
|
|
50648
51255
|
{
|
|
50649
51256
|
"name": "size",
|
|
50650
|
-
"type": "\"s\" | \"xs\" | \"m\" | \"
|
|
51257
|
+
"type": "\"s\" | \"xs\" | \"m\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | \"l\" | undefined",
|
|
50651
51258
|
"required": false,
|
|
50652
51259
|
"description": ""
|
|
50653
51260
|
},
|
|
@@ -51896,6 +52503,12 @@
|
|
|
51896
52503
|
"displayName": "Default",
|
|
51897
52504
|
"type": "full-code",
|
|
51898
52505
|
"code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst columnConfig: ColumnConfig[] = [\n {\n key: 'status',\n name: 'Статус',\n width: 120,\n renderCell: ({ row }) => (\n <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n <Canvas.Badge text={row.status} view=\"accent\" size=\"s\" />\n </Canvas.Container>\n ),\n },\n];\n\n<TableCanvas\n tableConfig={{ containerStyle: { height: '400px' } }}\n columnConfig={columnConfig}\n rows={rows}\n/>"
|
|
52506
|
+
},
|
|
52507
|
+
{
|
|
52508
|
+
"exportName": "IconOnly",
|
|
52509
|
+
"displayName": "Only Icon",
|
|
52510
|
+
"type": "full-code",
|
|
52511
|
+
"code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { IconSearch } from '@daisforge/ui/icons';\n\nconst icon = Canvas.icon(<IconSearch />);\n\nconst columnConfig: ColumnConfig[] = [\n {\n key: 'badge',\n name: 'Бейдж',\n width: 120,\n renderCell: ({ row }) => (\n <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n <Canvas.Badge text=\"\" leftIcon={icon} view={row.view} size=\"s\" />\n </Canvas.Container>\n ),\n },\n];\n\n<TableCanvas\n tableConfig={{ containerStyle: { height: '400px' } }}\n columnConfig={columnConfig}\n rows={rows}\n/>"
|
|
51899
52512
|
}
|
|
51900
52513
|
]
|
|
51901
52514
|
},
|
|
@@ -52132,8 +52745,8 @@
|
|
|
52132
52745
|
"feature": "CellsMerging",
|
|
52133
52746
|
"legacy": false,
|
|
52134
52747
|
"summary": "Объединение ячеек тела таблицы: по строкам (rowSpan), по колонкам (colSpan) и",
|
|
52135
|
-
"docs": "# CellsMerging (TableCanvas)\n\nОбъединение ячеек тела таблицы: по строкам (rowSpan), по колонкам (colSpan) и\nпрямоугольными блоками. Несколько одинаковых ячеек рисуются одной большой, а всё\nвзаимодействие — клики, выделение, навигация, копирование, вставка, протяжка,\nредактирование — обращается с блоком как с одной ячейкой.\n\nЭта страница — обзор: как выбрать способ и с чего начать, плюс живые примеры.\nПодробности (совмещение способов, работа с деревом, выравнивание, сводные\nограничения) — в\n[Справочнике](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs),\nтипы — в\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Как это устроено\n\nГлавная идея простая: объединение — это способ показа, а не способ хранения.\n\n- В данных значение повторяется в каждой строке блока. Если «Отдел А» тянется на\n три строки, то во всех трёх строках в поле отдела записано «Отдел А».\n- Таблица замечает повторы (или получает границы блока явно) и вместо трёх\n одинаковых ячеек рисует одну высокую. Содержимое берётся из верхней-левой\n ячейки блока.\n- Данные при этом не меняются. Уберите объединение — увидите те же строки с теми\n же значениями.\n\nОтсюда следует и поведение, знакомое по Excel: клик в любую точку блока выделяет\nблок целиком, правка блока меняет значение во всех его строках, копирование\nотдаёт значение один раз.\n\n## Три способа включить объединение\n\nМеханика под всеми способами одна. Отличие — кто вычисляет границы блоков:\nпотребитель или таблица. Способы можно совмещать в одной таблице — правила в\nСправочнике, глава «Если включено несколько способов сразу».\n\n### 1. mergeCells.mergedCellsRegions — блоки, заданные снаружи\n\n«Слей вот эти конкретные ячейки». Список блоков по стабильным ключам строк и\nколонок; списком владеет потребитель, как выделением. Таблица переводит ключи в\nтекущие видимые позиции. Если сортировка, перестановка или скрытие колонки\nразорвали блок — он не рисуется (как ограничение сортировки в Excel).\n\n```tsx\ntableConfig={{\n mergeCells: {\n mergedCellsRegions: [\n { rowKeys: ['r1', 'r2'], colKeys: ['dept'] },\n { rowKeys: ['r4', 'r5'], colKeys: ['plan', 'fact'] }, // прямоугольник 2×2\n ],\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nПримеры — стори с префиксом `mergedCellsRegions:` ниже.\n\n### 2. mergeCells.mergeByCellValues — по одинаковым значениям\n\n«В этих колонках сливай подряд идущие одинаковые значения». Границы блоков\nтаблица вычисляет сама из данных; после сортировки или фильтра блоки\nпересобираются.\n\n```tsx\ntableConfig={{\n mergeCells: {\n mergeByCellValues: [\n 'dept', // по значению колонки\n { colKey: 'role', value: (row) => row.roleGroup }, // по своей функции\n ],\n },\n}}\n```\n\nОдинаковые названия в разных ветках иерархии могут ложно слиться — лечится\nсоставным ключом, разбор в Справочнике, глава «Объединение по значению: где\nпроходит граница». Примеры — стори с префиксом `mergeByCellValues:` ниже.\n\n### 3. Merged-виды группировки и subRows — полный автомат\n\nПотребитель включает вид — всю работу с блоками делает таблица: строки\nупорядочиваются по группам, колонки уровней сливаются по границам групп, чекбокс\nи нумерация работают по верхней группе.\n\nЧерез группировку (структуру задают значения группирующих колонок):\n\n```tsx\ntableConfig={{\n rowsGrouping: {\n view: 'merged',\n groupByState: [groupBy, setGroupBy], // например ['dept', 'role']\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nЧерез subRows (структуру задаёт готовое дерево потребителя):\n\n```tsx\ntableConfig={{\n subRows: {\n view: 'merged',\n mergedColumns: ['dept', 'role'], // колонки уровней дерева\n getSubRows: (row) => row.children,\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nПримеры — «subRows: дерево с пагинацией» и «rowsGrouping: группировка\nпользователем» в конце страницы.\n\n## Какой способ выбрать\n\nКартинка у способов похожая, поэтому выбирать стоит не по внешнему виду, а по\nтому, кто владеет данными и что нужно пользователю.\n\n### Дерево приходит с сервера, нужна постраничная загрузка — subRows\n\nЕсли данные уже иерархические (дивизион, управление, команда, сотрудники) и\nприходят от сервера частями, берите `subRows` с `view: 'merged'`. Дерево остаётся\nу вас: вы отдаёте таблице страницу дерева, она разворачивает её в строки и сама\nсливает колонки-предки. Именно поэтому здесь работает пагинация по верхним\nблокам — таблице не нужно видеть все данные сразу.\n\nОбратная сторона: раз данными владеете вы, то поиск, сортировка и фильтрация\nдерева — тоже на вашей стороне. Формат дерева, пагинация и возврат правок —\nв Справочнике, глава «Дерево через subRows».\n\n### Плоские строки, пользователь сам выбирает группировку — rowsGrouping\n\nЕсли строки плоские, а пользователь должен на лету решать, по каким колонкам\nгруппировать, — берите `rowsGrouping` с `view: 'merged'`. Состав группировки живёт\nв `groupByState`, а с настройкой `groupButton` в блоке управления появляется\nкнопка: пользователь сам выбирает колонки, таблица пересобирает блоки. Встроенные\nпоиск, сортировка и фильтры работают — таблица применяет их до сборки групп.\n\nОбратная сторона: пагинации в этом виде нет — таблице нужны все строки сразу.\nНе действует и всё, что привязано к строкам-групп и шевронам дерева\n(`groupedColumnProps`, `renderGroupCell`, `expandAllBtn`) — полный список в\nСправочнике, глава «Что не работает и почему».\n\n### Плоские строки, группировка фиксированная, всё считает сервер — mergeByCellValues\n\nЕсли структура известна заранее и не меняется пользователем, а данные (включая\nстраницы, сортировку и фильтры) готовит сервер, — самый прямой путь это\n`mergeByCellValues`. Вы упорядочиваете строки как нужно, таблица сливает соседние\nодинаковые значения. Никакой лишней механики: ни кнопок, ни дерева.\n\n### Отдельные ручные блоки — mergedCellsRegions\n\nШапки секций внутри таблицы, нестандартные прямоугольники, объединение по кнопке\nили из контекстного меню — всё, что не выводится из значений, делается регионами.\nПотребитель добавляет блок в свой список — таблица его рисует.\n\n## Смежные разделы\n\n- [Справочник](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs) —\n совмещение способов, составные ключи, дерево, выравнивание, сводные ограничения.\n- [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs) —\n типы.\n- Объединение ячеек шапки — раздел ColumnsGrouping (`squashEmptyCells`).\n\n## Полные примеры\n\nТри больших примера ниже собраны как заготовки для продуктов: в каждом —\nобъединение ячеек в связке с поиском, сортировкой, фильтрами, пагинацией,\nредактированием и выделением. Различаются они тем, кто владеет данными, поэтому\nи код обвязки разный. Полный код каждого примера открывается кнопкой «Show code»\nи снабжён комментариями по ключевым местам.\n\n### mergeByCellValues: пример с серверными данными\n\nДанные плоские, всё считает «сервер» (в примере его заменяет функция\n`selectPage`), таблица только рисует полученную страницу.\n\nЧто здесь показано:\n\n- поиск, фильтры, сортировка и пагинация в `manual`-режиме — считает потребитель;\n- составные ключи пути (`divPath` / `unitPath` / `teamPath`) против ложного\n слияния одинаковых имён из разных веток;\n- сортировка внутри команды — блоки не рассыпаются;\n- закрепление колонок вместе с групповой шапкой;\n- редактирование с возвратом правок страницы в полный набор.\n\n<Canvas of={CellsMergingExamples.Showcase} />\n\n### subRows: дерево с пагинацией\n\nДанные — дерево, и оно остаётся у потребителя: таблице отдаётся страница целых\nподдеревьев.\n\nЧто здесь показано:\n\n- пагинация по верхним блокам (дивизионам) со своим списком «показывать по»;\n- `manual`-поиск, сортировка и фильтры, посчитанные по дереву\n (функция `selectTreePage`);\n- сортировка показателей внутри команды и перестановка веток по имени;\n- возврат правок листьев обратно в дерево.\n\n<Canvas of={CellsMergingExamples.SubRowsMerged} />\n\n### rowsGrouping: группировка пользователем\n\nДанные плоские и передаются целиком, остальное делает таблица. Самый короткий\nкод из трёх.\n\nЧто здесь показано:\n\n- встроенные поиск, сортировка и фильтры — применяются до сборки групп;\n- выбор состава группировки пользователем (кнопка `groupButton`);\n- полный стейт фильтров: ключ на каждый фильтр из колонок;\n- без пагинации — чтобы собрать группы, таблице нужны все строки сразу.\n\n<Canvas of={CellsMergingExamples.GroupingMerged} />\n\n## Как перенести пример к себе\n\n1. Замените данные и типы строк на свои. Сохраните стабильный `id` строки — на\n нём держатся выделение и возврат правок, между страницами он меняться не\n должен.\n2. Замените `selectPage` / `selectTreePage` реальным запросом к серверу. Контракт\n тот же: параметры выборки на входе, страница и общее количество на выходе.\n3. Проверьте, что в `filtering.state` есть ключ каждого фильтра из колонок (со\n значением «показать всё»), — селект-фильтр без своего ключа молча отсеет все\n строки.\n4. Для `mergeByCellValues` заведите составные ключи пути, если одинаковые\n названия возможны в разных ветках иерархии.\n5. Уберите фичи, которые вам не нужны, — настройки в примерах независимы друг от\n друга: пагинация, закрепление, чекбоксы, редактирование отключаются по\n отдельности.\n\n# CellsMerging: справочник\n\nПодробности объединения ячеек: совмещение способов, составные ключи, работа с\nдеревом, взаимодействие с остальными фичами таблицы, выравнивание и сводный\nсписок ограничений. Обзор способов и живые примеры — на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs), типы —\nна странице\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Если включено несколько способов сразу\n\nСпособы можно совмещать в одной таблице — правила простые и считаются по колонке:\n\n- Если колонка входит хотя бы в один регион из `mergedCellsRegions`, её\n объединения описывают только регионы. `mergeByCellValues` на этой колонке не\n действует.\n- Колонка merged-вида (группировки или subRows) сливается по границам групп.\n Пользовательский `mergeByCellValues` на той же колонке не действует — иначе два\n механизма спорили бы за одни ячейки.\n- В остальных случаях работает `mergeByCellValues`.\n- Разные колонки живут независимо: регион на одной колонке и слияние по значению\n на другой — обычная рабочая комбинация.\n\nПример: таблица с группировкой по «Отделу» (merged-вид) может дополнительно\nсливать колонку «Статус» через `mergeByCellValues`, а строки-заголовки секций\nрисовать регионами на всю ширину — все три способа уживаются, потому что заняты\nразными колонками.\n\n## Объединение по значению: где проходит граница\n\nУ `mergeByCellValues` есть классическая ловушка. Допустим, регионы «Север» и «Юг»,\nи в каждом есть «Команда 1» и «Команда 2»:\n\n```\nСевер | Команда 1 | Иванов\nСевер | Команда 2 | Петров\nЮг | Команда 2 | Сидоров\nЮг | Команда 1 | Смирнов\n```\n\nЕсли сливать колонку команды по её значению, «Команда 2» из Севера и «Команда 2»\nиз Юга стоят рядом — и сольются в один блок через границу региона. Визуально это\nвыглядит как ошибка: одна команда, а на деле две разные.\n\nРешение — сливать не по тексту в ячейке, а по составному ключу, в котором зашит\nпуть от корня:\n\n```tsx\nmergeCells: {\n mergeByCellValues: [\n 'region',\n // Сравнивается результат функции, а не текст в ячейке.\n { colKey: 'team', value: (row) => `${row.region} / ${row.team}` },\n ],\n}\n```\n\nТеперь у «Команды 2» из Севера ключ «Север / Команда 2», а у южной —\n«Юг / Команда 2». Ключи разные, слияние останавливается на границе региона само,\nбез какой-либо отдельной логики. В ячейке при этом показывается обычное значение\nколонки — функция влияет только на сравнение.\n\nВ полном примере (стори «mergeByCellValues: пример с серверными данными») такие\nключи собраны заранее в полях строки: `divPath`, `unitPath`, `teamPath` — по\nодному на каждый уровень иерархии.\n\nMerged-виды группировки и subRows строят такие ключи сами — там об этой ловушке\nдумать не нужно.\n\n## Дерево через subRows: как передавать данные\n\nРазберём подробнее самый ёмкий сценарий — `subRows` с `view: 'merged'`.\n\n### Какое дерево ждёт таблица\n\nВ `rows` передаются корневые узлы, детей таблица достаёт через `getSubRows`.\nРоли узлов распределены так:\n\n- **Внутренние узлы** (дивизион, управление, команда) — ярлыки уровней. Каждый\n несёт поле с именем своей колонки из `mergedColumns`: узел дивизиона — поле\n `division`, узел управления — поле `unit`, и так далее.\n- **Листья** — строки данных. Именно они становятся строками таблицы со своими\n показателями; внутренние узлы отдельными строками не показываются.\n\n```tsx\nconst tree = [\n {\n id: 'd1',\n division: 'Розничный бизнес', // узел уровня 0\n subRows: [\n {\n id: 'u1',\n unit: 'Управление продаж', // узел уровня 1\n subRows: [\n {\n id: 't1',\n team: 'Команда Север', // узел уровня 2\n subRows: [\n { id: 'e1', employee: 'Иванов', plan: 100, fact: 90 }, // лист\n { id: 'e2', employee: 'Петров', plan: 80, fact: 85 },\n ],\n },\n ],\n },\n ],\n },\n];\n```\n\n```tsx\ntableConfig={{\n subRows: {\n view: 'merged',\n mergedColumns: ['division', 'unit', 'team'], // порядок = уровни дерева\n getSubRows: (row) => row.subRows,\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\n`mergedColumns` — это соответствие уровней дерева и колонок: первый элемент\nпоказывает узлы верхнего уровня, второй — следующего, и так далее. Колонка\n`division` возьмёт значение из узла дивизиона и сольётся на все его листья,\n`unit` — на листья своего управления, вложенно.\n\nСворачивания в этом виде нет: таблица показывает всё переданное дерево целиком.\nХотите меньше строк на экране — передайте меньший кусок дерева (следующий\nраздел).\n\n### Пагинация по верхним блокам\n\nДерево у вас, поэтому страницы нарезаете вы — по верхним узлам. Таблице отдаётся\nсрез дерева, а в `pagination.count` — общее число верхних узлов:\n\n```tsx\nconst [page, setPage] = useState(1);\nconst [perPage, setPerPage] = useState(2); // дивизионов на страницу\nconst pageTree = tree.slice((page - 1) * perPage, page * perPage);\n\ntableConfig={{\n pagination: {\n count: tree.length, // всего верхних узлов, не листьев\n perPage,\n perPageList: [1, 2, 3], // варианты «показывать по» — в блоках\n value: page,\n onChange: (nextPage, nextPerPage) => {\n if (typeof nextPerPage === 'number' && nextPerPage !== perPage) {\n setPerPage(nextPerPage);\n setPage(1);\n } else if (typeof nextPage === 'number') {\n setPage(nextPage);\n }\n },\n },\n subRows: { /* как выше */ },\n}}\n// ...\nrows={pageTree}\n```\n\nСтраница «2 дивизиона» может содержать разное число строк-листьев — это нормально:\nединица пагинации здесь блок, а не строка. По той же причине настройте селектор\n«Показывать по»: его стандартные варианты (20/50/100) рассчитаны на строки и для\nблоков не имеют смысла — задайте свой список `perPageList` в блоках, как выше,\nлибо спрячьте селектор (`hasPerPage: false`). Если дерево приходит с сервера\nчастями, вместо `slice` будет запрос следующей страницы — контракт тот же.\n\n### Редактирование: правки возвращаются листьями\n\nРедактируются листья. В `editing.onRowsChange` приходят изменённые строки-листья —\nзаписать их обратно в своё дерево должен потребитель, например по `id`:\n\n```tsx\nediting: {\n rowKeyGetter: (r) => r.id,\n onRowsChange: (updatedLeaves) => {\n const byId = new Map(updatedLeaves.map((r) => [r.id, r]));\n // Обойдите дерево и замените листья с совпавшими id.\n setTree((prev) => writeLeavesBack(prev, byId));\n },\n},\n```\n\nЭто следствие владения данными: таблица не знает, как устроено ваше дерево,\nпоэтому отдаёт плоский результат, а раскладываете его вы.\n\n### Что остаётся на вашей стороне\n\n- **Поиск, сортировка, фильтрация** — встроенные механизмы к структурному дереву\n пока не применяются. Отфильтровали или отсортировали своё дерево — передали\n результат в `rows`, таблица показала.\n- **Выделение** при этом работает из коробки: один чекбокс на верхний блок, клик\n выделяет все его листья (подробнее — в разделе про выделение ниже).\n\nЖивой пример всего вместе — стори «subRows: дерево с пагинацией» на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs).\n\n## Объединение и остальные возможности таблицы\n\nБлоки — не отдельный мир: выделение, сортировка, буфер обмена и редактирование\nпродолжают работать. Здесь собрано, как именно.\n\n### Выделение, нумерация и навигация\n\nВыделение настраивается как обычно — `selecting` со стейтом и `rowKeyGetter`.\nА вот ведёт оно себя по-разному в зависимости от способа объединения:\n\n- **Плоский вид с mergeByCellValues** — чекбокс у каждой строки, номер у каждой\n строки. Объединение колонок на выделение не влияет: в стори\n «mergeByCellValues: пример с серверными данными» можно выделить одного\n сотрудника внутри слитого блока.\n- **Merged-виды группировки и subRows** — один чекбокс и один номер на группу\n верхнего уровня. Клик по чекбоксу выделяет все строки группы разом, повторный —\n снимает. «Выделить всё» в шапке тоже работает. Счётчик выбранного внизу\n считает строки, а не группы: выделили дивизион из 12 сотрудников — внизу\n «выбрано 12».\n\nСпециально настраивать групповое поведение не нужно: таблица включает его сама,\nкогда активен merged-вид.\n\nНавигация тоже понимает блоки: клик в любую точку блока выделяет его целиком,\nрамка фокуса рисуется вокруг всего блока, один шаг стрелкой перепрыгивает блок.\nПопасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n\n### Сортировка, фильтрация, поиск и пагинация\n\nВозможности зависят от того, кто владеет данными.\n\n**mergeByCellValues (плоский вид).** Встроенные сортировка, фильтр и поиск\nработают как обычно, а блоки пересобираются после каждого изменения порядка —\nобъединение всегда отражает текущий видимый список строк. Если данные приходят с\nсервера постранично, следите, чтобы сортировка на сервере не разрывала группы:\nполовина группы на одной странице и половина на другой будут выглядеть как два\nотдельных блока.\n\n**rowsGrouping (view: 'merged').** Встроенные поиск, сортировка и фильтры\nработают: таблица применяет их к строкам до сборки групп, поэтому группы всегда\nсобираются из уже отфильтрованного списка. Пагинации нет: группировке нужны все\nстроки сразу. Сортировку по группирующим колонкам можно снять настройкой\n`disableGroupColumnsSort` — как в дереве, где сгруппированные колонки не\nсортируются.\n\nЧастая ошибка при встроенных фильтрах (не только в этом виде): в стейте\n`filtering.state` должен быть ключ каждого фильтра, объявленного в колонках.\nSelect-фильтр без своего ключа получит пустое значение вместо «показать всё» и\nможет отсеять все строки — таблица окажется пустой без единой ошибки.\n\n**subRows (view: 'merged').** Дерево у потребителя, поэтому пагинация по верхним\nблокам работает: отдаёте страницу дерева — таблица её показывает. Встроенные\nпоиск, сортировка и фильтрация к структурному дереву пока не применяются — эти\nоперации делаются на стороне потребителя над его данными.\n\n### Копирование, вставка и протяжка\n\n- Копирование отдаёт значение в позиции верхней-левой ячейки блока, остальные\n ячейки блока в буфере пустые — как в Excel.\n- Вставка пишет во весь блок: значение попадает во все его строки.\n- Протяжка (fill) растягивается только до целых блоков — залить пол-блока нельзя;\n пунктирная рамка протяжки сама прилипает к границам блоков.\n\n### Редактирование\n\n- Правка ячейки блока записывает значение во все его строки — данные под блоком\n всегда совпадают с тем, что на экране.\n- При объединении по значению правка пересобирает блоки: изменили «Отдел» у\n блока — он разъедется или сольётся с соседним, потому что объединение выводится\n из данных.\n- У редактируемых Select-ячеек редактор открывается по выравниванию блока: текст\n прижат к низу — редактор откроется у нижнего края, а выпадающий список\n раскроется вверх.\n\n## Выравнивание контента в блоке\n\nПо умолчанию контент блока выравнивается по горизонтали из `contentAlign` колонки\n(иначе слева), по вертикали — по центру. Настраивается лестницей «точечное важнее\nобщего»:\n\n- `mergedCellsAlign` конкретного региона (только для `mergedCellsRegions`);\n- `mergedCellsAlign` на колонке — все блоки этой колонки, работает для всех\n способов включения;\n- дефолт фичи: `mergeCells.mergedCellsAlign` или `rowsGrouping.mergedCellsAlign`.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', name: 'Отдел', mergedCellsAlign: { horizontal: 'center', vertical: 'top' } },\n]}\n```\n\nКолоночный `mergedCellsAlign` может быть и функцией `(row) => MergedCellsAlign`\nпо данным строки блока — так разные блоки одной колонки получают разное\nвыравнивание. Это единственный способ управлять выравниванием поблочно в\nmerged-видах группировки и subRows, где границы блоков решает таблица, а не\nпотребитель.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', mergedCellsAlign: (row) =>\n row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n### Свой рендер в блоке\n\nВыравнивание действует на текстовый контент. Кастомный `renderCell` получает весь\nпрямоугольник блока и выравнивает содержимое сам — через свойства своих\nконтейнеров.\n\nУ колонок со своим рендером есть неочевидность: предпросмотр значения (по\nдвойному клику на ячейке без редактирования) у них по умолчанию выключен.\nСо стороны это выглядит как «у блоков не открывается предпросмотр», хотя дело в\nколонке, а не в объединении. Включается настройкой колонки:\n\n```tsx\n{ key: 'dept', renderCell: ..., renderCellPreview: 'cellEditorAsPreview' }\n```\n\n## Что не работает и почему\n\nСводный список ограничений. Если «что-то не рисуется» — сначала сюда.\n\n### Во всех способах\n\n- Все ячейки блока обязаны нести одинаковые данные — это контракт\n `mergeByCellValues` (значения реально повторяются в строках) и регионов.\n Причина проста: блок показывает верхнюю-левую **видимую** ячейку, а какая\n ячейка окажется верхней-левой — зависит от закрепления и порядка колонок.\n Если данные одинаковые, блок выглядит одинаково при любой перестановке.\n- Попасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n Это поведение, а не ошибка.\n- Выравнивание пока не поддерживает письмо справа налево (RTL).\n- Горизонтальная протяжка через colSpan-блок не растягивается до границ блока\n (в работе).\n- У колонок со своим `renderCell` по умолчанию выключен предпросмотр значения —\n включается `renderCellPreview: 'cellEditorAsPreview'` (см. «Свой рендер в\n блоке» выше).\n\n### mergedCellsRegions\n\n- Разорванный регион исчезает молча: если после сортировки, перестановки или\n скрытия колонок ключи региона перестали идти подряд, блок просто не рисуется.\n Ошибок и предупреждений нет — следите за порядком сами.\n\n### rowsGrouping (view: 'merged')\n\n- Пагинации нет: чтобы собрать группы, таблице нужны все строки сразу.\n- Отдельная колонка «Группировка» не создаётся, поэтому не действует всё, что к\n ней привязано: `groupedColumnProps`, свой контент ячейки группы\n (`renderGroupCell` у колонки) и кнопка «развернуть всё» (`expandAllBtn`) —\n строк-групп и шевронов в этом виде нет.\n\n### subRows (view: 'merged')\n\n- Встроенные поиск, сортировка и фильтрация к структурному дереву не\n применяются — эти операции делает потребитель над своими данными.\n- `column.subRow` целиком не действует: шеврон (`isColumnWithArrow`), свой\n контент и ключи вложенных уровней (`renderSubRowCell`, `keyOfColumnInSubRow`,\n `parentKeyAsDefault`, `contentFormat`), свой редактор уровня. Листья рисуются\n как обычные строки — работают их обычные `renderCell`, `contentFormat` и\n `editingCell`.\n- `expandedIdsState` и сворачивание не действуют: раскрывать нечего, дерево\n показано целиком.\n\nЭто осознанное поведение: один и тот же конфиг `subRows` или `rowsGrouping`\nможно переключать между `view: 'tree'` и `view: 'merged'` — лишние настройки\nдругого вида не мешают. Пометки «работает только в виде дерева» есть и в\nподсказках типов.\n\n> Подробнее о типах — [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs)",
|
|
52136
|
-
"apiDocs": "# CellsMerging API\n\n## tableConfig.mergeCells\n\nТочка входа для объединения ячеек тела. Все поля опциональны:\n\n```ts\nmergeCells?: {\n /** Колонки, объединяемые по подряд идущим одинаковым значениям. */\n mergeByCellValues?: Array<string | { colKey: string; value: (row) => unknown }>;\n /** Управляемый список объединений по ключам строк и колонок. */\n mergedCellsRegions?: MergedCellsRegion[];\n /** Нужен для mergedCellsRegions: сопоставляет rowKeys со строками. */\n rowKeyGetter?: (row) => string | number;\n /** Общий (табличный) дефолт выравнивания контента в блоках. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsRegion\n\nОдин управляемый регион: ключи строк, ключи колонок и точечное выравнивание.\n\n```typescript\ntype MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsAlign\n\nВыравнивание контента в блоке. Задаётся на трёх уровнях: `mergedCellsAlign` региона,\n`columnConfig[].mergedCellsAlign` (колонка), `mergeCells.mergedCellsAlign` или\n`rowsGrouping.mergedCellsAlign` (дефолт). Точечное важнее общего.\n\nКолоночный `mergedCellsAlign` — это `MergedCellsAlign` (одно на все блоки колонки) или\nфункция `(row) => MergedCellsAlign | undefined` по данным верхней строки блока. Функция\nдаёт разное выравнивание разным блокам, включая merged-виды группировки/subRows, где\nграницы блоков решает таблица.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', mergedCellsAlign: (row) =>\n row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n```typescript\ntype MergedCellsAlign = {\n /** По горизонтали. @default из `
|
|
52748
|
+
"docs": "# CellsMerging (TableCanvas)\n\nОбъединение ячеек тела таблицы: по строкам (rowSpan), по колонкам (colSpan) и\nпрямоугольными блоками. Несколько одинаковых ячеек рисуются одной большой, а всё\nвзаимодействие — клики, выделение, навигация, копирование, вставка, протяжка,\nредактирование — обращается с блоком как с одной ячейкой.\n\nЭта страница — обзор: как выбрать способ и с чего начать, плюс живые примеры.\nПодробности (совмещение способов, работа с деревом, выравнивание, сводные\nограничения) — в\n[Справочнике](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs),\nтипы — в\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Как это устроено\n\nГлавная идея простая: объединение — это способ показа, а не способ хранения.\n\n- В данных значение повторяется в каждой строке блока. Если «Отдел А» тянется на\n три строки, то во всех трёх строках в поле отдела записано «Отдел А».\n- Таблица замечает повторы (или получает границы блока явно) и вместо трёх\n одинаковых ячеек рисует одну высокую. Содержимое берётся из верхней-левой\n ячейки блока.\n- Данные при этом не меняются. Уберите объединение — увидите те же строки с теми\n же значениями.\n\nОтсюда следует и поведение, знакомое по Excel: клик в любую точку блока выделяет\nблок целиком, правка блока меняет значение во всех его строках, копирование\nотдаёт значение один раз.\n\n## Три способа включить объединение\n\nМеханика под всеми способами одна. Отличие — кто вычисляет границы блоков:\nпотребитель или таблица. Способы можно совмещать в одной таблице — правила в\nСправочнике, глава «Если включено несколько способов сразу».\n\n### 1. mergeCells.mergedCellsRegions — блоки, заданные снаружи\n\n«Слей вот эти конкретные ячейки». Список блоков по стабильным ключам строк и\nколонок; списком владеет потребитель, как выделением. Таблица переводит ключи в\nтекущие видимые позиции. Если сортировка, перестановка или скрытие колонки\nразорвали блок — он не рисуется (как ограничение сортировки в Excel).\n\n```tsx\ntableConfig={{\n mergeCells: {\n mergedCellsRegions: [\n { rowKeys: ['r1', 'r2'], colKeys: ['dept'] },\n { rowKeys: ['r4', 'r5'], colKeys: ['plan', 'fact'] }, // прямоугольник 2×2\n ],\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nПримеры — стори с префиксом `mergedCellsRegions:` ниже.\n\n### 2. mergeCells.mergeByCellValues — по одинаковым значениям\n\n«В этих колонках сливай подряд идущие одинаковые значения». Границы блоков\nтаблица вычисляет сама из данных; после сортировки или фильтра блоки\nпересобираются.\n\n```tsx\ntableConfig={{\n mergeCells: {\n mergeByCellValues: [\n 'dept', // по значению колонки\n { colKey: 'role', value: (row) => row.roleGroup }, // по своей функции\n ],\n },\n}}\n```\n\nОдинаковые названия в разных ветках иерархии могут ложно слиться — лечится\nсоставным ключом, разбор в Справочнике, глава «Объединение по значению: где\nпроходит граница». Примеры — стори с префиксом `mergeByCellValues:` ниже.\n\n### 3. Merged-виды группировки и subRows — полный автомат\n\nПотребитель включает вид — всю работу с блоками делает таблица: строки\nупорядочиваются по группам, колонки уровней сливаются по границам групп, чекбокс\nи нумерация работают по верхней группе.\n\nЧерез группировку (структуру задают значения группирующих колонок):\n\n```tsx\ntableConfig={{\n rowsGrouping: {\n view: 'merged',\n groupByState: [groupBy, setGroupBy], // например ['dept', 'role']\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nЧерез subRows (структуру задаёт готовое дерево потребителя):\n\n```tsx\ntableConfig={{\n subRows: {\n view: 'merged',\n mergedColumns: ['dept', 'role'], // колонки уровней дерева\n getSubRows: (row) => row.children,\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\nПримеры — «subRows: дерево с пагинацией» и «rowsGrouping: группировка\nпользователем» в конце страницы.\n\n## Какой способ выбрать\n\nКартинка у способов похожая, поэтому выбирать стоит не по внешнему виду, а по\nтому, кто владеет данными и что нужно пользователю.\n\n### Дерево приходит с сервера, нужна постраничная загрузка — subRows\n\nЕсли данные уже иерархические (дивизион, управление, команда, сотрудники) и\nприходят от сервера частями, берите `subRows` с `view: 'merged'`. Дерево остаётся\nу вас: вы отдаёте таблице страницу дерева, она разворачивает её в строки и сама\nсливает колонки-предки. Именно поэтому здесь работает пагинация по верхним\nблокам — таблице не нужно видеть все данные сразу.\n\nОбратная сторона: раз данными владеете вы, то поиск, сортировка и фильтрация\nдерева — тоже на вашей стороне. Формат дерева, пагинация и возврат правок —\nв Справочнике, глава «Дерево через subRows».\n\n### Плоские строки, пользователь сам выбирает группировку — rowsGrouping\n\nЕсли строки плоские, а пользователь должен на лету решать, по каким колонкам\nгруппировать, — берите `rowsGrouping` с `view: 'merged'`. Состав группировки живёт\nв `groupByState`, а с настройкой `groupButton` в блоке управления появляется\nкнопка: пользователь сам выбирает колонки, таблица пересобирает блоки. Встроенные\nпоиск, сортировка и фильтры работают — таблица применяет их до сборки групп.\n\nОбратная сторона: пагинации в этом виде нет — таблице нужны все строки сразу.\nНе действует и всё, что привязано к строкам-групп и шевронам дерева\n(`groupedColumnProps`, `renderGroupCell`, `expandAllBtn`) — полный список в\nСправочнике, глава «Что не работает и почему».\n\n### Плоские строки, группировка фиксированная, всё считает сервер — mergeByCellValues\n\nЕсли структура известна заранее и не меняется пользователем, а данные (включая\nстраницы, сортировку и фильтры) готовит сервер, — самый прямой путь это\n`mergeByCellValues`. Вы упорядочиваете строки как нужно, таблица сливает соседние\nодинаковые значения. Никакой лишней механики: ни кнопок, ни дерева.\n\n### Отдельные ручные блоки — mergedCellsRegions\n\nШапки секций внутри таблицы, нестандартные прямоугольники, объединение по кнопке\nили из контекстного меню — всё, что не выводится из значений, делается регионами.\nПотребитель добавляет блок в свой список — таблица его рисует.\n\n## Смежные разделы\n\n- [Справочник](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs) —\n совмещение способов, составные ключи, дерево, выравнивание, сводные ограничения.\n- [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs) —\n типы.\n- Объединение ячеек шапки — раздел ColumnsGrouping (`squashEmptyCells`).\n\n## Полные примеры\n\nТри больших примера ниже собраны как заготовки для продуктов: в каждом —\nобъединение ячеек в связке с поиском, сортировкой, фильтрами, пагинацией,\nредактированием и выделением. Различаются они тем, кто владеет данными, поэтому\nи код обвязки разный. Полный код каждого примера открывается кнопкой «Show code»\nи снабжён комментариями по ключевым местам.\n\n### mergeByCellValues: пример с серверными данными\n\nДанные плоские, всё считает «сервер» (в примере его заменяет функция\n`selectPage`), таблица только рисует полученную страницу.\n\nЧто здесь показано:\n\n- поиск, фильтры, сортировка и пагинация в `manual`-режиме — считает потребитель;\n- составные ключи пути (`divPath` / `unitPath` / `teamPath`) против ложного\n слияния одинаковых имён из разных веток;\n- сортировка внутри команды — блоки не рассыпаются;\n- закрепление колонок вместе с групповой шапкой;\n- редактирование с возвратом правок страницы в полный набор.\n\n<Canvas of={CellsMergingExamples.Showcase} />\n\n### subRows: дерево с пагинацией\n\nДанные — дерево, и оно остаётся у потребителя: таблице отдаётся страница целых\nподдеревьев.\n\nЧто здесь показано:\n\n- пагинация по верхним блокам (дивизионам) со своим списком «показывать по»;\n- `manual`-поиск, сортировка и фильтры, посчитанные по дереву\n (функция `selectTreePage`);\n- сортировка показателей внутри команды и перестановка веток по имени;\n- возврат правок листьев обратно в дерево.\n\n<Canvas of={CellsMergingExamples.SubRowsMerged} />\n\n### rowsGrouping: группировка пользователем\n\nДанные плоские и передаются целиком, остальное делает таблица. Самый короткий\nкод из трёх.\n\nЧто здесь показано:\n\n- встроенные поиск, сортировка и фильтры — применяются до сборки групп;\n- выбор состава группировки пользователем (кнопка `groupButton`);\n- полный стейт фильтров: ключ на каждый фильтр из колонок;\n- без пагинации — чтобы собрать группы, таблице нужны все строки сразу.\n\n<Canvas of={CellsMergingExamples.GroupingMerged} />\n\n## Как перенести пример к себе\n\n1. Замените данные и типы строк на свои. Сохраните стабильный `id` строки — на\n нём держатся выделение и возврат правок, между страницами он меняться не\n должен.\n2. Замените `selectPage` / `selectTreePage` реальным запросом к серверу. Контракт\n тот же: параметры выборки на входе, страница и общее количество на выходе.\n3. Проверьте, что в `filtering.state` есть ключ каждого фильтра из колонок (со\n значением «показать всё»), — селект-фильтр без своего ключа молча отсеет все\n строки.\n4. Для `mergeByCellValues` заведите составные ключи пути, если одинаковые\n названия возможны в разных ветках иерархии.\n5. Уберите фичи, которые вам не нужны, — настройки в примерах независимы друг от\n друга: пагинация, закрепление, чекбоксы, редактирование отключаются по\n отдельности.\n\n# CellsMerging: справочник\n\nПодробности объединения ячеек: совмещение способов, составные ключи, работа с\nдеревом, взаимодействие с остальными фичами таблицы, выравнивание и сводный\nсписок ограничений. Обзор способов и живые примеры — на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs), типы —\nна странице\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Если включено несколько способов сразу\n\nСпособы можно совмещать в одной таблице — правила простые и считаются по колонке:\n\n- Если колонка входит хотя бы в один регион из `mergedCellsRegions`, её\n объединения описывают только регионы. `mergeByCellValues` на этой колонке не\n действует.\n- Колонка merged-вида (группировки или subRows) сливается по границам групп.\n Пользовательский `mergeByCellValues` на той же колонке не действует — иначе два\n механизма спорили бы за одни ячейки.\n- В остальных случаях работает `mergeByCellValues`.\n- Разные колонки живут независимо: регион на одной колонке и слияние по значению\n на другой — обычная рабочая комбинация.\n\nПример: таблица с группировкой по «Отделу» (merged-вид) может дополнительно\nсливать колонку «Статус» через `mergeByCellValues`, а строки-заголовки секций\nрисовать регионами на всю ширину — все три способа уживаются, потому что заняты\nразными колонками.\n\n## Объединение по значению: где проходит граница\n\nУ `mergeByCellValues` есть классическая ловушка. Допустим, регионы «Север» и «Юг»,\nи в каждом есть «Команда 1» и «Команда 2»:\n\n```\nСевер | Команда 1 | Иванов\nСевер | Команда 2 | Петров\nЮг | Команда 2 | Сидоров\nЮг | Команда 1 | Смирнов\n```\n\nЕсли сливать колонку команды по её значению, «Команда 2» из Севера и «Команда 2»\nиз Юга стоят рядом — и сольются в один блок через границу региона. Визуально это\nвыглядит как ошибка: одна команда, а на деле две разные.\n\nРешение — сливать не по тексту в ячейке, а по составному ключу, в котором зашит\nпуть от корня:\n\n```tsx\nmergeCells: {\n mergeByCellValues: [\n 'region',\n // Сравнивается результат функции, а не текст в ячейке.\n { colKey: 'team', value: (row) => `${row.region} / ${row.team}` },\n ],\n}\n```\n\nТеперь у «Команды 2» из Севера ключ «Север / Команда 2», а у южной —\n«Юг / Команда 2». Ключи разные, слияние останавливается на границе региона само,\nбез какой-либо отдельной логики. В ячейке при этом показывается обычное значение\nколонки — функция влияет только на сравнение.\n\nВ полном примере (стори «mergeByCellValues: пример с серверными данными») такие\nключи собраны заранее в полях строки: `divPath`, `unitPath`, `teamPath` — по\nодному на каждый уровень иерархии.\n\nMerged-виды группировки и subRows строят такие ключи сами — там об этой ловушке\nдумать не нужно.\n\n## Дерево через subRows: как передавать данные\n\nРазберём подробнее самый ёмкий сценарий — `subRows` с `view: 'merged'`.\n\n### Какое дерево ждёт таблица\n\nВ `rows` передаются корневые узлы, детей таблица достаёт через `getSubRows`.\nРоли узлов распределены так:\n\n- **Внутренние узлы** (дивизион, управление, команда) — ярлыки уровней. Каждый\n несёт поле с именем своей колонки из `mergedColumns`: узел дивизиона — поле\n `division`, узел управления — поле `unit`, и так далее.\n- **Листья** — строки данных. Именно они становятся строками таблицы со своими\n показателями; внутренние узлы отдельными строками не показываются.\n\n```tsx\nconst tree = [\n {\n id: 'd1',\n division: 'Розничный бизнес', // узел уровня 0\n subRows: [\n {\n id: 'u1',\n unit: 'Управление продаж', // узел уровня 1\n subRows: [\n {\n id: 't1',\n team: 'Команда Север', // узел уровня 2\n subRows: [\n { id: 'e1', employee: 'Иванов', plan: 100, fact: 90 }, // лист\n { id: 'e2', employee: 'Петров', plan: 80, fact: 85 },\n ],\n },\n ],\n },\n ],\n },\n];\n```\n\n```tsx\ntableConfig={{\n subRows: {\n view: 'merged',\n mergedColumns: ['division', 'unit', 'team'], // порядок = уровни дерева\n getSubRows: (row) => row.subRows,\n rowKeyGetter: (row) => row.id,\n },\n}}\n```\n\n`mergedColumns` — это соответствие уровней дерева и колонок: первый элемент\nпоказывает узлы верхнего уровня, второй — следующего, и так далее. Колонка\n`division` возьмёт значение из узла дивизиона и сольётся на все его листья,\n`unit` — на листья своего управления, вложенно.\n\nСворачивания в этом виде нет: таблица показывает всё переданное дерево целиком.\nХотите меньше строк на экране — передайте меньший кусок дерева (следующий\nраздел).\n\n### Пагинация по верхним блокам\n\nДерево у вас, поэтому страницы нарезаете вы — по верхним узлам. Таблице отдаётся\nсрез дерева, а в `pagination.count` — общее число верхних узлов:\n\n```tsx\nconst [page, setPage] = useState(1);\nconst [perPage, setPerPage] = useState(2); // дивизионов на страницу\nconst pageTree = tree.slice((page - 1) * perPage, page * perPage);\n\ntableConfig={{\n pagination: {\n count: tree.length, // всего верхних узлов, не листьев\n perPage,\n perPageList: [1, 2, 3], // варианты «показывать по» — в блоках\n value: page,\n onChange: (nextPage, nextPerPage) => {\n if (typeof nextPerPage === 'number' && nextPerPage !== perPage) {\n setPerPage(nextPerPage);\n setPage(1);\n } else if (typeof nextPage === 'number') {\n setPage(nextPage);\n }\n },\n },\n subRows: { /* как выше */ },\n}}\n// ...\nrows={pageTree}\n```\n\nСтраница «2 дивизиона» может содержать разное число строк-листьев — это нормально:\nединица пагинации здесь блок, а не строка. По той же причине настройте селектор\n«Показывать по»: его стандартные варианты (20/50/100) рассчитаны на строки и для\nблоков не имеют смысла — задайте свой список `perPageList` в блоках, как выше,\nлибо спрячьте селектор (`hasPerPage: false`). Если дерево приходит с сервера\nчастями, вместо `slice` будет запрос следующей страницы — контракт тот же.\n\n### Редактирование: правки возвращаются листьями\n\nРедактируются листья. В `editing.onRowsChange` приходят изменённые строки-листья —\nзаписать их обратно в своё дерево должен потребитель, например по `id`:\n\n```tsx\nediting: {\n rowKeyGetter: (r) => r.id,\n onRowsChange: (updatedLeaves) => {\n const byId = new Map(updatedLeaves.map((r) => [r.id, r]));\n // Обойдите дерево и замените листья с совпавшими id.\n setTree((prev) => writeLeavesBack(prev, byId));\n },\n},\n```\n\nЭто следствие владения данными: таблица не знает, как устроено ваше дерево,\nпоэтому отдаёт плоский результат, а раскладываете его вы.\n\n### Что остаётся на вашей стороне\n\n- **Поиск, сортировка, фильтрация** — встроенные механизмы к структурному дереву\n пока не применяются. Отфильтровали или отсортировали своё дерево — передали\n результат в `rows`, таблица показала.\n- **Выделение** при этом работает из коробки: один чекбокс на верхний блок, клик\n выделяет все его листья (подробнее — в разделе про выделение ниже).\n\nЖивой пример всего вместе — стори «subRows: дерево с пагинацией» на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs).\n\n## Объединение и остальные возможности таблицы\n\nБлоки — не отдельный мир: выделение, сортировка, буфер обмена и редактирование\nпродолжают работать. Здесь собрано, как именно.\n\n### Выделение, нумерация и навигация\n\nВыделение настраивается как обычно — `selecting` со стейтом и `rowKeyGetter`.\nА вот ведёт оно себя по-разному в зависимости от способа объединения:\n\n- **Плоский вид с mergeByCellValues** — чекбокс у каждой строки, номер у каждой\n строки. Объединение колонок на выделение не влияет: в стори\n «mergeByCellValues: пример с серверными данными» можно выделить одного\n сотрудника внутри слитого блока.\n- **Merged-виды группировки и subRows** — один чекбокс и один номер на группу\n верхнего уровня. Клик по чекбоксу выделяет все строки группы разом, повторный —\n снимает. «Выделить всё» в шапке тоже работает. Счётчик выбранного внизу\n считает строки, а не группы: выделили дивизион из 12 сотрудников — внизу\n «выбрано 12».\n\nСпециально настраивать групповое поведение не нужно: таблица включает его сама,\nкогда активен merged-вид.\n\nНавигация тоже понимает блоки: клик в любую точку блока выделяет его целиком,\nрамка фокуса рисуется вокруг всего блока, один шаг стрелкой перепрыгивает блок.\nПопасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n\n### Сортировка, фильтрация, поиск и пагинация\n\nВозможности зависят от того, кто владеет данными.\n\n**mergeByCellValues (плоский вид).** Встроенные сортировка, фильтр и поиск\nработают как обычно, а блоки пересобираются после каждого изменения порядка —\nобъединение всегда отражает текущий видимый список строк. Если данные приходят с\nсервера постранично, следите, чтобы сортировка на сервере не разрывала группы:\nполовина группы на одной странице и половина на другой будут выглядеть как два\nотдельных блока.\n\n**rowsGrouping (view: 'merged').** Встроенные поиск, сортировка и фильтры\nработают: таблица применяет их к строкам до сборки групп, поэтому группы всегда\nсобираются из уже отфильтрованного списка. Пагинации нет: группировке нужны все\nстроки сразу. Сортировку по группирующим колонкам можно снять настройкой\n`disableGroupColumnsSort` — как в дереве, где сгруппированные колонки не\nсортируются.\n\nЧастая ошибка при встроенных фильтрах (не только в этом виде): в стейте\n`filtering.state` должен быть ключ каждого фильтра, объявленного в колонках.\nSelect-фильтр без своего ключа получит пустое значение вместо «показать всё» и\nможет отсеять все строки — таблица окажется пустой без единой ошибки.\n\n**subRows (view: 'merged').** Дерево у потребителя, поэтому пагинация по верхним\nблокам работает: отдаёте страницу дерева — таблица её показывает. Встроенные\nпоиск, сортировка и фильтрация к структурному дереву пока не применяются — эти\nоперации делаются на стороне потребителя над его данными.\n\n### Копирование, вставка и протяжка\n\n- Копирование отдаёт значение в позиции верхней-левой ячейки блока, остальные\n ячейки блока в буфере пустые — как в Excel.\n- Вставка пишет во весь блок: значение попадает во все его строки.\n- Протяжка (fill) растягивается только до целых блоков — залить пол-блока нельзя;\n пунктирная рамка протяжки сама прилипает к границам блоков.\n\n### Редактирование\n\n- Правка ячейки блока записывает значение во все его строки — данные под блоком\n всегда совпадают с тем, что на экране.\n- При объединении по значению правка пересобирает блоки: изменили «Отдел» у\n блока — он разъедется или сольётся с соседним, потому что объединение выводится\n из данных.\n- У редактируемых Select-ячеек редактор открывается по выравниванию блока: текст\n прижат к низу — редактор откроется у нижнего края, а выпадающий список\n раскроется вверх.\n\n## Выравнивание контента в блоке\n\nПо умолчанию контент блока выравнивается по горизонтали как обычная ячейка\nэтой колонки — из `contentFormat.alignContent` (у числового формата это правый\nкрай), иначе слева. По вертикали — по центру: у обычной ячейки вертикального\nвыравнивания нет, это чисто блочная настройка. Настраивается лестницей «точечное важнее\nобщего»:\n\n- `mergedCellsAlign` конкретного региона (только для `mergedCellsRegions`);\n- `mergedCellsAlign` на колонке — все блоки этой колонки, работает для всех\n способов включения;\n- дефолт фичи: `mergeCells.mergedCellsAlign` или `rowsGrouping.mergedCellsAlign`.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', name: 'Отдел', mergedCellsAlign: { horizontal: 'center', vertical: 'top' } },\n]}\n```\n\nКолоночный `mergedCellsAlign` может быть и функцией `(row) => MergedCellsAlign`\nпо данным строки блока — так разные блоки одной колонки получают разное\nвыравнивание. Это единственный способ управлять выравниванием поблочно в\nmerged-видах группировки и subRows, где границы блоков решает таблица, а не\nпотребитель.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', mergedCellsAlign: (row) =>\n row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n### Свой рендер в блоке\n\nВыравнивание действует на текстовый контент. Кастомный `renderCell` получает весь\nпрямоугольник блока и выравнивает содержимое сам — через свойства своих\nконтейнеров.\n\nУ колонок со своим рендером есть неочевидность: предпросмотр значения (по\nдвойному клику на ячейке без редактирования) у них по умолчанию выключен.\nСо стороны это выглядит как «у блоков не открывается предпросмотр», хотя дело в\nколонке, а не в объединении. Включается настройкой колонки:\n\n```tsx\n{ key: 'dept', renderCell: ..., renderCellPreview: 'cellEditorAsPreview' }\n```\n\n## Что не работает и почему\n\nСводный список ограничений. Если «что-то не рисуется» — сначала сюда.\n\n### Во всех способах\n\n- Все ячейки блока обязаны нести одинаковые данные — это контракт\n `mergeByCellValues` (значения реально повторяются в строках) и регионов.\n Причина проста: блок показывает верхнюю-левую **видимую** ячейку, а какая\n ячейка окажется верхней-левой — зависит от закрепления и порядка колонок.\n Если данные одинаковые, блок выглядит одинаково при любой перестановке.\n- Попасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n Это поведение, а не ошибка.\n- Выравнивание пока не поддерживает письмо справа налево (RTL).\n- Горизонтальная протяжка через colSpan-блок не растягивается до границ блока\n (в работе).\n- У колонок со своим `renderCell` по умолчанию выключен предпросмотр значения —\n включается `renderCellPreview: 'cellEditorAsPreview'` (см. «Свой рендер в\n блоке» выше).\n\n### mergedCellsRegions\n\n- Разорванный регион исчезает молча: если после сортировки, перестановки или\n скрытия колонок ключи региона перестали идти подряд, блок просто не рисуется.\n Ошибок и предупреждений нет — следите за порядком сами.\n\n### rowsGrouping (view: 'merged')\n\n- Пагинации нет: чтобы собрать группы, таблице нужны все строки сразу.\n- Отдельная колонка «Группировка» не создаётся, поэтому не действует всё, что к\n ней привязано: `groupedColumnProps`, свой контент ячейки группы\n (`renderGroupCell` у колонки) и кнопка «развернуть всё» (`expandAllBtn`) —\n строк-групп и шевронов в этом виде нет.\n\n### subRows (view: 'merged')\n\n- Встроенные поиск, сортировка и фильтрация к структурному дереву не\n применяются — эти операции делает потребитель над своими данными.\n- `column.subRow` целиком не действует: шеврон (`isColumnWithArrow`), свой\n контент и ключи вложенных уровней (`renderSubRowCell`, `keyOfColumnInSubRow`,\n `parentKeyAsDefault`, `contentFormat`), свой редактор уровня. Листья рисуются\n как обычные строки — работают их обычные `renderCell`, `contentFormat` и\n `editingCell`.\n- `expandedIdsState` и сворачивание не действуют: раскрывать нечего, дерево\n показано целиком.\n\nЭто осознанное поведение: один и тот же конфиг `subRows` или `rowsGrouping`\nможно переключать между `view: 'tree'` и `view: 'merged'` — лишние настройки\nдругого вида не мешают. Пометки «работает только в виде дерева» есть и в\nподсказках типов.\n\n> Подробнее о типах — [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs)",
|
|
52749
|
+
"apiDocs": "# CellsMerging API\n\n## tableConfig.mergeCells\n\nТочка входа для объединения ячеек тела. Все поля опциональны:\n\n```ts\nmergeCells?: {\n /** Колонки, объединяемые по подряд идущим одинаковым значениям. */\n mergeByCellValues?: Array<string | { colKey: string; value: (row) => unknown }>;\n /** Управляемый список объединений по ключам строк и колонок. */\n mergedCellsRegions?: MergedCellsRegion[];\n /** Нужен для mergedCellsRegions: сопоставляет rowKeys со строками. */\n rowKeyGetter?: (row) => string | number;\n /** Общий (табличный) дефолт выравнивания контента в блоках. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsRegion\n\nОдин управляемый регион: ключи строк, ключи колонок и точечное выравнивание.\n\n```typescript\ntype MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsAlign\n\nВыравнивание контента в блоке. Задаётся на трёх уровнях: `mergedCellsAlign` региона,\n`columnConfig[].mergedCellsAlign` (колонка), `mergeCells.mergedCellsAlign` или\n`rowsGrouping.mergedCellsAlign` (дефолт). Точечное важнее общего.\n\nКолоночный `mergedCellsAlign` — это `MergedCellsAlign` (одно на все блоки колонки) или\nфункция `(row) => MergedCellsAlign | undefined` по данным верхней строки блока. Функция\nдаёт разное выравнивание разным блокам, включая merged-виды группировки/subRows, где\nграницы блоков решает таблица.\n\n```tsx\ncolumnConfig={[\n { key: 'dept', mergedCellsAlign: (row) =>\n row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n```typescript\ntype MergedCellsAlign = {\n /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n horizontal?: 'left' | 'center' | 'right';\n /** По вертикали. @default 'center' */\n vertical?: 'top' | 'center' | 'bottom';\n};\n```\n\n## rowsGrouping (merged-вид)\n\nПоля группировки, относящиеся к merged-виду: `view: 'merged'`,\n`mergedCellsAlign`, `disableGroupColumnsSort`.\n\n```typescript\ntype RowsGrouping<\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n /**\n * массив группированных колонок и его setter\n */\n groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n /**\n * Как показывать группировку.\n * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n * группу верхнего уровня.\n * @default 'tree'\n */\n view?: 'tree' | 'merged';\n /**\n * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n * группирующих колонок. Колоночный mergedCellsAlign важнее.\n */\n mergedCellsAlign?: MergedCellsAlign;\n /**\n * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n * (как в дереве). По остальным колонкам сортировка остаётся.\n * @default false\n */\n disableGroupColumnsSort?: boolean;\n /**\n * Функция определения уникального id строки\n */\n rowKeyGetter: (row: RowType) => string | number;\n /**\n * Показывать ли кнопку «Группировать» в controlBlock.\n * При `false` кнопка скрыта и не участвует в компрессии,\n * но группировка строк продолжает работать от внешнего `groupByState`.\n * @default true\n */\n showInControl?: boolean;\n /**\n * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n * колонки остаются на своих местах.\n * @default 'Группировка'\n */\n groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n renderCell?: (\n props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n parentGroupKey: string | undefined;\n groupByArr: string[];\n },\n ) => CanvasContent;\n rowsGrouping?: Pick<\n ColumnRowsGrouping<RowType, ColumnConfig>,\n 'renderGroupCell'\n >;\n };\n /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n expandAllBtn?: {\n /**\n * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n * @returns boolean\n */\n expandedAll: (p: {\n /**\n * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n */\n allRowsIds: Set<string | number> | null;\n /**\n * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n */\n shownRows: readonly RowType[];\n expandedRowsIds: Set<string | number>;\n }) => boolean;\n };\n /**\n * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n */\n groupButton?: {\n getGroupedCount?: (props: {\n /**\n * высчитанное автоматически количество активных группировок.\n */\n currCount: number;\n /**\n * активные группировки.\n */\n groupedCols: string[];\n columns: {\n /**\n * `visible` - видимые в выпадающем списке колонки-группировки.\n */\n visible: string[];\n /**\n * `hidden` - невидимые или не участвующие в группировке колонки\n *\n * (columnConfig.rowsGrouping=undefined ||\n * columnConfig.rowsGrouping.groupByColumn=false).\n */\n hidden: string[];\n };\n }) => number;\n /**\n * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n *\n * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n */\n defaultCustomItems?: DropdownItemOption[];\n /**\n * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n *\n * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n */\n onItemSelect?: (props: {\n item: DropdownItemOption;\n setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n columns: {\n visible: string[];\n hidden: string[];\n };\n }) => void;\n };\n /**\n * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n *\n * @param groupRow данные сгруппированной строки\n * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n */\n groupRowReplaceTo?: (\n groupRow: GroupRow<RowType>,\n ) => GroupRow<RowType> | RowType;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<\n RowType extends ObjectForExtending,\n ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n column: ColumnConfig;\n tabIndex: number;\n theme?: Theme;\n // TODO isExpanded: boolean;\n // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n\nexport type ColumnRowsGrouping<\n RowType extends ObjectForExtending,\n ColumnConfig extends LocalColumnInstance,\n> = {\n /**\n * @default true - при наличии ColumnConfig.rowsGrouping\n */\n groupByColumn?: boolean;\n /**\n * @default ColumnConfig.key\n */\n columnGroupLabel?: string;\n /**\n * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n * поэтому этот рендер не вызывается.\n */\n renderGroupCell?: (\n props: RenderGroupCellProps<RowType, ColumnConfig>,\n ) => CanvasContent;\n};\n```\n\n## subRows (merged-вид)\n\nПоля subRows, относящиеся к merged-виду: `view: 'merged'` и `mergedColumns`\n(упорядоченный список колонок-предков, индекс = глубина уровня дерева).\n\n```typescript\ntype SubRows<RowType, RowIdType> = {\n /**\n * Возвращает дочерние строки узла (или undefined, если их нет).\n *\n * Функция должна быть стабильной — не менять поведение между рендерами.\n * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n */\n getSubRows: (row: RowType) => RowType[] | undefined;\n /**\n * Возвращает уникальный ключ строки.\n *\n * Функция должна быть стабильной — не менять поведение между рендерами.\n * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Внешний стейт развёрнутых строк.\n * Если не задан — используется внутренний useState.\n * При view: 'merged' не используется: сворачивания в этом виде нет.\n */\n expandedIdsState?: [\n Set<string | number>,\n (\n newV:\n | Set<string | number>\n | ((prev: Set<string | number>) => Set<string | number>),\n ) => void,\n ];\n /**\n * Как показывать дерево.\n * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n * данные (пагинация, сортировка, поиск) остаются на его стороне.\n */\n view?: 'tree' | 'merged';\n /**\n * Только для view: 'merged'. Колонки-предки по порядку уровней:\n * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n */\n mergedColumns?: string[];\n};\n```",
|
|
52137
52750
|
"api": [
|
|
52138
52751
|
{
|
|
52139
52752
|
"typeName": "MergedCellsRegion",
|
|
@@ -52141,7 +52754,7 @@
|
|
|
52141
52754
|
},
|
|
52142
52755
|
{
|
|
52143
52756
|
"typeName": "MergedCellsAlign",
|
|
52144
|
-
"source": "type MergedCellsAlign = {\n /** По горизонтали. @default из `
|
|
52757
|
+
"source": "type MergedCellsAlign = {\n /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n horizontal?: 'left' | 'center' | 'right';\n /** По вертикали. @default 'center' */\n vertical?: 'top' | 'center' | 'bottom';\n};"
|
|
52145
52758
|
},
|
|
52146
52759
|
{
|
|
52147
52760
|
"typeName": "RowsGrouping",
|
|
@@ -52301,12 +52914,16 @@
|
|
|
52301
52914
|
"feature": "ColumnsControl",
|
|
52302
52915
|
"legacy": false,
|
|
52303
52916
|
"summary": "*tableConfig.columnsControl**",
|
|
52304
|
-
"docs": "# ColumnsControl (TableCanvas)\n\n**tableConfig.columnsControl**\n\nНастройка колонок таблицы: скрытие, закрепление, изменение порядка (через Aside-панель и drag в header).\n\n## Ключевые особенности\n\n- Активация через `enable: true` — включает все подфичи по умолчанию\n- Скрытие колонок через свитчи в Aside (`hiding`)\n- Закрепление колонок (`pinning`)\n- Перетаскивание колонок в Aside (`reorderingAside`) и через header (`reorderingHeader`)\n- Дефолтные состояния при первом рендере (`pinnedDefault`, `hiddenDefault`, `orderDefault`)\n- Переопределение названий колонок в Aside (`columnsLabel`)\n- Колбэк при применении настроек (`onConfirm`)\n\n## Подфичи\n\nКаждая подфича по умолчанию наследует значение `enable`. Можно отключить отдельно:\n\n- **`hiding`** — скрытие/показ колонок через свитчи. `disableHiding` исключает конкретные колонки\n- **`pinning`** — закрепление колонок слева. `disablePinning` исключает конкретные колонки\n- **`reorderingAside`** — drag-and-drop порядка колонок в Aside-панели\n- **`reorderingHeader`** — drag-and-drop заголовков колонок прямо в таблице. `onReorderingHeader` — callback с новым порядком\n\n## Дефолтные состояния\n\n- **`pinnedDefault`** — массив ключей колонок, закреплённых при первом рендере\n- **`hiddenDefault`** — массив ключей скрытых колонок при первом рендере\n- **`orderDefault`** — массив ключей, определяющий начальный порядок колонок\n\n## onConfirm\n\nCallback вызывается при нажатии «Применить» в Aside. Получает текущее состояние (`pinned`, `order`, `hidden`, `changed`) и сеттеры для программного управления состоянием.\n\n## Меню закрепления в контрл-блоке (pinningMenu)\n\nКогда включено `pinning`, в правой зоне иконок контрл-блока автоматически появляется нативная кнопка-иконка (пин + шеврон) — быстрый доступ к закреплению выбранных колонок, дополняющий Aside-панель. Задаётся через `controlBlock.pinningMenu`.\n\n- Фича **нативная**: появляется сама при активном `pinning`, отдельно включать не нужно. Отключается `controlBlock.pinningMenu.enable: false`.\n- **Размеры** завязаны на размер контрл-блока (`controlBlock.size`) — в компактном (`xs`) ужимается вместе с остальными иконками.\n- Участвует в **компрессии**: при нехватке места уезжает в overflow-меню `…` вложенным подменю.\n\nПункты меню:\n\n- **Стандартные (из коробки):** «Открепить всё» и «Закрепить столбцы».\n- **Свои пункты** — через `pinningMenu.items` (напр. «Закрепить строки», «Закрепить шапку»). Порядок задаётся `order` (у нативных: `Открепить всё` = 100, `Закрепить столбцы` = 200), разделитель после пункта — `dividerAfter`. Совпадение `value` с нативным = переопределение.\n- Состояние и иконку продуктовых пунктов **контролирует продукт** (иконка — `ReactNode` или функция от `rowSize`, может отражать состояние).\n\nЛевая иконка (кнопка-действие):\n\n- Синеет, когда среди **видимых** колонок есть хотя бы одна закреплённая (скрыли видимость закреплённой — снова обычный цвет).\n- Tooltip и действие зависят от выделения: нет выделения — подсказка выбрать колонки; выбраны незакреплённые — «Закрепить»; выбраны только закреплённые — «Открепить».\n- После закрепления выделение **переезжает** за колонками (закреплённые уезжают влево), соседние сливаются без разделителей.\n- Клик по действию закрепления **без выделенных колонок** шлёт событие в `tableConfig.notifications` (`type: 'pin'`, `code: 'no-selection'`) — продукт показывает свою подсказку. Подробнее — в разделе [Notifications](?path=/docs/локальные-компоненты-tablecanvas-notifications--docs).\n\nПример добавления своих пунктов — в стори «ColumnsControl: доп. пункты меню закрепления».\n\n> Подробнее о типах и пропсах — [ColumnsControl API](?path=/docs/локальные-компоненты-tablecanvas-columnscontrol-api--docs)",
|
|
52305
|
-
"apiDocs": "# ColumnsControl API\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};\n```\n\n## PinningMenuConfig\n\nМеню закрепления в контрл-блоке (`controlBlock.pinningMenu`). Появляется, когда включено `columnsControl.pinning`.\n\n```typescript\ntype PinningMenuConfig = {\n /**\n * Явное вкл/выкл фичи.\n * @default columnsControl.pinning\n */\n enable?: boolean;\n /**\n * Продуктовые пункты меню — мёржатся с нативными (override по value,\n * сортировка по order).\n */\n items?: PinningMenuItem[];\n /**\n * DomMetadata левой кнопки-иконки закрепления. Её `dataAttributes`\n * навешиваются на кнопку-иконку (data-атрибуты для e2e-тестов, аналитики и\n * онбординга — поиск элемента в DOM). Пример:\n * `{ dataAttributes: { 'data-testid': 'pinning-icon' } }`.\n */\n iconDomMetadata?: DomMetadata;\n};\n```\n\n## PinningMenuItem\n\nПункт меню закрепления — нативный или добавленный продуктом.\n\n```typescript\ntype PinningMenuItem = {\n /**\n * Уникальный ключ пункта. Совпадение с value нативного пункта = override\n * (продуктовые поля перекрывают нативные).\n */\n value: string;\n label: string;\n /**\n * Иконка слева в пункте. Узел рендерится как есть, либо функция (ctx),\n * чтобы подстроить размер под rowSize (в т.ч. внутри overflow-дропдауна\n * при компрессии). Стейт/иконку продуктовых пунктов контролирует продукт.\n */\n icon?: FeatureIconRender;\n /**\n * Действие пункта. У нативных пунктов задаётся таблицей; продукт может\n * переопределить.\n */\n onClick?: () => void;\n /**\n * Порядок в списке (по возрастанию). Нативные: reset=100, pin-columns=200.\n * Пункты без order идут в конец, сохраняя исходный порядок.\n */\n order?: number;\n /**\n * Нарисовать разделитель после пункта.\n * @default false\n */\n dividerAfter?: boolean;\n disabled?: boolean;\n};\n```",
|
|
52917
|
+
"docs": "# ColumnsControl (TableCanvas)\n\n**tableConfig.columnsControl**\n\nНастройка колонок таблицы: скрытие, закрепление, изменение порядка (через Aside-панель и drag в header).\n\n## Ключевые особенности\n\n- Активация через `enable: true` — включает все подфичи по умолчанию\n- Скрытие колонок через свитчи в Aside (`hiding`)\n- Закрепление колонок (`pinning`)\n- Перетаскивание колонок в Aside (`reorderingAside`) и через header (`reorderingHeader`)\n- Дефолтные состояния при первом рендере (`pinnedDefault`, `hiddenDefault`, `orderDefault`)\n- Переопределение названий колонок в Aside (`columnsLabel`)\n- Колбэк при применении настроек (`onConfirm`)\n- Синий индикатор скрытых столбцов в шапке (`hiddenColumnsIndicator`)\n\n## Подфичи\n\nКаждая подфича по умолчанию наследует значение `enable`. Можно отключить отдельно:\n\n- **`hiding`** — скрытие/показ колонок через свитчи. `disableHiding` исключает конкретные колонки\n- **`pinning`** — закрепление колонок слева. `disablePinning` исключает конкретные колонки\n- **`reorderingAside`** — drag-and-drop порядка колонок в Aside-панели\n- **`reorderingHeader`** — drag-and-drop заголовков колонок прямо в таблице. `onReorderingHeader` — callback с новым порядком\n\n## Дефолтные состояния\n\n- **`pinnedDefault`** — массив ключей колонок, закреплённых при первом рендере\n- **`hiddenDefault`** — массив ключей скрытых колонок при первом рендере\n- **`orderDefault`** — массив ключей, определяющий начальный порядок колонок\n\n## onConfirm\n\nCallback вызывается при нажатии «Применить» в Aside. Получает текущее состояние (`pinned`, `order`, `hidden`, `changed`) и сеттеры для программного управления состоянием.\n\n## Индикатор скрытых столбцов (hiddenColumnsIndicator)\n\nКогда между двумя видимыми колонками спрятаны столбцы, на границе в шапке вместо обычного бордера рисуется толстая синяя полосатая линия. Так пользователь видит, что тут есть скрытый промежуток, и может быстро его раскрыть.\n\n- Фича **нативная**: включается сама вместе с `hiding`. Отдельно управляется флагом `hiddenColumnsIndicator` (по умолчанию `true` при активном `hiding`). Отключается `hiddenColumnsIndicator: false`.\n- **Одна полоса на весь промежуток**: сколько бы столбцов ни было скрыто подряд, линия одна. Двойной клик раскрывает сразу весь промежуток.\n- **Наведение** на линию показывает тултип «Дважды нажмите, чтобы развернуть».\n- **Ресайз** соседней колонки за эту же границу работает как обычно (тянем перетаскиванием), меняется только двойной клик: он раскрывает промежуток вместо автосайза. Если полоса высокая, тянуть за ресайз можно по всей её высоте, а не только в листовом ряду.\n- **Края таблицы**: если скрыт первый или последний столбец, линия прижимается к левому или правому краю.\n- **Сгруппированная шапка**: фича относится только к колонкам, сами группы не скрываются, а высота полосы подстраивается под то, что скрыто. Если спрятаны только листья внутри групп, полоса низкая (в листовом ряду). Если среди скрытых есть большая колонка верхнего уровня, полоса тянется вверх на всю высоту шапки. Высоту дополнительно ограничивает общая группа видимых соседей: пока они под одной группой, полоса не поднимается выше её низа.\n\n### onHiddenColumnsIndicatorExpand\n\nКолбэк-уведомление о раскрытии промежутка двойным кликом. Само раскрытие (снятие скрытия) делает обёртка; колбэк нужен, чтобы продукт мог подписаться на это событие. В него приходит объект с полями: `keys` (ключи раскрываемых столбцов), `leftKey` и `rightKey` (видимые соседи слева и справа от линии, `undefined` на краю таблицы).\n\nСрабатывает **только** на двойной клик по линии индикатора. Обычное изменение видимости через панель настройки колонок (Aside) или контекстное меню продукта его не вызывает: для этих сценариев есть общий стейт скрытых колонок и `onConfirm`.\n\nПримеры: стори «ColumnsControl: индикатор скрытых столбцов» и рядом (по бокам, выключен, в группе, в скваш-колонках).\n\n## Меню закрепления в контрл-блоке (pinningMenu)\n\nКогда включено `pinning`, в правой зоне иконок контрл-блока автоматически появляется нативная кнопка-иконка (пин + шеврон) — быстрый доступ к закреплению выбранных колонок, дополняющий Aside-панель. Задаётся через `controlBlock.pinningMenu`.\n\n- Фича **нативная**: появляется сама при активном `pinning`, отдельно включать не нужно. Отключается `controlBlock.pinningMenu.enable: false`.\n- **Размеры** завязаны на размер контрл-блока (`controlBlock.size`) — в компактном (`xs`) ужимается вместе с остальными иконками.\n- Участвует в **компрессии**: при нехватке места уезжает в overflow-меню `…` вложенным подменю.\n\nПункты меню:\n\n- **Стандартные (из коробки):** «Открепить всё» и «Закрепить столбцы».\n- **Свои пункты** — через `pinningMenu.items` (напр. «Закрепить строки», «Закрепить шапку»). Порядок задаётся `order` (у нативных: `Открепить всё` = 100, `Закрепить столбцы` = 200), разделитель после пункта — `dividerAfter`. Совпадение `value` с нативным = переопределение.\n- Состояние и иконку продуктовых пунктов **контролирует продукт** (иконка — `ReactNode` или функция от `rowSize`, может отражать состояние).\n\nЛевая иконка (кнопка-действие):\n\n- Синеет, когда среди **видимых** колонок есть хотя бы одна закреплённая (скрыли видимость закреплённой — снова обычный цвет).\n- Tooltip и действие зависят от выделения: нет выделения — подсказка выбрать колонки; выбраны незакреплённые — «Закрепить»; выбраны только закреплённые — «Открепить».\n- После закрепления выделение **переезжает** за колонками (закреплённые уезжают влево), соседние сливаются без разделителей.\n- Клик по действию закрепления **без выделенных колонок** шлёт событие в `tableConfig.notifications` (`type: 'pin'`, `code: 'no-selection'`) — продукт показывает свою подсказку. Подробнее — в разделе [Notifications](?path=/docs/локальные-компоненты-tablecanvas-notifications--docs).\n\nПример добавления своих пунктов — в стори «ColumnsControl: доп. пункты меню закрепления».\n\n> Подробнее о типах и пропсах — [ColumnsControl API](?path=/docs/локальные-компоненты-tablecanvas-columnscontrol-api--docs)",
|
|
52918
|
+
"apiDocs": "# ColumnsControl API\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n /**\n * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n * ресайз на этой границе работает как обычно.\n * @default hiding\n */\n hiddenColumnsIndicator?: boolean;\n /**\n * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n * столбцы раскрылись и между какими видимыми колонками стояла линия.\n */\n onHiddenColumnsIndicatorExpand?: (\n info: HiddenColumnsIndicatorExpandInfo,\n ) => void;\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};\n```\n\n## HiddenColumnsIndicatorExpandInfo\n\nДанные, которые приходят в колбэк `onHiddenColumnsIndicatorExpand` при раскрытии промежутка двойным кликом по индикатору скрытых столбцов.\n\n```typescript\ntype HiddenColumnsIndicatorExpandInfo = {\n /** Ключи скрытых столбцов, которые раскрываются (весь промежуток за линией). */\n keys: string[];\n /** Видимый сосед слева от линии. undefined, если линия у левого края таблицы. */\n leftKey?: string;\n /** Видимый сосед справа от линии. undefined, если линия у правого края таблицы. */\n rightKey?: string;\n};\n```\n\n## PinningMenuConfig\n\nМеню закрепления в контрл-блоке (`controlBlock.pinningMenu`). Появляется, когда включено `columnsControl.pinning`.\n\n```typescript\ntype PinningMenuConfig = {\n /**\n * Явное вкл/выкл фичи.\n * @default columnsControl.pinning\n */\n enable?: boolean;\n /**\n * Продуктовые пункты меню — мёржатся с нативными (override по value,\n * сортировка по order).\n */\n items?: PinningMenuItem[];\n /**\n * DomMetadata левой кнопки-иконки закрепления. Её `dataAttributes`\n * навешиваются на кнопку-иконку (data-атрибуты для e2e-тестов, аналитики и\n * онбординга — поиск элемента в DOM). Пример:\n * `{ dataAttributes: { 'data-testid': 'pinning-icon' } }`.\n */\n iconDomMetadata?: DomMetadata;\n};\n```\n\n## PinningMenuItem\n\nПункт меню закрепления — нативный или добавленный продуктом.\n\n```typescript\ntype PinningMenuItem = {\n /**\n * Уникальный ключ пункта. Совпадение с value нативного пункта = override\n * (продуктовые поля перекрывают нативные).\n */\n value: string;\n label: string;\n /**\n * Иконка слева в пункте. Узел рендерится как есть, либо функция (ctx),\n * чтобы подстроить размер под rowSize (в т.ч. внутри overflow-дропдауна\n * при компрессии). Стейт/иконку продуктовых пунктов контролирует продукт.\n */\n icon?: FeatureIconRender;\n /**\n * Действие пункта. У нативных пунктов задаётся таблицей; продукт может\n * переопределить.\n */\n onClick?: () => void;\n /**\n * Порядок в списке (по возрастанию). Нативные: reset=100, pin-columns=200.\n * Пункты без order идут в конец, сохраняя исходный порядок.\n */\n order?: number;\n /**\n * Нарисовать разделитель после пункта.\n * @default false\n */\n dividerAfter?: boolean;\n disabled?: boolean;\n};\n```",
|
|
52306
52919
|
"api": [
|
|
52307
52920
|
{
|
|
52308
52921
|
"typeName": "ColumnsControlConfig",
|
|
52309
|
-
"source": "type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};"
|
|
52922
|
+
"source": "type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n /**\n * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n * ресайз на этой границе работает как обычно.\n * @default hiding\n */\n hiddenColumnsIndicator?: boolean;\n /**\n * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n * столбцы раскрылись и между какими видимыми колонками стояла линия.\n */\n onHiddenColumnsIndicatorExpand?: (\n info: HiddenColumnsIndicatorExpandInfo,\n ) => void;\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};"
|
|
52923
|
+
},
|
|
52924
|
+
{
|
|
52925
|
+
"typeName": "HiddenColumnsIndicatorExpandInfo",
|
|
52926
|
+
"source": "type HiddenColumnsIndicatorExpandInfo = {\n /** Ключи скрытых столбцов, которые раскрываются (весь промежуток за линией). */\n keys: string[];\n /** Видимый сосед слева от линии. undefined, если линия у левого края таблицы. */\n leftKey?: string;\n /** Видимый сосед справа от линии. undefined, если линия у правого края таблицы. */\n rightKey?: string;\n};"
|
|
52310
52927
|
},
|
|
52311
52928
|
{
|
|
52312
52929
|
"typeName": "PinningMenuConfig",
|
|
@@ -52324,6 +52941,18 @@
|
|
|
52324
52941
|
"type": "full-code",
|
|
52325
52942
|
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n renderCell(cellInfo) {\n return (\n <Canvas.Button\n id=\"header-tooltip-drag\"\n portalHoverEnabled\n onClick={() => {}}\n >\n 123\n </Canvas.Button>\n );\n },\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'developer',\n name: 'Developer',\n },\n {\n key: 'tr1',\n name: 'TR',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n disableHiding: ['id'],\n pinning: true,\n disablePinning: ['developer'],\n reorderingAside: true,\n reorderingHeader: true,\n columnsLabel: {\n task: 'Задачи',\n },\n orderDefault: ['id', 'issueType', 'task'],\n hiddenDefault: ['tr1'],\n pinnedDefault: ['complete'],\n onConfirm: ({ order, hidden, pinned }, _setters) => {\n // eslint-disable-next-line no-alert\n alert(`\n order: ${order.join(', ')}\n pinned: ${pinned.join(', ')}\n hidden: ${hidden.join(', ')}\n `);\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
52326
52943
|
},
|
|
52944
|
+
{
|
|
52945
|
+
"exportName": "ColumnsControlDynamicColumn",
|
|
52946
|
+
"displayName": "ColumnsControl: динамическое добавление колонки",
|
|
52947
|
+
"type": "full-code",
|
|
52948
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n date: '',\n globalFilter: '',\n });\n const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n const themeOverride = useCallback<\n NonNullable<ColumnConfig<Row>['themeOverride']>\n >((cellInfo) => {\n if (cellInfo.hovered.rowHover) {\n return { bgCell: cellInfo.theme.bgHeader };\n }\n return {};\n }, []);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n themeOverride,\n },\n {\n key: 'task',\n name: 'Title',\n themeOverride,\n minWidth: 200,\n width: 250,\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n themeOverride,\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n sortingType: 'stringSort',\n themeOverride,\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n themeOverride,\n filtering: {\n component: 'input',\n filter: 'includes',\n valueInRow: (r) => `${r.task} ${r.id}`,\n keyInFilterState: 'task',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n themeOverride,\n },\n ],\n [developerIsShown, themeOverride],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n highlightActiveType: 'row',\n columnsControl: {\n enable: true,\n hiding: true,\n pinning: true,\n reorderingAside: true,\n reorderingHeader: true,\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: { label: 'id', clearedValue: '' },\n task: { label: 'task', clearedValue: '' },\n priority: { label: 'Some Label', clearedValue: 'All' },\n issueType: { label: 'issueType', clearedValue: [] },\n complete: { label: 'complete', clearedValue: '' },\n date: { label: 'Дата', clearedValue: '' },\n globalFilter: { label: 'Global filter', clearedValue: '' },\n },\n },\n sorting: {\n state: sortingStateAndSetter,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
|
|
52949
|
+
},
|
|
52950
|
+
{
|
|
52951
|
+
"exportName": "SimpleTableDynamicColumn",
|
|
52952
|
+
"displayName": "SimpleTable: динамическое добавление колонки",
|
|
52953
|
+
"type": "full-code",
|
|
52954
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n const [isFavorite, setIsFavorite] = useState(true);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n date: '',\n globalFilter: '',\n });\n const themeOverride = useCallback<\n NonNullable<ColumnConfig<Row>['themeOverride']>\n >((cellInfo) => {\n if (cellInfo.hovered.rowHover) {\n return { bgCell: cellInfo.theme.bgHeader };\n }\n return {};\n }, []);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n themeOverride,\n renderHeaderCell: ({ theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n gap={8}\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n >\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconAddOutline />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n </Canvas.Container>\n ),\n renderCell: ({ theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n gap={8}\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n >\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconAddOutline />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n </Canvas.Container>\n ),\n },\n {\n key: 'task',\n name: 'Title',\n themeOverride,\n minWidth: 200,\n width: 250,\n renderCell: ({ row, theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n gap={8}\n wrap=\"wrap\"\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n style={{ width: '100%' }}\n >\n <Canvas.Container direction=\"column\" gap={2}>\n <Canvas.Text\n font={theme.baseFontStyle}\n color={theme.accentFg}\n style={{ flexGrow: 1 }}\n >\n {row.task ?? '—'}\n </Canvas.Text>\n <Canvas.Text\n font={theme.baseFontStyle}\n color={theme.textHeader}\n style={{ flexGrow: 1 }}\n >\n {row.priority ?? '—'}\n </Canvas.Text>\n </Canvas.Container>\n <Canvas.Button\n portalHoverEnabled\n variant=\"secondary\"\n onClick={() =>\n // eslint-disable-next-line no-console\n console.log('Подробнее по сотруднику', row.complete)\n }\n >\n Подробнее\n </Canvas.Button>\n </Canvas.Container>\n ),\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n themeOverride,\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n sortingType: 'stringSort',\n themeOverride,\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n themeOverride,\n filtering: {\n component: 'input',\n filter: 'includes',\n\n valueInRow: (r) => `${r.task} ${r.id}`,\n\n keyInFilterState: 'task',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n themeOverride,\n },\n ],\n [developerIsShown, themeOverride],\n );\n\n const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n highlightActiveType: 'row',\n\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: '',\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n sorting: {\n state: sortingStateAndSetter,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
|
|
52955
|
+
},
|
|
52327
52956
|
{
|
|
52328
52957
|
"exportName": "ColumnsControlPinningMenu",
|
|
52329
52958
|
"displayName": "ColumnsControl: доп. пункты меню закрепления",
|
|
@@ -52335,6 +52964,36 @@
|
|
|
52335
52964
|
"displayName": "ID",
|
|
52336
52965
|
"type": "full-code",
|
|
52337
52966
|
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'developer',\n name: 'Developer',\n },\n {\n key: 'tr1',\n name: 'TR',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n const selectingRowStateAndSetter = useState(\n (): ReadonlySet<string | number> => new Set(),\n );\n\n return (\n <TableCanvas\n tableConfig={{\n selecting: {\n rowCheckboxDisabled: (row) => row.id === 2,\n rowShowCheckbox: (row) => row.id !== 3,\n state: selectingRowStateAndSetter,\n rowKeyGetter: (r) => r.id + r.issueType,\n showDefault: false,\n },\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n disableHiding: ['id'],\n pinning: true,\n disablePinning: ['developer'],\n reorderingAside: true,\n reorderingHeader: true,\n columnsLabel: {\n task: 'Задачи',\n },\n orderDefault: ['id', 'issueType', 'task'],\n hiddenDefault: ['tr1'],\n pinnedDefault: ['complete'],\n onConfirm: ({ order, hidden, pinned }, _setters) => {\n // eslint-disable-next-line no-alert\n alert(`\n order: ${order.join(', ')}\n pinned: ${pinned.join(', ')}\n hidden: ${hidden.join(', ')}\n `);\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
52967
|
+
},
|
|
52968
|
+
{
|
|
52969
|
+
"exportName": "HiddenColumnsIndicator",
|
|
52970
|
+
"displayName": "ColumnsControl: индикатор скрытых столбцов",
|
|
52971
|
+
"type": "full-code",
|
|
52972
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n columnsControl: {\n enable: true,\n hiding: true,\n hiddenDefault: ['priority', 'developer', 'tr1'],\n },\n }}\n columnConfig={INDICATOR_COLS}\n rows={rows}\n />\n );\n }"
|
|
52973
|
+
},
|
|
52974
|
+
{
|
|
52975
|
+
"exportName": "HiddenColumnsIndicatorEdges",
|
|
52976
|
+
"displayName": "ColumnsControl: индикатор скрытых столбцов по бокам",
|
|
52977
|
+
"type": "full-code",
|
|
52978
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n columnsControl: {\n enable: true,\n hiding: true,\n pinning: true,\n pinnedDefault: ['task'],\n hiddenDefault: ['id', 'complete'],\n },\n }}\n columnConfig={INDICATOR_COLS}\n rows={rows}\n />\n );\n }"
|
|
52979
|
+
},
|
|
52980
|
+
{
|
|
52981
|
+
"exportName": "HiddenColumnsIndicatorDisabled",
|
|
52982
|
+
"displayName": "ColumnsControl: индикатор скрытых столбцов выключен",
|
|
52983
|
+
"type": "full-code",
|
|
52984
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n columnsControl: {\n enable: true,\n hiding: true,\n hiddenColumnsIndicator: false,\n hiddenDefault: ['priority'],\n },\n }}\n columnConfig={INDICATOR_COLS}\n rows={rows}\n />\n );\n }"
|
|
52985
|
+
},
|
|
52986
|
+
{
|
|
52987
|
+
"exportName": "HiddenColumnsIndicatorGrouped",
|
|
52988
|
+
"displayName": "ColumnsControl: индикатор скрытых столбцов в группе",
|
|
52989
|
+
"type": "full-code",
|
|
52990
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig: ColumnOrColumnGroupConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n {\n key: 'metrics',\n name: 'Показатели',\n children: [\n { key: 'task', name: 'План', width: 130 },\n { key: 'priority', name: 'Факт', width: 130 },\n { key: 'issueType', name: 'Прогноз', width: 130 },\n ],\n },\n {\n key: 'grade',\n name: 'Оценка',\n children: [\n { key: 'developer', name: 'Инд', width: 130 },\n { key: 'complete', name: 'Итог', width: 130 },\n ],\n },\n ];\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n columnsControl: {\n enable: true,\n hiding: true,\n hiddenDefault: ['priority', 'developer'],\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
52991
|
+
},
|
|
52992
|
+
{
|
|
52993
|
+
"exportName": "HiddenColumnsIndicatorSquashed",
|
|
52994
|
+
"displayName": "ColumnsControl: индикатор скрытых столбцов в скваш-колонках",
|
|
52995
|
+
"type": "full-code",
|
|
52996
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig: ColumnOrColumnGroupConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 100 },\n {\n key: 'deep',\n name: 'Глубокая',\n children: [\n {\n key: 'sub',\n name: 'Подгруппа',\n children: [\n { key: 'task', name: 'A', width: 110 },\n { key: 'priority', name: 'B', width: 110 },\n { key: 'issueType', name: 'B1', width: 110 },\n ],\n },\n ],\n },\n { key: 'developer', name: 'Ср', width: 130 },\n {\n key: 'shallow',\n name: 'Мелкая',\n children: [{ key: 'complete', name: 'C', width: 160 }],\n },\n ];\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n columnsGrouping: { squashEmptyCells: true },\n columnsControl: {\n enable: true,\n hiding: true,\n hiddenDefault: ['issueType', 'developer'],\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
52338
52997
|
}
|
|
52339
52998
|
]
|
|
52340
52999
|
},
|
|
@@ -52779,7 +53438,7 @@
|
|
|
52779
53438
|
"legacy": false,
|
|
52780
53439
|
"summary": "*tableConfig.\\*.domMetadata**",
|
|
52781
53440
|
"docs": "# DomMetadata\n\n**tableConfig.\\*.domMetadata**\n\nМетки для автоматизированного тестирования, аналитики и онбординга.\n\n`DomMetadata` позволяет навешивать CSS-классы, data-атрибуты и обработчики кликов на интерактивные элементы таблицы.\nЭто нужно для:\n\n- **Аналитики** — трекинг кликов по кнопкам таблицы\n- **Автотестов** — поиск элементов по `data-testid`\n- **Онбординга** — привязка подсказок к конкретным элементам\n\n## Поддерживаемые элементы (className, dataAttributes)\n\nСледующие элементы поддерживают `className` и `dataAttributes` через `domMetadata`:\n\n**Control Block (панель управления):**\n\n- **Редактирование** — `tableConfig.editing.domMetadata`\n- **Полноэкранный режим** — `tableConfig.fullScreenEnabled.domMetadata`\n- **Размер строки** — `tableConfig.rowSize.domMetadata`\n- **Переключение вида** (строки/карточки) — `tableConfig.view.domMetadata`\n- **Группировка строк** — `tableConfig.rowsGrouping.domMetadata`\n- **Поиск** — `tableConfig.searching.domMetadata`\n- **Итоговые строки** — `tableConfig.summaryRows.domMetadata`\n- **KeyText** (controlBlock) — `tableConfig.keyText.controlBlock.domMetadata`\n- **KeyText** (sidebar) — `tableConfig.keyText.sidebar.domMetadata`\n\n**Selecting (выбор строк):**\n\n- **Чекбокс \"Выбрать все\"** (controlBlock) — `tableConfig.selecting.controlBlock.domMetadata`\n- **Свитч в сайдбаре** — `tableConfig.selecting.sidebar.domMetadata`\n\n**Sidebar (правая панель):**\n\n- **Табы сайдбара** — `tableConfig.sidebarConfig.defaultTabs[].domMetadata`\n- **Подтабы настроек** (Фильтры, Столбцы) — `tableConfig.sidebarConfig.defaultTabs[{id:'filtering'|'columns'}].domMetadata`\n\n**Другие:**\n\n- **Кнопка сворачивания таблицы** — `tableConfig.collapse.domMetadata`\n\n## Элементы с расширенным onClick (className, dataAttributes, onClick + detail)\n\nВ дополнение к `className` и `dataAttributes`, следующие элементы поддерживают `onClick` с контекстом `detail`:\n\n- **Группировать** (чекбоксы, сброс) — `tableConfig.rowsGrouping.domMetadata` — actions: `toggle-group`, `reset-groups`, `custom-item-select`\n- **Кнопка размера строки** — `tableConfig.rowSize.domMetadata` — action: `change-row-size`\n- **Шестеренка настроек** — `tableConfig.sidebarConfig.defaultTabs[{id:'tableSettings'}].domMetadata` — action: `toggle-sidebar-tab`\n- **Крестик закрыть сайдбар** — тот же `domMetadata` таба — action: `close-sidebar`\n- **Закрепить столбец** — `tableConfig.columnsControl.pinDomMetadata` — actions: `pin-column`, `unpin-column`\n- **Свитчер видимости столбца** — `tableConfig.columnsControl.switchDomMetadata` — actions: `show-column`, `hide-column`\n\n## onClick\n\nОбработчик `onClick` вызывается **после** основной логики элемента. Он не мешает работе кнопки и не вызывает `stopPropagation`.\n\n```tsx\nonClick?: (\n e?: React.MouseEvent<HTMLElement>, // MouseEvent (undefined для элементов внутри Dropdown)\n detail?: Record<string, unknown> // контекст: action, columnKey, size и др.\n) => void;\n```\n\n### Примеры detail\n\n```ts\n// Группировка\n{ action: 'toggle-group', columnKey: 'status' }\n{ action: 'reset-groups' }\n\n// Размер строки\n{ action: 'change-row-size', size: 'medium' }\n\n// Сайдбар\n{ action: 'toggle-sidebar-tab', tabId: 'tableSettings' }\n{ action: 'close-sidebar' }\n\n// Столбцы\n{ action: 'pin-column', columnKey: 'name' }\n{ action: 'unpin-column', columnKey: 'name' }\n{ action: 'hide-column', columnKey: 'name' }\n{ action: 'show-column', columnKey: 'name' }\n```\n\nПодробнее о типах — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-dommetadata-api--docs).",
|
|
52782
|
-
"apiDocs": "# DomMetadata API\n\n## DomMetadata\n\n```typescript\ntype DomMetadata = {\n /**\n * CSS класс для стилизации и поиска элемента\n *\n * @example 'user-profile-card'\n * @example 'onboarding-step-1'\n */\n className?: string;\n /**\n * Data-атрибуты для тестирования, аналитики и онбординга\n *\n * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n */\n dataAttributes?: DataAttributes;\n /**\n * Обработчик клика для аналитики и трекинга\n *\n * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n *\n * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n * @param detail - контекст действия: action, columnKey, size и др.\n *\n * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n */\n onClick?: (\n e?: React.MouseEvent<HTMLElement>,\n detail?: Record<string, unknown>,\n ) => void;\n};\n```\n\n## DOM_METADATA_ACTIONS\n\n```typescript\nexport const DOM_METADATA_ACTIONS = {\n /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n TOGGLE_GROUP: 'toggle-group',\n /** Сброс всех группировок */\n RESET_GROUPS: 'reset-groups',\n /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n CUSTOM_ITEM_SELECT: 'custom-item-select',\n /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n CHANGE_ROW_SIZE: 'change-row-size',\n /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n /** Закрытие сайдбара (крестик) */\n CLOSE_SIDEBAR: 'close-sidebar',\n /** Закрепление столбца. detail.columnKey — ключ столбца */\n PIN_COLUMN: 'pin-column',\n /** Открепление столбца. detail.columnKey — ключ столбца */\n UNPIN_COLUMN: 'unpin-column',\n /** Скрытие столбца. detail.columnKey — ключ столбца */\n HIDE_COLUMN: 'hide-column',\n /** Показ столбца. detail.columnKey — ключ столбца */\n SHOW_COLUMN: 'show-column',\n} as const;\n```\n\n## DomMetadataAction\n\n```typescript\ntype DomMetadataAction =\n (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];\n```\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};\n```",
|
|
53441
|
+
"apiDocs": "# DomMetadata API\n\n## DomMetadata\n\n```typescript\ntype DomMetadata = {\n /**\n * CSS класс для стилизации и поиска элемента\n *\n * @example 'user-profile-card'\n * @example 'onboarding-step-1'\n */\n className?: string;\n /**\n * Data-атрибуты для тестирования, аналитики и онбординга\n *\n * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n */\n dataAttributes?: DataAttributes;\n /**\n * Обработчик клика для аналитики и трекинга\n *\n * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n *\n * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n * @param detail - контекст действия: action, columnKey, size и др.\n *\n * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n */\n onClick?: (\n e?: React.MouseEvent<HTMLElement>,\n detail?: Record<string, unknown>,\n ) => void;\n};\n```\n\n## DOM_METADATA_ACTIONS\n\n```typescript\nexport const DOM_METADATA_ACTIONS = {\n /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n TOGGLE_GROUP: 'toggle-group',\n /** Сброс всех группировок */\n RESET_GROUPS: 'reset-groups',\n /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n CUSTOM_ITEM_SELECT: 'custom-item-select',\n /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n CHANGE_ROW_SIZE: 'change-row-size',\n /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n /** Закрытие сайдбара (крестик) */\n CLOSE_SIDEBAR: 'close-sidebar',\n /** Закрепление столбца. detail.columnKey — ключ столбца */\n PIN_COLUMN: 'pin-column',\n /** Открепление столбца. detail.columnKey — ключ столбца */\n UNPIN_COLUMN: 'unpin-column',\n /** Скрытие столбца. detail.columnKey — ключ столбца */\n HIDE_COLUMN: 'hide-column',\n /** Показ столбца. detail.columnKey — ключ столбца */\n SHOW_COLUMN: 'show-column',\n} as const;\n```\n\n## DomMetadataAction\n\n```typescript\ntype DomMetadataAction =\n (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];\n```\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n /**\n * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n * ресайз на этой границе работает как обычно.\n * @default hiding\n */\n hiddenColumnsIndicator?: boolean;\n /**\n * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n * столбцы раскрылись и между какими видимыми колонками стояла линия.\n */\n onHiddenColumnsIndicatorExpand?: (\n info: HiddenColumnsIndicatorExpandInfo,\n ) => void;\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};\n```",
|
|
52783
53442
|
"api": [
|
|
52784
53443
|
{
|
|
52785
53444
|
"typeName": "DomMetadata",
|
|
@@ -52795,7 +53454,7 @@
|
|
|
52795
53454
|
},
|
|
52796
53455
|
{
|
|
52797
53456
|
"typeName": "ColumnsControlConfig",
|
|
52798
|
-
"source": "type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};"
|
|
53457
|
+
"source": "type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n /**\n * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n * ресайз на этой границе работает как обычно.\n * @default hiding\n */\n hiddenColumnsIndicator?: boolean;\n /**\n * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n * столбцы раскрылись и между какими видимыми колонками стояла линия.\n */\n onHiddenColumnsIndicatorExpand?: (\n info: HiddenColumnsIndicatorExpandInfo,\n ) => void;\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};"
|
|
52799
53458
|
}
|
|
52800
53459
|
],
|
|
52801
53460
|
"stories": [
|
|
@@ -52975,11 +53634,11 @@
|
|
|
52975
53634
|
"legacy": false,
|
|
52976
53635
|
"summary": "*tableConfig.filtering**",
|
|
52977
53636
|
"docs": "# Filtering\n\n**tableConfig.filtering**\n\nФильтрация данных таблицы с поддержкой автоматического и ручного режимов.\n\n## Ключевые особенности\n\n- Три типа фильтров: `input`, `select`, `custom`\n- Автоматическая фильтрация по умолчанию, ручная через `manualFiltering: true`\n- Отображение активных фильтров в виде chip-элементов\n- Поддержка фильтрации через sidebar с настройкой порядка и глобальных фильтров\n- Кастомизация chip-стилей и лейблов\n\n## Типы фильтров\n\n### Input\n\nТекстовый фильтр с режимами: `'includes'`, `'startWith'`, `'equal'` или кастомная функция.\n\n### Select\n\nФильтр выбором из списка. Поддержка одиночного (`'single'`) и множественного (`'multiple'`) выбора.\n\n### Custom\n\nПолностью кастомный компонент фильтра через `customRender`.\n\n## Конфигурация FilteringConfig\n\n- **`state`** `[T, setState]` — стейт фильтров (обязательный)\n- **`manualFiltering`** `boolean` — ручная фильтрация (данные не фильтруются таблицей)\n- **`filtersInfo`** `Record<keyof T, { label, clearedValue }>` — метки и дефолтные значения фильтров\n- **`sidebarConfig`** `{ order?, items }` — конфигурация sidebar с фильтрами\n- **`chipStyle`** `(itemOrGroup, item) => CSSObject` — кастомные стили для chip-элементов\n- **`renderGroupLabel`** `(group) => string` — кастомный заголовок группы чипсов\n- **`renderChipLabel`** `(group, item) => string` — кастомный текст чипса\n\n## Кастомизация чипсов\n\n### chipStyle\n\nПозволяет динамически задавать стили для каждого чипа фильтра в зависимости от его типа и содержимого.\n\n### renderGroupLabel\n\nФорматтер заголовка группы чипсов. Полезен для i18n или добавления счётчика выбранных элементов.\n\n### renderChipLabel\n\nФорматтер текста внутри чипса. Полезен при серверной пагинации, когда в стейте хранится только `value`, а `label` подставляется из кэша.\n\n## Особенности\n\n- При `manualFiltering: true` таблица не фильтрует данные — ожидается внешняя логика (серверная)\n- `sidebarConfig` позволяет добавлять глобальные фильтры, не привязанные к колонкам\n- `filtersInfo` задаёт лейблы и значения по умолчанию для каждого фильтра\n\n> Подробнее о типах — [Filtering API](?path=/docs/локальные-компоненты-tablecanvas-filtering-api--docs)",
|
|
52978
|
-
"apiDocs": "# Filtering API\n\n## FilteringConfig\n\n```typescript\ntype FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true, onBeforeCopy: (data) => data } }}\n */\n cellTransfer?: CellTransferConfig;\n\n /**\n * Объединение ячеек тела таблицы.\n *\n * mergeByCellValues — колонки, в которых подряд идущие одинаковые значения\n * сливаются в один блок (по вертикали). Границы блоков таблица считает сама из\n * данных; сортировка и фильтр их пересобирают. Данные не меняются — значение и\n * так повторяется в строках, объединение лишь показывает его одной ячейкой.\n *\n * mergedCellsRegions — список блоков, заданных снаружи (как выделение): каждый\n * блок описан ключами строк (rowKeys) и колонок (colKeys). Нужен rowKeyGetter.\n * Если после сортировки или скрытия колонок строки/колонки блока перестали идти\n * подряд — блок не рисуется. Важнее mergeByCellValues.\n *\n * Примеры: mergeCells={{ mergeByCellValues: ['dept', 'role'] }},\n * mergeCells={{ mergedCellsRegions, rowKeyGetter: (r) => r.id }}.\n */\n mergeCells?: {\n mergeByCellValues?: Array<\n string | { colKey: string; value: (row: RowType) => unknown }\n >;\n /** Список блоков, заданных снаружи (по ключам строк и колонок). */\n mergedCellsRegions?: MergedCellsRegion[];\n /**\n * Нужен для mergedCellsRegions: находит строку по её ключу. Должна быть\n * стабильной функцией; менять её на лету не нужно — в пересборку таблицы она\n * не входит.\n */\n rowKeyGetter?: (row: RowType) => string | number;\n /**\n * Выравнивание по умолчанию для всех блоков. Колоночный mergedCellsAlign и\n * выравнивание конкретного региона важнее.\n */\n mergedCellsAlign?: MergedCellsAlign;\n };\n\n /**\n * Модуль нотификаций: стандартизированный канал событий для внешних\n * потребителей. Таблица UI не рисует — вызывает `onNotification`, потребитель\n * показывает тост/модалку на своей стороне. Сейчас эмитятся ошибки copy/paste\n * (в т.ч. multi-range 2D-разброс, readonly/overflow-abort, пропуск валидацией).\n */\n notifications?: TableNotificationsConfig;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n /**\n * Столбец с нумерацией строк.\n * Активируется наличием этого свойства. Поддерживает `subRows` любой глубины.\n *\n * @see {@link RowMarkersTableConfig} — полное описание конфигурации и примеры.\n */\n rowMarkers?: RowMarkersTableConfig<RowType>;\n rowsGrouping?: RowsGrouping<RowType, SummaryRowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * unstickyHeader - откреплённая шапка. Header уезжает вместе со скроллом контента.\n * @default false\n */\n unstickyHeader?: boolean;\n\n /** Тултип при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\n tooltip?: TableConfigTooltip;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: InfinityScrollConfig<RowType>;\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n /**\n * Empty state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n emptyState?: TableCanvasEmptyStateConfig;\n /**\n * Error state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n errorState?: TableCanvasErrorStateConfig;\n // FIXME:\n // noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n // FIXME:\n // rowDetailPanel?: RowDetailConfig<RowType>;\n // FIXME: Временно комментирую использование, пока не адаптируем TableCanvas\n // rowInstruments?: {\n // getRowDropdownConfig: RowInstrumentsType<RowType>;\n // /**\n // * @default false\n // */\n // defaultOpened?: boolean;\n // /**\n // * @default true\n // */\n // showInControl?: boolean;\n // /**\n // * Внешний стейт видимости\n // */\n // openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n // };\n fullScreenEnabled?: FullScreen;\n /**\n * Переносит портал editor overlay внутрь контейнера таблицы вместо document.body.\n * Решает проблему focus trap и сдвига координат при рендере таблицы в модалке с CSS transform.\n * @default undefined (overlay рендерится в document.body — стандартное поведение)\n */\n editorOverlayPortal?: 'inside';\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - callback открытия контекстного меню.\n */\n onHeaderContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenu'];\n onHeaderContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenuDropdown'];\n onCellContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenuDropdown'];\n onCellContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenu'];\n /**\n * Обработчик клика по ячейке.\n *\n * Получает `cell` readonly [colIndex, rowIndex] от glide, и `info` обогащённый объект\n * с row, column, ctxs, refTable (аналогично onCellContextMenu).\n */\n onCellClicked?: (\n cell: readonly [number, number],\n info: TableInfoWithRow<RowType, SummaryRowType>,\n ) => void;\n} & GlideInstanceOmitted<RowType, SummaryRowType>;\n\ntype GlideInstanceOmitted<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = Pick<\n Omit<\n TableGlideInstanceProps<RowType, SummaryRowType>,\n | keyof TableGlideCustomProps<RowType, SummaryRowType>\n | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n >,\n | 'className'\n | 'columnSelect'\n | 'minColumnWidth'\n | 'maxColumnWidth'\n | 'maxColumnAutoWidth'\n | 'onVisibleRegionChanged'\n | 'onCellClicked'\n // | 'CellReadOnlyEditor'\n // | 'onGroupHeaderClicked'\n | 'onHeaderClicked'\n | 'onItemHovered'\n | 'trapFocus'\n | 'onColumnResize'\n>;\nexport type CellReadOnlyEditorProps<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = CellReadOnlyEditorGlideInstanceStaticProps &\n EditingCellInfo<RowType, SummaryRowType>;\n\n// & Pick<\n// DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n// | 'summaryRowHeight'\n// | 'onFill'\n// | 'onCopy'\n// | 'onPaste'\n// | 'onCellClick'\n// | 'onCellDoubleClick'\n// | 'onCellContextMenu'\n// | 'onCellKeyDown'\n// | 'onSelectedCellChange'\n// | 'onScroll'\n// | 'onColumnResize'\n// | 'onColumnsReorder'\n// | 'enableVirtualization'\n// | 'rowClass'\n// | 'data-testid'\n// | 'headerRowHeight'\n// >;\n\n/**\n * Конфигурация фичи rowMarkers (столбец с нумерацией строк).\n *\n * Столбец frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping.\n * Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n *\n * **Дефолтное поведение** (без `getRowMarker`): root-only нумерация —\n * корневые строки получают номер (`startIndex + rootIndex`), дочерние — пустую строку.\n *\n * @example\n * ```tsx\n * // Минимальная конфигурация\n * tableConfig={{ rowMarkers: { startIndex: 1 } }}\n *\n * // Сквозная стабильная нумерация\n * tableConfig={{ rowMarkers: { getRowMarker: ({ flatIndex }) => flatIndex + 1 } }}\n * ```\n */\nexport type RowMarkersTableConfig<\n RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n /**\n * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n * @default 1\n */\n startIndex?: number;\n\n /**\n * Ширина столбца с нумерацией (в px).\n * Если задан `size` — он приоритетнее.\n+ * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+ * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n * @default 32\n */\n width?: number;\n /**\n * Размер столбца. Приоритетнее `width`.\n * - `xs` = 20px\n * - `s` = 32px\n * - `m` = 48px\n */\n size?: 'xs' | 's' | 'm';\n /**\n * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n * Вызывается при рендере каждой ячейки столбца нумерации.\n *\n * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n *\n * @example\n * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n * getRowMarker: ({ flatIndex }) => flatIndex + 1\n *\n * @example\n * // Корневые — номер, дочерние — прочерк\n * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n *\n * @example\n * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n */\n getRowMarker?: (args: {\n /** Данные текущей строки. */\n row: RowType;\n /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n level: number;\n /** `true`, если строка дочерняя (`level > 0`). */\n isSubRow: boolean;\n /**\n * Индекс строки в **видимых** строках.\n * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n */\n rowIndex: number;\n /**\n * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n * Не меняется при collapse/expand — подходит для сквозной нумерации.\n */\n flatIndex: number;\n /**\n * Порядковый номер среди siblings одного родителя (0-based).\n * Для корневых строк — порядковый номер среди всех корневых.\n * Для дочерних — порядковый номер среди children одного `parentKey`.\n */\n siblingIndex: number;\n /**\n * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n *\n * Примеры:\n * - корневая строка (2-я): `[1]`\n * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n *\n * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n *\n * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n */\n siblingPath: number[];\n /**\n * Ключ родительской строки (`rowKeyGetter(parent)`).\n * `null` для корневых строк. Работает для **любой** глубины вложенности.\n */\n parentKey: string | number | null;\n /** Текущий видимый `flattened` массив строк. */\n rows: readonly RowType[];\n }) => string | number;\n};\n```\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n FilterStateType extends ObjectForExtending,\n ColumnConfig,\n> = {\n popoverIsOpen: boolean;\n setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n columnConfig: ColumnConfig;\n tabIndex: number;\n headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n FiltersVariables &\n HeaderContextValueTypeInstance<ObjectForExtending>;\n /**\n * Источник открытия фильтра: из шапки таблицы или из сайдбара\n * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n */\n filterSource?: 'header' | 'sidebar';\n};\n```",
|
|
53637
|
+
"apiDocs": "# Filtering API\n\n## FilteringConfig\n\n```typescript\ntype FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true, onBeforeCopy: (data) => data } }}\n */\n cellTransfer?: CellTransferConfig;\n\n /**\n * Объединение ячеек тела таблицы.\n *\n * mergeByCellValues — колонки, в которых подряд идущие одинаковые значения\n * сливаются в один блок (по вертикали). Границы блоков таблица считает сама из\n * данных; сортировка и фильтр их пересобирают. Данные не меняются — значение и\n * так повторяется в строках, объединение лишь показывает его одной ячейкой.\n *\n * mergedCellsRegions — список блоков, заданных снаружи (как выделение): каждый\n * блок описан ключами строк (rowKeys) и колонок (colKeys). Нужен rowKeyGetter.\n * Если после сортировки или скрытия колонок строки/колонки блока перестали идти\n * подряд — блок не рисуется. Важнее mergeByCellValues.\n *\n * Примеры: mergeCells={{ mergeByCellValues: ['dept', 'role'] }},\n * mergeCells={{ mergedCellsRegions, rowKeyGetter: (r) => r.id }}.\n */\n mergeCells?: {\n mergeByCellValues?: Array<\n string | { colKey: string; value: (row: RowType) => unknown }\n >;\n /** Список блоков, заданных снаружи (по ключам строк и колонок). */\n mergedCellsRegions?: MergedCellsRegion[];\n /**\n * Нужен для mergedCellsRegions: находит строку по её ключу. Должна быть\n * стабильной функцией; менять её на лету не нужно — в пересборку таблицы она\n * не входит.\n */\n rowKeyGetter?: (row: RowType) => string | number;\n /**\n * Выравнивание по умолчанию для всех блоков. Колоночный mergedCellsAlign и\n * выравнивание конкретного региона важнее.\n */\n mergedCellsAlign?: MergedCellsAlign;\n };\n\n /**\n * Модуль нотификаций: стандартизированный канал событий для внешних\n * потребителей. Таблица UI не рисует — вызывает `onNotification`, потребитель\n * показывает тост/модалку на своей стороне. Сейчас эмитятся ошибки copy/paste\n * (в т.ч. multi-range 2D-разброс, readonly/overflow-abort, пропуск валидацией).\n */\n notifications?: TableNotificationsConfig;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n /**\n * Столбец с нумерацией строк.\n * Активируется наличием этого свойства. Поддерживает `subRows` любой глубины.\n *\n * @see {@link RowMarkersTableConfig} — полное описание конфигурации и примеры.\n */\n rowMarkers?: RowMarkersTableConfig<RowType>;\n rowsGrouping?: RowsGrouping<RowType, SummaryRowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * unstickyHeader - откреплённая шапка. Header уезжает вместе со скроллом контента.\n * @default false\n */\n unstickyHeader?: boolean;\n\n /** Тултип при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\n tooltip?: TableConfigTooltip;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: InfinityScrollConfig<RowType>;\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n /**\n * Empty state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n emptyState?: TableCanvasEmptyStateConfig;\n /**\n * Error state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n errorState?: TableCanvasErrorStateConfig;\n // FIXME:\n // noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n // FIXME:\n // rowDetailPanel?: RowDetailConfig<RowType>;\n // FIXME: Временно комментирую использование, пока не адаптируем TableCanvas\n // rowInstruments?: {\n // getRowDropdownConfig: RowInstrumentsType<RowType>;\n // /**\n // * @default false\n // */\n // defaultOpened?: boolean;\n // /**\n // * @default true\n // */\n // showInControl?: boolean;\n // /**\n // * Внешний стейт видимости\n // */\n // openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n // };\n fullScreenEnabled?: FullScreen;\n /**\n * Переносит портал editor overlay внутрь контейнера таблицы вместо document.body.\n * Решает проблему focus trap и сдвига координат при рендере таблицы в модалке с CSS transform.\n * @default undefined (overlay рендерится в document.body — стандартное поведение)\n */\n editorOverlayPortal?: 'inside';\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - callback открытия контекстного меню.\n */\n onHeaderContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenu'];\n onHeaderContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenuDropdown'];\n onCellContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenuDropdown'];\n onCellContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenu'];\n /**\n * Обработчик клика по ячейке.\n *\n * Получает `cell` readonly [colIndex, rowIndex] от glide, и `info` обогащённый объект\n * с row, column, ctxs, refTable (аналогично onCellContextMenu).\n */\n onCellClicked?: (\n cell: readonly [number, number],\n info: TableInfoWithRow<RowType, SummaryRowType>,\n ) => void;\n} & GlideInstanceOmitted<RowType, SummaryRowType>;\n\ntype GlideInstanceOmitted<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = Pick<\n Omit<\n TableGlideInstanceProps<RowType, SummaryRowType>,\n | keyof TableGlideCustomProps<RowType, SummaryRowType>\n | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n >,\n | 'className'\n | 'columnSelect'\n | 'minColumnWidth'\n | 'maxColumnWidth'\n | 'maxColumnAutoWidth'\n | 'onVisibleRegionChanged'\n | 'onCellClicked'\n // | 'CellReadOnlyEditor'\n // | 'onGroupHeaderClicked'\n | 'onHeaderClicked'\n | 'onItemHovered'\n | 'trapFocus'\n | 'onColumnResize'\n>;\nexport type CellReadOnlyEditorProps<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = CellReadOnlyEditorGlideInstanceStaticProps &\n EditingCellInfo<RowType, SummaryRowType>;\n\n// & Pick<\n// DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n// | 'summaryRowHeight'\n// | 'onFill'\n// | 'onCopy'\n// | 'onPaste'\n// | 'onCellClick'\n// | 'onCellDoubleClick'\n// | 'onCellContextMenu'\n// | 'onCellKeyDown'\n// | 'onSelectedCellChange'\n// | 'onScroll'\n// | 'onColumnResize'\n// | 'onColumnsReorder'\n// | 'enableVirtualization'\n// | 'rowClass'\n// | 'data-testid'\n// | 'headerRowHeight'\n// >;\n\n/**\n * Конфигурация фичи rowMarkers (столбец с нумерацией строк).\n *\n * Столбец frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping.\n * Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n *\n * **Дефолтное поведение** (без `getRowMarker`): root-only нумерация —\n * корневые строки получают номер (`startIndex + rootIndex`), дочерние — пустую строку.\n *\n * @example\n * ```tsx\n * // Минимальная конфигурация\n * tableConfig={{ rowMarkers: { startIndex: 1 } }}\n *\n * // Сквозная стабильная нумерация\n * tableConfig={{ rowMarkers: { getRowMarker: ({ flatIndex }) => flatIndex + 1 } }}\n * ```\n */\nexport type RowMarkersTableConfig<\n RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n /**\n * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n * @default 1\n */\n startIndex?: number;\n\n /**\n * Ширина столбца с нумерацией (в px).\n * Если задан `size` — он приоритетнее.\n+ * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+ * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n * @default 32\n */\n width?: number;\n /**\n * Размер столбца. Приоритетнее `width`.\n * - `xs` = 20px\n * - `s` = 32px\n * - `m` = 48px\n */\n size?: 'xs' | 's' | 'm';\n /**\n * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n * Вызывается при рендере каждой ячейки столбца нумерации.\n *\n * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n *\n * @example\n * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n * getRowMarker: ({ flatIndex }) => flatIndex + 1\n *\n * @example\n * // Корневые — номер, дочерние — прочерк\n * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n *\n * @example\n * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n */\n getRowMarker?: (args: {\n /** Данные текущей строки. */\n row: RowType;\n /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n level: number;\n /** `true`, если строка дочерняя (`level > 0`). */\n isSubRow: boolean;\n /**\n * Индекс строки в **видимых** строках.\n * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n */\n rowIndex: number;\n /**\n * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n * Не меняется при collapse/expand — подходит для сквозной нумерации.\n */\n flatIndex: number;\n /**\n * Порядковый номер среди siblings одного родителя (0-based).\n * Для корневых строк — порядковый номер среди всех корневых.\n * Для дочерних — порядковый номер среди children одного `parentKey`.\n */\n siblingIndex: number;\n /**\n * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n *\n * Примеры:\n * - корневая строка (2-я): `[1]`\n * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n *\n * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n *\n * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n */\n siblingPath: number[];\n /**\n * Ключ родительской строки (`rowKeyGetter(parent)`).\n * `null` для корневых строк. Работает для **любой** глубины вложенности.\n */\n parentKey: string | number | null;\n /** Текущий видимый `flattened` массив строк. */\n rows: readonly RowType[];\n }) => string | number;\n};\n```\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n FilterStateType extends ObjectForExtending,\n ColumnConfig,\n> = {\n popoverIsOpen: boolean;\n setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n columnConfig: ColumnConfig;\n tabIndex: number;\n headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n FiltersVariables &\n HeaderContextValueTypeInstance<ObjectForExtending>;\n /**\n * Источник открытия фильтра: из шапки таблицы или из сайдбара\n * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n */\n filterSource?: 'header' | 'sidebar';\n};\n```",
|
|
52979
53638
|
"api": [
|
|
52980
53639
|
{
|
|
52981
53640
|
"typeName": "FilteringConfig",
|
|
52982
|
-
"source": "type FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *"
|
|
53641
|
+
"source": "type FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *"
|
|
52983
53642
|
},
|
|
52984
53643
|
{
|
|
52985
53644
|
"typeName": "FilterComponentInPopoverProps",
|
|
@@ -52991,7 +53650,7 @@
|
|
|
52991
53650
|
"exportName": "FilteringTable",
|
|
52992
53651
|
"displayName": "Filtering Table",
|
|
52993
53652
|
"type": "full-code",
|
|
52994
|
-
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n const [isFavorite, setIsFavorite] = useState(true);\n const [rows] = useState(() => {\n const seededRandom = createSeededRandom(42);\n return createRows().map((el) => ({\n ...el,\n id: Math.floor(seededRandom() * 1000),\n date: (() => {\n const date = new Date(\n FIXED_DATE_TIMESTAMP +\n (Math.floor(seededRandom() * 61) - 30) * 86400000,\n );\n return `${String(date.getDate()).padStart(2, '0')}.${String(\n date.getMonth() + 1,\n ).padStart(2, '0')}.${date.getFullYear()}`;\n })(),\n }));\n });\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n globalFilter: '',\n date: undefined as string | undefined,\n });\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'date',\n name: 'Date',\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters },\n } = props;\n return (\n <Calendar\n value={filters?.['date']}\n onChangeValue={(v) => {\n if (setFilters)\n setFilters((prev) => ({\n ...prev,\n date: v,\n }));\n }}\n />\n );\n },\n filter: (filterValue, rowValue) =>\n filterValue ? rowValue === filterValue : true,\n valueInRow: (r) => (r as Row & { date: string })?.date,\n compareWithClearedValue: (clearedValue, currV) =>\n clearedValue === currV,\n keyInFilterState: 'date',\n },\n },\n\n {\n key: 'priority',\n name: 'Priority',\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n filtering: {\n beforeList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n custom beforeList\n </TableFilterSelectListItem>\n );\n },\n component: 'select',\n selectOptions: {\n type: 'stateInHeaderContext',\n optionsKeyInHeaderContext: 'issueTypeOptions',\n },\n keyInFilterState: 'issueType',\n valueInRow: (r) => r.issueType,\n filter: {\n typeOfValue: 'multiple',\n filteringType: (fv, rv) =>\n !fv.length || fv.some((fvCurr) => fvCurr === rv),\n },\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n const headerContextValue = useMemo(\n () => ({\n issueTypeOptions: [\n { text: 'Bug', value: 'Bug' },\n { text: 'Improvement', value: 'Improvement' },\n { text: 'Epic', value: 'Epic' },\n { text: 'Story', value: 'Story' },\n ],\n }),\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: undefined,\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n headerContextValue={headerContextValue}\n />\n );\n }"
|
|
53653
|
+
"code": "import React, { useMemo, useState } from 'react';\nimport {\n Box,\n Button,\n Calendar,\n Combobox,\n ComboboxItemOption,\n Divider,\n} from '@daisforge/ui';\nimport { IconStar } from '@daisforge/ui/icons';\nimport {\n ColumnConfig,\n TableCanvas,\n TableFilterSelect,\n TableFilterSelectListItem,\n} from '@daisforge/ui/components/TableCanvas';\n\nimport { createRows, type Row } from './data/tableData';\n\n() => {\n const [isFavorite, setIsFavorite] = useState(true);\n const [rows] = useState(() => {\n const seededRandom = createSeededRandom(42);\n return createRows().map((el) => ({\n ...el,\n id: Math.floor(seededRandom() * 1000),\n date: (() => {\n const date = new Date(\n FIXED_DATE_TIMESTAMP +\n (Math.floor(seededRandom() * 61) - 30) * 86400000,\n );\n return `${String(date.getDate()).padStart(2, '0')}.${String(\n date.getMonth() + 1,\n ).padStart(2, '0')}.${date.getFullYear()}`;\n })(),\n }));\n });\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n issueTypeCustom: [] as string[],\n complete: '',\n globalFilter: '',\n date: undefined as string | undefined,\n });\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'date',\n name: 'Date',\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters },\n } = props;\n return (\n <Calendar\n value={filters?.['date']}\n onChangeValue={(v) => {\n if (setFilters)\n setFilters((prev) => ({\n ...prev,\n date: v,\n }));\n }}\n />\n );\n },\n filter: (filterValue, rowValue) =>\n filterValue ? rowValue === filterValue : true,\n valueInRow: (r) => (r as Row & { date: string })?.date,\n compareWithClearedValue: (clearedValue, currV) =>\n clearedValue === currV,\n keyInFilterState: 'date',\n },\n },\n\n {\n key: 'priority',\n name: 'Priority',\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n {\n value: 'All',\n text: 'Все инциденты и запросы на доработку без ограничения по срочности',\n },\n {\n value: 'High',\n text: 'Высокий приоритет критически важного инцидента',\n },\n {\n value: 'Critical',\n text: 'Критическая ошибка блокирующая работу сервиса',\n },\n {\n value: 'Medium',\n text: 'Средний приоритет плановой доработки функциональности',\n },\n {\n value: 'Low',\n text: 'Низкий приоритет косметического усовершенствования интерфейса',\n },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n filtering: {\n beforeList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой сверху списка\n </TableFilterSelectListItem>\n );\n },\n afterList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой внизу списка\n </TableFilterSelectListItem>\n );\n },\n component: 'select',\n selectOptions: {\n type: 'stateInHeaderContext',\n optionsKeyInHeaderContext: 'issueTypeOptions',\n },\n keyInFilterState: 'issueType',\n valueInRow: (r) => r.issueType,\n filter: {\n typeOfValue: 'multiple',\n filteringType: (fv, rv) =>\n !fv.length || fv.some((fvCurr) => fvCurr === rv),\n },\n },\n },\n {\n key: 'issueTypeCustom',\n name: 'Issue Type (custom render) ',\n renderCell({ row }) {\n return row.issueType;\n },\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters, rowSize },\n setPopoverIsOpen,\n } = props;\n // Опции для выпадашки берутся из headerContextValue (см. headerContextValue ниже)\n const headerContextState = props.headerContextState as Record<\n string,\n unknown\n >;\n const issueTypeOptions = (headerContextState.issueTypeOptions ??\n []) as { text: string; value: string }[];\n\n // Локальный черновик выбранных значений: меняется при кликах по айтемам,\n // а в реальный стейт фильтров попадает по кнопке «Применить» (afterList).\n const [draftValue, setDraftValue] = useState<string[]>(\n (filters?.['issueTypeCustom'] as string[] | undefined) ?? [],\n );\n\n const apply = () => {\n if (setFilters) {\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }));\n setPopoverIsOpen(false);\n }\n };\n\n return (\n <TableFilterSelect\n mode=\"multiple\"\n value={draftValue}\n onChange={setDraftValue}\n options={issueTypeOptions}\n size={rowSize}\n width=\"232px\"\n beforeList={\n <TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>\n }\n afterList={\n <Box\n $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n rowSize === 'big' ? '4px' : '4px'\n }; margin-top: 4px;`}\n >\n <Divider />\n <Button\n size={rowSize === 'small' ? 'xxs' : 's'}\n style={{ marginLeft: 'auto ' }}\n view=\"accent\"\n onClick={apply}\n >\n Применить\n </Button>\n </Box>\n }\n />\n );\n },\n filter: (filterValue, rowValue) =>\n !Array.isArray(filterValue) ||\n !(filterValue as string[]).length ||\n (filterValue as string[]).some((fvCurr) => fvCurr === rowValue),\n valueInRow: (r) => r.issueType,\n compareWithClearedValue: (clearedValue, currV) =>\n JSON.stringify(clearedValue) === JSON.stringify(currV),\n keyInFilterState: 'issueTypeCustom',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n const headerContextValue = useMemo(\n () => ({\n issueTypeOptions: [\n {\n // Ошибка-1212---3232-3---4343434 - для визуальной проверки длинных текстов без пробелов\n text: 'Ошибка-1212---3232-3---4343434 при формировании выписки по счету',\n value: 'Bug',\n },\n {\n text: 'Улучшение производительности загрузки списка документов',\n value: 'Improvement',\n },\n {\n text: 'Эпик крупной функциональности платежного модуля',\n value: 'Epic',\n },\n {\n text: 'История пользовательского сценария оформления кредита',\n value: 'Story',\n },\n ],\n }),\n [],\n );\n\n // Combobox из sdds-finai ожидает items в формате { value, label }.\n const sidebarIssueTypeOptions = useMemo<ComboboxItemOption[]>(\n () =>\n headerContextValue.issueTypeOptions.map((option) => ({\n value: option.value,\n label: option.text,\n })),\n [headerContextValue],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n sidebarConfig: {\n items: {\n // Переопределяем рендер колоночного фильтра именно для сайдбара:\n // колоночный customRender остаётся в поповере шапки.\n issueTypeCustom: {\n label: 'Issue Type (custom render)',\n customRenderFn: (filters, setFilters) => {\n // Хуки здесь допустимы: customRenderFn рендерится как\n // компонент (см. RenderSlot в feature-filtering).\n // Черновик выбора уезжает в фильтры сайдбара по кнопке\n // «Применить» внутри выпадающего списка (afterList).\n const [draftValue, setDraftValue] = useState<string[]>(\n filters.issueTypeCustom,\n );\n\n return (\n <Combobox\n multiple\n size=\"s\"\n items={sidebarIssueTypeOptions}\n value={draftValue}\n onChange={(next: string[]) => setDraftValue(next)}\n closeAfterSelect={false}\n placeholder=\"Выберите Issue Type\"\n afterList={\n <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n <Divider />\n <Button\n size=\"xs\"\n view=\"accent\"\n style={{ marginLeft: 'auto' }}\n onClick={() =>\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }))\n }\n >\n Применить\n </Button>\n </Box>\n }\n />\n );\n },\n },\n },\n },\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n issueTypeCustom: {\n label: 'issueTypeCustom',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: undefined,\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n headerContextValue={headerContextValue}\n />\n );\n }"
|
|
52995
53654
|
},
|
|
52996
53655
|
{
|
|
52997
53656
|
"exportName": "ManualFiltering",
|
|
@@ -53023,6 +53682,74 @@
|
|
|
53023
53682
|
}
|
|
53024
53683
|
]
|
|
53025
53684
|
},
|
|
53685
|
+
{
|
|
53686
|
+
"component": "TableCanvas",
|
|
53687
|
+
"feature": "Borders",
|
|
53688
|
+
"legacy": false,
|
|
53689
|
+
"summary": "*tableConfig.borders**",
|
|
53690
|
+
"docs": "# Borders (TableCanvas)\n\n**tableConfig.borders**\n\nУправление линиями сетки таблицы: их включение и выключение.\n\nНастраивается на четырёх уровнях, от общего к точечному. Каждый следующий уровень\nсильнее предыдущего: настройка ячейки важнее настройки колонки и строки, а те\nважнее общих настроек.\n\n## Уровни\n\n- **вся таблица** — `borders.vertical` и `borders.horizontal`: убрать все\n вертикальные или все горизонтальные линии тела (по умолчанию линии есть);\n- **колонка** — `borders.getVerticalBorder`: вернуть для колонки `true` или\n `false`, чтобы переопределить общую настройку вертикалей, или `undefined`,\n чтобы оставить её (например, убрать разделитель справа от одной колонки);\n- **строка** — `borders.getHorizontalBorder`: вернуть для строки `true` или\n `false`, чтобы переопределить общую настройку горизонталей, или `undefined`,\n чтобы оставить её;\n- **ячейка** — `borders.getCellBorder`: включить или выключить каждую из\n четырёх сторон рамки ячейки; для ячеек без переопределений вернуть `undefined`.\n\n## Точечные колбэки\n\n`getHorizontalBorder` и `getCellBorder` получают саму строку (`row`), её индекс\n(`rowIndex`) и уровень вложенности subRows (`treeLvl`, где `0` это корень). При\nраскрытии дерева индексы строк сдвигаются, поэтому настройку удобно привязывать к\nстроке или к уровню, а не к номеру. Для summary-строк колбэки не вызываются.\n\nТипичные сценарии:\n\n- выключить все линии и точечно дорисовать нужные (например, только контур\n объединённого блока);\n- оставить горизонтали, но не рисовать их внутри раскрытых subRows\n (`treeLvl > 0` вернуть `false`), чтобы родитель с детьми выглядел цельным.\n\n## Объединённые ячейки\n\nВнутрь объединённого блока линии не рисуются никогда: остаётся только внешний\nконтур. Чтобы оформить рамку блока, задавайте стороны у его крайних ячеек через\n`getCellBorder` — внутренние рамки всё равно отсекаются.\n\n## Итоговые (summary) строки\n\nНастройки вертикали действуют и на итоговую строку: разделители колонок проходят\nчерез неё насквозь, а `getVerticalBorder` убирает разделитель у выбранной колонки\nи в теле, и в итоге.\n\nТочечные горизонтали (`getHorizontalBorder`) и рамки отдельных ячеек\n(`getCellBorder`) в итоговых строках пока не поддержаны: на их линии влияют только\nпо-колоночная вертикаль и общие настройки. Полное управление линиями внутри\nитоговых строк появится позже.\n\n> Подробнее о типах — [Borders API](?path=/docs/локальные-компоненты-tablecanvas-borders-api--docs)",
|
|
53691
|
+
"apiDocs": "# Borders API\n\n## tableConfig.borders\n\n```typescript\ntype BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n```\n\n## CellBorderVisibility\n\nСтороны рамки одной ячейки, которые возвращает `getCellBorder`. Для каждой\nстороны:\n\n- `true` — рисовать линию;\n- `false` — не рисовать линию;\n- поле не задано — сторона берётся с уровня ниже (настройка колонки, строки или\n общая).\n\n```typescript\ntype CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n```\n\n## borders.getVerticalBorder\n\nТочечная вертикальная линия справа от колонки. Колбэк получает `columnKey` и\n`columnIndex` (в порядке отрисовки, закреплённые в начале) и возвращает `true`\nили `false`, чтобы переопределить общую настройку `borders.vertical`, или\n`undefined`, чтобы оставить её.\n\nКолбэк зовётся на каждую видимую колонку при каждой перерисовке, поэтому должен\nбыть быстрым. Если условие зависит от набора колонок, держите этот набор в `Set`\nзаранее (вне колбэка) и проверяйте через `has` — так проверка остаётся дешёвой\nи не растёт с числом колонок:\n\n```tsx\nconst COLUMNS_WITHOUT_RIGHT_BORDER = new Set(['priority', 'issueType']);\n\nborders={{\n getVerticalBorder: ({ columnKey }) =>\n COLUMNS_WITHOUT_RIGHT_BORDER.has(columnKey) ? false : undefined,\n}}\n```\n\nТот же приём подходит и для `getHorizontalBorder` и `getCellBorder`: тяжёлые\nвычисления и наборы данных готовьте заранее, а в колбэке оставляйте только\nбыструю проверку.",
|
|
53692
|
+
"api": [
|
|
53693
|
+
{
|
|
53694
|
+
"typeName": "BordersConfig",
|
|
53695
|
+
"source": "type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};"
|
|
53696
|
+
},
|
|
53697
|
+
{
|
|
53698
|
+
"typeName": "CellBorderVisibility",
|
|
53699
|
+
"source": "type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};"
|
|
53700
|
+
}
|
|
53701
|
+
],
|
|
53702
|
+
"stories": [
|
|
53703
|
+
{
|
|
53704
|
+
"exportName": "NoVerticalLines",
|
|
53705
|
+
"displayName": "NoVerticalLines",
|
|
53706
|
+
"type": "full-code",
|
|
53707
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n tableConfig={{ borders: { vertical: false } }}\n columnConfig={COLS}\n rows={rows}\n/>"
|
|
53708
|
+
},
|
|
53709
|
+
{
|
|
53710
|
+
"exportName": "HideColumnBorder",
|
|
53711
|
+
"displayName": "HideColumnBorder",
|
|
53712
|
+
"type": "full-code",
|
|
53713
|
+
"code": "import { useMemo } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst columnsWithoutRightBorder = useMemo(\n () => new Set(['priority', 'issueType']),\n [],\n);\n\n<TableCanvas\n tableConfig={{\n borders: {\n getVerticalBorder: ({ columnKey }) =>\n columnsWithoutRightBorder.has(columnKey) ? false : undefined,\n },\n }}\n columnConfig={COLS}\n rows={rows}\n/>"
|
|
53714
|
+
},
|
|
53715
|
+
{
|
|
53716
|
+
"exportName": "NoHorizontalLines",
|
|
53717
|
+
"displayName": "NoHorizontalLines",
|
|
53718
|
+
"type": "full-code",
|
|
53719
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n tableConfig={{ borders: { horizontal: false } }}\n columnConfig={COLS}\n rows={rows}\n/>"
|
|
53720
|
+
},
|
|
53721
|
+
{
|
|
53722
|
+
"exportName": "PerCellBorders",
|
|
53723
|
+
"displayName": "PerCellBorders",
|
|
53724
|
+
"type": "full-code",
|
|
53725
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst BOTTOM_ON = { bottom: true } as const;\n\n<TableCanvas\n tableConfig={{\n borders: {\n horizontal: false,\n getCellBorder: ({ columnKey, row }) =>\n columnKey === 'complete' && row.complete >= 50 ? BOTTOM_ON : undefined,\n },\n }}\n columnConfig={COLS}\n rows={rows}\n/>"
|
|
53726
|
+
},
|
|
53727
|
+
{
|
|
53728
|
+
"exportName": "SubRowsWithoutInnerLines",
|
|
53729
|
+
"displayName": "Title",
|
|
53730
|
+
"type": "full-code",
|
|
53731
|
+
"code": "() => {\n const [rows] = useState(createRows);\n const cols: readonly ColumnConfig<Row>[] = [\n {\n key: 'task',\n name: 'Title',\n width: 220,\n subRow: { keyOfColumnInSubRow: 'task', isColumnWithArrow: true },\n },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n ];\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n subRows: {\n getSubRows: (row) => row.subRows,\n rowKeyGetter: (row) => row.id,\n },\n borders: {\n vertical: false,\n getHorizontalBorder: ({ treeLvl }) =>\n treeLvl > 0 ? false : undefined,\n },\n }}\n columnConfig={cols}\n rows={rows}\n />\n );\n }"
|
|
53732
|
+
},
|
|
53733
|
+
{
|
|
53734
|
+
"exportName": "MillionRows",
|
|
53735
|
+
"displayName": "Строк",
|
|
53736
|
+
"type": "full-code",
|
|
53737
|
+
"code": "({\n rowsCount,\n colsCount,\n perCell,\n }: {\n rowsCount: number;\n colsCount: number;\n perCell: boolean;\n }) => {\n const rows = useMemo(() => makeLeanRows(rowsCount), [rowsCount]);\n const columnConfig = useMemo(() => makeManyCols(colsCount), [colsCount]);\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 480 },\n rowMarkers: { startIndex: 1 },\n borders: perCell\n ? {\n horizontal: false,\n getCellBorder: ({ columnKey, row, rowIndex }) => {\n if (rowIndex % 10 === 9) return BOTTOM_ON;\n if (columnKey !== 'complete') return undefined;\n return row.complete >= 50 ? BOTTOM_ON : undefined;\n },\n }\n : { vertical: false },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
53738
|
+
},
|
|
53739
|
+
{
|
|
53740
|
+
"exportName": "WithMergedCells",
|
|
53741
|
+
"displayName": "Регион",
|
|
53742
|
+
"type": "full-code",
|
|
53743
|
+
"code": "() => {\n const [rows] = useState(makeMergeRows);\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n mergeCells: { mergeByCellValues: ['region', 'dept'] },\n hoverEffects: { row: true },\n cellsSelection: { mode: 'range-cell' },\n borders: {\n vertical: false,\n horizontal: false,\n getCellBorder: ({ columnKey, row }) => {\n if (columnKey === 'region' || columnKey === 'dept') {\n return FRAME_ON;\n }\n if (columnKey === 'metric') {\n return row.metric >= 50 ? SIDES_WITH_BOTTOM : SIDES_ON;\n }\n if (columnKey === 'status') {\n return SIDES_ON;\n }\n return undefined;\n },\n },\n }}\n columnConfig={MERGE_COLS}\n rows={rows}\n />\n );\n }"
|
|
53744
|
+
},
|
|
53745
|
+
{
|
|
53746
|
+
"exportName": "SummaryVerticalBorders",
|
|
53747
|
+
"displayName": "ID",
|
|
53748
|
+
"type": "full-code",
|
|
53749
|
+
"code": "() => {\n const [rows] = useState(createRows);\n const avgComplete = useMemo(\n () =>\n Math.round(rows.reduce((sum, r) => sum + r.complete, 0) / rows.length),\n [rows],\n );\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n summaryRows: { showDefault: true, showInControl: false },\n borders: {\n getVerticalBorder: ({ columnKey }) =>\n columnKey === 'priority' ? false : undefined,\n },\n }}\n columnConfig={SUMMARY_COLS}\n rows={rows}\n bottomSummaryRows={[avgComplete]}\n />\n );\n }"
|
|
53750
|
+
}
|
|
53751
|
+
]
|
|
53752
|
+
},
|
|
53026
53753
|
{
|
|
53027
53754
|
"component": "TableCanvas",
|
|
53028
53755
|
"feature": "FullScreenMode",
|
|
@@ -53090,6 +53817,34 @@
|
|
|
53090
53817
|
}
|
|
53091
53818
|
]
|
|
53092
53819
|
},
|
|
53820
|
+
{
|
|
53821
|
+
"component": "TableCanvas",
|
|
53822
|
+
"feature": "HoverEffects",
|
|
53823
|
+
"legacy": false,
|
|
53824
|
+
"summary": "Эффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.",
|
|
53825
|
+
"docs": "# Hover Effects\n\nЭффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.\nСейчас поддерживается **подсветка строки под курсором** (`row`). Чисто визуальная фича, по умолчанию\n**выключена**. В будущем в этом же объекте появятся hover по ячейке и т.д.\n\n## Как включить\n\n```tsx\ntableConfig={{ hoverEffects: { row: true } }} // цвета из темы\n```\n\n## Цвета (уровень темы)\n\n- **data-ячейки** hovered-строки — серый `bgRowHovered`;\n- **служебные колонки** (нумерация / чекбокс / инструменты строк) hovered-строки\n не сереют — темнеют голубым `bgServiceRowHovered`, тем же цветом, что\n сервис-зона при селектинге;\n- строка, **отмеченная чекбоксом** (`selecting`), под курсором темнеет целиком —\n `bgSelectedRowHovered` (как hover шапки), вместо серого.\n\n## Приоритеты слоёв (важно)\n\nHover — **самый нижний визуальный слой**, он не конкурирует с выделением:\n\n- выделение ячеек/строк/колонок (`cellsSelection`) и «залипшая» активная строка\n (`highlightActiveType='row'`) рисуются **поверх** и перекрывают hover;\n- после сброса выделения hover под курсором снова виден;\n- summary-строки hover не получают.\n\n## Особенности\n\n- Работает по всей строке: hover срабатывает над любой ячейкой строки,\n включая нумерацию и чекбокс.\n- Уход мыши с таблицы (или на шапку/групп-хедер) сбрасывает подсветку.\n- Не требует `themeOverride` и не влияет на copy/paste и прочую логику\n выделения — ось полностью независимая. Не путать с `highlightActiveType` —\n тот подсвечивает строку по **клику** («залипает»), hover — по наведению.\n\n> Подробнее о типах — [HoverEffects API](?path=/docs/локальные-компоненты-tablecanvas-hovereffects-api--docs)\n\n> Внутреннее устройство и почему такие приоритеты — в доке\n> `packages/ui-kit/src/components/TableCanvas/docs/SelectionAndHighlighting.md`,\n> раздел 7.",
|
|
53826
|
+
"apiDocs": "# HoverEffects API\n\n## HoverEffectsConfig\n\n`tableConfig.hoverEffects` — единый конфиг эффектов при наведении. Значения,\nцвета по зонам строки и приоритет слоёв описаны в комментариях к типу.\n\n```typescript\ntype HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};\n```",
|
|
53827
|
+
"api": [
|
|
53828
|
+
{
|
|
53829
|
+
"typeName": "HoverEffectsConfig",
|
|
53830
|
+
"source": "type HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};"
|
|
53831
|
+
}
|
|
53832
|
+
],
|
|
53833
|
+
"stories": [
|
|
53834
|
+
{
|
|
53835
|
+
"exportName": "HoverEffectsPlayground",
|
|
53836
|
+
"displayName": "HoverEffectsPlayground",
|
|
53837
|
+
"type": "full-code",
|
|
53838
|
+
"code": "import { useMemo, useState } from 'react';\nimport { Select } from '@daisforge/ui/components/Select';\nimport {\n type CellsSelectionMode,\n type ColumnConfig,\n type HighlightActiveType,\n type HoverEffectsConfig,\n TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Варианты значения tableConfig.hoverEffects для селекта.\ntype HoverEffectsOption = 'disabled' | 'row';\n\nconst HOVER_EFFECTS_OPTIONS: readonly HoverEffectsOption[] = ['row', 'disabled'];\n\n// Каждый вариант это готовое значение tableConfig.hoverEffects.\nconst HOVER_EFFECTS_BY_OPTION: Record<HoverEffectsOption, HoverEffectsConfig> = {\n disabled: {},\n row: { row: true },\n};\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: readonly HighlightActiveType[] = [\n 'row',\n 'disabled',\n];\n\nconst SELECTION_MODE_OPTIONS: readonly CellsSelectionMode[] = [\n 'range-cell',\n 'multi-range-cell',\n 'cell',\n 'disabled',\n];\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 90 },\n { key: 'task', name: 'Title', width: 260 },\n { key: 'priority', name: 'Priority', width: 180 },\n { key: 'issueType', name: 'Issue Type', width: 180 },\n { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n const [hoverOption, setHoverOption] = useState<HoverEffectsOption>('row');\n const [highlightActiveType, setHighlightActiveType] =\n useState<HighlightActiveType>('row');\n const [selectionMode, setSelectionMode] =\n useState<CellsSelectionMode>('range-cell');\n const [rows] = useState(createRows);\n\n const selectingStateAndSetter = useState<ReadonlySet<string | number>>(\n () =>\n new Set(\n rows\n .filter((row) => [3, 5].includes(Number(row.id)))\n .map(getRowSelectionKey),\n ),\n );\n\n const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n () => COLUMN_CONFIG,\n [],\n );\n\n return (\n <>\n <div\n style={{ display: 'grid', gap: 12, maxWidth: 420, marginBottom: 16 }}\n >\n <div>\n hoverEffects (эффекты при наведении)\n <Select\n value={hoverOption}\n onChange={(value) => setHoverOption(value as HoverEffectsOption)}\n items={HOVER_EFFECTS_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n\n <div>\n highlightActiveType (залипшая активная строка)\n <Select\n value={highlightActiveType}\n onChange={(value) =>\n setHighlightActiveType(value as HighlightActiveType)\n }\n items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n\n <div>\n cellsSelection.mode (режим выделения)\n <Select\n value={selectionMode}\n onChange={(value) =>\n setSelectionMode(value as CellsSelectionMode)\n }\n items={SELECTION_MODE_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n </div>\n\n <StoryHint>\n Водите мышью по строкам — data-ячейки подсвечиваются серым, служебные\n колонки (нумерация/чекбокс) — голубым, как при селектинге.\n Checkbox-строки (3 и 5) под курсором темнеют целиком. Клик по строке\n (активная строка / выделение) рисуется <b>поверх</b> hover-подсветки и\n перекрывает её; после сброса выделения hover снова виден.\n </StoryHint>\n\n <TableCanvas\n key={[hoverOption, highlightActiveType, selectionMode].join('-')}\n tableConfig={{\n containerStyle: { height: '700px', maxWidth: 980 },\n hoverEffects: HOVER_EFFECTS_BY_OPTION[hoverOption],\n highlightActiveType,\n cellsSelection: { mode: selectionMode },\n rowMarkers: { startIndex: 1 },\n selecting: {\n state: selectingStateAndSetter,\n rowKeyGetter: getRowSelectionKey,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </>\n );\n }"
|
|
53839
|
+
},
|
|
53840
|
+
{
|
|
53841
|
+
"exportName": "HoverEffectsRowSimple",
|
|
53842
|
+
"displayName": "Минимальное включение",
|
|
53843
|
+
"type": "full-code",
|
|
53844
|
+
"code": "import {\n type CellsSelectionMode,\n type ColumnConfig,\n type HighlightActiveType,\n type HoverEffectsConfig,\n TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 90 },\n { key: 'task', name: 'Title', width: 260 },\n { key: 'priority', name: 'Priority', width: 180 },\n { key: 'issueType', name: 'Issue Type', width: 180 },\n { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n const [rows] = useState(createRows);\n const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n () => COLUMN_CONFIG,\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '600px' },\n hoverEffects: { row: true },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
53845
|
+
}
|
|
53846
|
+
]
|
|
53847
|
+
},
|
|
53093
53848
|
{
|
|
53094
53849
|
"component": "TableCanvas",
|
|
53095
53850
|
"feature": "InfinityScroll",
|
|
@@ -53653,7 +54408,7 @@
|
|
|
53653
54408
|
"exportName": "SubRows",
|
|
53654
54409
|
"displayName": "Иерархичный вид",
|
|
53655
54410
|
"type": "full-code",
|
|
53656
|
-
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(() =>
|
|
54411
|
+
"code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n // Разная глубина и число детей у строк — «рваная лестница» отступов\n const [rows] = useState(() => createRaggedRowsTree());\n\n const columns = useMemo(\n (): readonly ColumnConfig<TreeRow>[] => [\n {\n key: 'block',\n name: 'Блок / Трайб / Продукт',\n\n subRow: {\n keyOfColumnInSubRow: (lvl) => {\n switch (lvl) {\n case 0:\n return 'block';\n case 1:\n return 'tribe';\n default:\n return 'product';\n }\n },\n\n isColumnWithArrow: true,\n hideHeaderExpandAllArrow: false,\n },\n },\n {\n key: 'blockActivity',\n name: 'Активность блока',\n },\n {\n key: ' ',\n name: 'Локация трайба',\n subRow: {\n renderSubRowCell: (props, lvl) => {\n if (lvl === 1) {\n return (\n <Canvas.Container\n alignItems=\"center\"\n padding={{ left: 8 }}\n style={{ width: '100%' }}\n >\n <Canvas.Badge\n id=\"kek\"\n text={props.row?.tribeZone}\n view=\"accent\"\n size=\"m\"\n />\n </Canvas.Container>\n );\n }\n return '';\n },\n },\n },\n {\n key: 'q1',\n name: 'Q1',\n\n subRow: {\n parentKeyAsDefault: true,\n },\n },\n\n {\n key: 'q2',\n name: 'Q2',\n subRow: {\n keyOfColumnInSubRow: 'q1',\n },\n },\n {\n key: 'q3',\n name: 'Q3',\n subRow: {\n keyOfColumnInSubRow: 'q1',\n },\n },\n {\n key: 'q4',\n name: 'Q4',\n subRow: {\n keyOfColumnInSubRow: 'q1',\n },\n },\n ],\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '85vh' },\n subRows: {\n getSubRows: (row) => row?.subRows,\n rowKeyGetter: (row) => row.id,\n },\n // Отступ уровня зависит от размера строки: big 16/66/116,\n // medium 6/42/78, small 4/32/60 px\n rowSize: { showInControl: true, default: 'big' },\n fullScreenEnabled: true,\n resizableColumn: true,\n }}\n columnConfig={columns}\n rows={rows}\n />\n );\n }"
|
|
53657
54412
|
}
|
|
53658
54413
|
]
|
|
53659
54414
|
},
|
|
@@ -53684,7 +54439,7 @@
|
|
|
53684
54439
|
"feature": "ThemeOverride",
|
|
53685
54440
|
"legacy": false,
|
|
53686
54441
|
"summary": "*columnConfig.themeOverride**",
|
|
53687
|
-
"docs": "# Theme Override\n\n**columnConfig.themeOverride**\n\nПереопределение визуальных свойств ячейки на уровне колоночного конфига. Колбэк вызывается для каждой ячейки колонки и возвращает частичный override темы (`Partial<Theme>`), либо `undefined`, если для ячейки переопределение не нужно.\n\n## Ключевые особенности\n\n- `bgCell` — цвет фона ячейки (рисуется нативно, закрашивает всю площадь ячейки, включая паддинги)\n- `cellHorizontalPadding` — горизонтальные отступы контента ячейки\n- `cellVerticalPadding` — вертикальные отступы контента ячейки\n- Колбэк получает `cellInfo` (row, column, ctxs, theme) и `lvl` — уровень вложенности subRow (0 для корневых строк, 1+ для дочерних)\n- Условное поведение: можно менять стили в зависимости от данных строки или уровня вложенности\n\n## Сигнатура\n\n```ts\nthemeOverride?: (\n cellInfo: CellInfo<Row, SummRow, CustomCtxs>,\n lvl: number\n) => CellThemeOverrideResult | undefined;\n```\n\n## Особенности\n\n### Обычные колонки\n\nДля колонок без `subRow.isColumnWithArrow` `cellHorizontalPadding` через `themeOverride` применяется напрямую и одинаково на всех уровнях вложенности (root и subRows). Левый и правый паддинги получают точное значение из override.\n\n### Tree-колонки (с шевроном раскрытия)\n\nДля колонок с `subRow.isColumnWithArrow: true` левый край ячейки рассчитывается формулой `
|
|
54442
|
+
"docs": "# Theme Override\n\n**columnConfig.themeOverride**\n\nПереопределение визуальных свойств ячейки на уровне колоночного конфига. Колбэк вызывается для каждой ячейки колонки и возвращает частичный override темы (`Partial<Theme>`), либо `undefined`, если для ячейки переопределение не нужно.\n\n## Ключевые особенности\n\n- `bgCell` — цвет фона ячейки (рисуется нативно, закрашивает всю площадь ячейки, включая паддинги)\n- `cellHorizontalPadding` — горизонтальные отступы контента ячейки\n- `cellVerticalPadding` — вертикальные отступы контента ячейки\n- Колбэк получает `cellInfo` (row, column, ctxs, theme) и `lvl` — уровень вложенности subRow (0 для корневых строк, 1+ для дочерних)\n- Условное поведение: можно менять стили в зависимости от данных строки или уровня вложенности\n\n## Сигнатура\n\n```ts\nthemeOverride?: (\n cellInfo: CellInfo<Row, SummRow, CustomCtxs>,\n lvl: number\n) => CellThemeOverrideResult | undefined;\n```\n\n## Особенности\n\n### Обычные колонки\n\nДля колонок без `subRow.isColumnWithArrow` `cellHorizontalPadding` через `themeOverride` применяется напрямую и одинаково на всех уровнях вложенности (root и subRows). Левый и правый паддинги получают точное значение из override.\n\n### Tree-колонки (с шевроном раскрытия)\n\nДля колонок с `subRow.isColumnWithArrow: true` левый край ячейки рассчитывается формулой `cellHorizontalPadding + step * lvl`, где шаг зависит от размера строки: `big` — 50 (16 → 66 → 116 → 166 px), `medium` — 36 (6 → 42 → 78 → 114 px), `small` — 28 (4 → 32 → 60 → 88 px). Отступ зависит только от уровня вложенности и не зависит от наличия шеврона, поэтому текст дочерней строки всегда правее текста родителя. Шеврон рисуется иконкой без пустого места слева: раскрытый `∨` начинается ровно на линии уровня (там же, где текст соседнего листа), у свёрнутого `>` небольшой отступ, чтобы при раскрытии не было скачка. Справа от шеврона места столько же, сколько у исходной иконки, поэтому расстояние до текста прежнее. Двойной шеврон в шапке (`раскрыть/скрыть все строки`) построен так же и стоит на линии свёрнутого шеврона строки, а заголовок колонки — над текстом строк верхнего уровня. Override влияет на левый край, но итоговое значение `= override + offsets`, а не ровно значение override. Правый край и `bgCell` для tree-колонок работают как обычно.\n\n### Кастомный renderCell\n\nДля колонок с `renderCell` системная обёртка с паддингом не добавляется. Разработчик сам управляет отступами через `theme.cellHorizontalPadding` внутри своего renderCell.\n\n### bgCell\n\n`bgCell` рисуется нативно на уровне самой таблицы. Фон закрашивает всю ячейку целиком, включая области паддингов и любых обёрток.\n\n## См. также\n\n- `getRowThemeOverride` — нативный API таблицы для переопределения темы **строки целиком** (по индексу строки, без cellInfo). Используется для подсветки summary-строк и selected-строк. Если нужен row-level эффект (например, \"выделенная строка целиком\") — используйте этот механизм, а не `themeOverride` на каждой ячейке.\n\n> Подробнее о типах — [Theme Override API](?path=/docs/локальные-компоненты-tablecanvas-themeoverride-api--docs)",
|
|
53688
54443
|
"apiDocs": "# Theme Override API\n\nПереопределение темы настраивается через свойство `themeOverride` в `columnConfig`.\n\nЯвляется частью `ColumnConfig`.\n\n## CellThemeOverrideResult\n\n```typescript\ntype CellThemeOverrideResult = Partial<{\n bgCell: string;\n cellHorizontalPadding: number;\n cellVerticalPadding: number;\n}>;\n```\n\n## CellInfo\n\n```typescript\ntype CellInfo<\n R extends ObjectForExtending,\n SR = unknown,\n CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n CellInfoGlideInstance<R, SR, CustomCtxs>,\n 'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n column: ColumnConfig<R, SR, CustomCtxs>;\n ctxs: CtxsType<CustomCtxs>;\n /**\n * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n */\n hovered: CellHoverState;\n /**\n * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n */\n active: CellActiveState;\n};\n```",
|
|
53689
54444
|
"api": [
|
|
53690
54445
|
{
|
|
@@ -53734,8 +54489,8 @@
|
|
|
53734
54489
|
"feature": "Tooltip",
|
|
53735
54490
|
"legacy": false,
|
|
53736
54491
|
"summary": "*tableConfig.tooltip + columnConfig.cellTooltip / headerCellTooltip**",
|
|
53737
|
-
"docs": "# Tooltip на канвасной таблице\n\n**tableConfig.tooltip + columnConfig.cellTooltip / headerCellTooltip**\n\nОдин общий тултип для элементов, отрисованных на канвасе (ячейки, заголовки, кнопки и т.д.). Тултип показывается при наведении на те канвас-элементы, которые явно участвуют в механике тултипа.\n\n## Принцип работы\n\n- На таблице работает **один тултип**: при наведении на разные элементы отображается один и тот же тултип-оверлей с нужным текстом/пропсами для текущего элемента.\n- Участие элемента в показе тултипа задаётся через проп **`portalHoverEnabled`** на Canvas-примитиве — без этого пропса наведение на элемент не будет передаваться в подсистему тултипа.\n\n## Три источника конфига (по приоритету)\n\n1. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. Строка или объект с `text`. Самый высокий приоритет. **Работает всегда.**\n2. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — конфиг на уровне колонки. Может быть строкой, объектом или функцией `(context) => config | null`. Для ячеек используется `cellTooltip`, для заголовков — `headerCellTooltip`. **Требует `tooltip.enabled: true` в `tableConfig`.**\n3. **Встроенный маппинг по `nodeId`** — внутренний словарь (например, иконка drag в заголовке → «Перетащить колонку»). **Работает всегда.**\n\n## Как включить тултип на элементе\n\n### Через `tooltip` на Canvas-примитиве\n\nВ `renderCell` / `renderHeaderCell` задать `portalHoverEnabled` и `tooltip` на нужном элементе:\n\n```tsx\nrenderCell: () => (\n <Canvas.Button\n portalHoverEnabled\n tooltip=\"Нажмите для перехода\"\n onClick={() => {}}\n >\n Подробнее\n </Canvas.Button>\n);\n```\n\n### Авто-тултип для обрезанного текста (`autoTooltip` на `Canvas.Text`)\n\nЧастный случай node-тултипа: `Canvas.Text` с пропом `autoTooltip` показывает тултип с полным текстом **только когда текст реально обрезан в многоточие** (однострочный ellipsis или многострочный clamp). `portalHoverEnabled` включается автоматически, `tooltip.enabled: true` в `tableConfig` не требуется — работает всегда, как и остальные node-тултипы.\n\n```tsx\nrenderCell: ({ row }) => (\n <Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip\n style={{ flexGrow: 1 }}\n >\n {row.longText}\n </Canvas.Text>\n);\n```\n\nПоведение настраивается объектом: `placement`, `view`, `mouseEnterDelay` / `mouseLeaveDelay`, трансформация текста через `text`, выключение через `enabled: false`. Подробности и правила — в [доке Canvas.Text](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvastext--docs), тип — `CanvasTextAutoTooltip`.\n\n> Действует только на `Canvas.Text` в canvas-разметке (`renderCell` / `renderHeaderCell`). Обычные текстовые ячейки (примитивные значения без `renderCell`) рисуются встроенным text-рендерером glide — авто-тултип на них пока не распространяется.\n\n### Через `cellTooltip` / `headerCellTooltip` в `columnConfig`\n\nЗадать на уровне колонки — строкой, объектом или функцией. Не забудьте включить `tooltip.enabled: true`:\n\n```tsx\ntableConfig={{\n tooltip: { enabled: true },\n}}\ncolumnConfig={[\n {\n key: 'task',\n name: 'Title',\n headerCellTooltip: 'Название задачи',\n cellTooltip: ({ row }) => `Задача: ${row.task}`,\n },\n]}\n```\n\n## Формат конфига\n\n- **Строка** — используется как текст тултипа с дефолтными пропсами.\n- **Объект** `{ text: string, placement?, view?, mouseEnterDelay?, ... }` — текст и кастомные пропсы для `Tooltip`.\n- **`null`** — тултип для этого элемента не показывается (переход к следующему приоритету или без тултипа).\n\nПодробное описание типов и контракта — в разделе [API](/docs/локальные-компоненты-tablecanvas-tooltip-api--docs).",
|
|
53738
|
-
"apiDocs": "# Tooltip API\n\n## Источники конфига тултипа\n\nТултип может быть задан на **трёх уровнях** (проверяются по приоритету, первый непустой побеждает):\n\n1. **Встроенный маппинг по `nodeId`** — внутренний словарь `TOOLTIP_TEXTS` (например, `HEADER_TOOLTIP_DRAG_ID` → «Перетащить колонку»). **Работает всегда.** Наивысший приоритет — колоночный конфиг не может перебить внутренние тултипы UI таблицы.\n2. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. внутри `renderCell` / `renderHeaderCell`. Тип: `CanvasNodeTooltipConfig`. **Работает всегда.**\n3. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — на уровне конфигурации колонки. Может быть строкой, объектом или функцией `(context) => config | null`. **Работает только при `tooltip.enabled: true`.**\n\n**Формат конфига:** строка (только текст) или объект с обязательным полем `text` и опциональными пропсами `Tooltip` (`placement`, `view` и т.д.; без `opened`, `target`, `style`), а также `mouseEnterDelay` / `mouseLeaveDelay` для per-node задержек.\n\nПо умолчанию текст рендерится с `white-space: normal` — переносы строк (`\\n`) в `text` схлопываются в пробел. Чтобы сохранить переносы (например, в многострочных подсказках), добавьте в объектную форму конфига `preserveLineBreaks: true` — тогда к тексту тултипа применится `white-space: pre-line`. Флаг выключен по умолчанию и не меняет поведение существующих строковых тултипов.\n\n## Модуль tableConfig.tooltip\n\nГлобальные настройки тултипа вынесены в `tableConfig.tooltip` (тип `TableConfigTooltip`):\n\n- **tooltip.enabled** — включает колоночные/кастомные тултипы (`cellTooltip`, `headerCellTooltip`). По умолчанию `false`. Внутренние тултипы (проп `tooltip` на Canvas-элементе и маппинг по `nodeId`) работают всегда, независимо от `enabled`.\n- **tooltip.mouseEnterDelay** — глобальная задержка перед показом (мс, по умолчанию `500`). Per-node переопределяет.\n- **tooltip.mouseLeaveDelay** — глобальная задержка перед скрытием (мс, по умолчанию `0`). Per-node переопределяет.\n\nПример:\n\n```tsx\ntableConfig={{\n tooltip: {\n enabled: true,\n mouseEnterDelay: 300,\n },\n}}\n```\n\n## Колоночные cellTooltip / headerCellTooltip\n\nЗадаются в `columnConfig` на уровне колонки. Значение — строка, объект или функция. Требуют `tooltip.enabled: true` в `tableConfig`:\n\n```tsx\nconst columnConfig = [\n {\n key: 'task',\n name: 'Title',\n // Строка — простой текст\n headerCellTooltip: 'Название задачи',\n // Функция — динамический конфиг\n cellTooltip: ({ row, column }) => {\n return `${column.name}: ${row.task}`;\n },\n },\n];\n```\n\nКонтекст функции `cellTooltip` содержит: `row`, `column`, `ctxs`, `refTable`, `colInd`, `rowInd`, `theme`.\nКонтекст функции `headerCellTooltip` содержит: `column`, `ctxs`, `refTable`, `colInd`, `theme`.\n\n---\n\n## Типы\n\n### CanvasNodeTooltipConfig\n\nПроп `tooltip` на Canvas-элементах и базовый формат конфига. Строка (текст) или объект с `text` и опциональными пропсами Tooltip.\n\n```typescript\ntype CanvasNodeTooltipConfig =\n | string\n | (CanvasNodeTooltipProps & {\n /** Текст тултипа (только string, не ReactNode). */\n text: string;\n /** Задержка перед показом (мс). По умолчанию 0. */\n mouseEnterDelay?: number;\n /** Задержка перед скрытием после ухода мыши (мс). По умолчанию 0. */\n mouseLeaveDelay?: number;\n });\n```\n\n### CanvasNodeTooltipProps\n\nПропсы Tooltip, которые можно задать через объектную форму конфига. Управляемые внутренне поля (`opened`, `target`, `style`, `text`, `mouseEnterDelay`, `mouseLeaveDelay`, `hoverTimeout`, `trigger`) исключены.\n\n```typescript\ntype CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n};\n```\n\n### TooltipConfigResult\n\nАлиас: `CanvasNodeTooltipConfig | null`. Используется как возвращаемый тип функциональной формы `cellTooltip` / `headerCellTooltip`.\n\n```typescript\ntype TooltipConfigResult = CanvasNodeTooltipConfig | null;\n```\n\n### TooltipData\n\nВнутренний результат резолвинга: текст, пропсы тултипа и per-node задержки. Возвращается из `resolveTooltipData` и передаётся в `usePortalHover`.\n\n```typescript\ninterface TooltipData {\n tooltipText: string;\n tooltipProps?: CanvasNodeTooltipProps;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n}\n```\n\n### TableConfigTooltip\n\nГлобальные настройки тултипа в `tableConfig.tooltip`.\n\n```typescript\ntype TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n};\n```\n\n### CanvasPortalHoverDetail\n\nОбъект события hover по canvas-элементу. Содержит координаты, размеры, `nodeId`, `source` (`'header'` | `'cell'`), `tooltipFromNode` и `tooltipContext` (column, row, ctxs, refTable).\n\n```typescript\ninterface CanvasPortalHoverDetail<\n TContext extends TooltipContextShape = TooltipContextShape\n> {\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n node?: CanvasNode | null;\n nodeId?: string;\n source?: CanvasPortalSource;\n originId?: string;\n /** column, row, ctxs, refTable — тип задаётся generic TContext */\n tooltipContext?: TContext;\n /** Конфиг с ноды (проп tooltip на Canvas-элементе). */\n tooltipFromNode?: CanvasNodeTooltipConfig;\n /**\n * Приоритет события. usePortalHover не заменяет активный тултип с бо́льшим приоритетом.\n * - 1 — canvas-нода (CanvasHoverController)\n * - 0 — колоночный тултип (useItemHoveredHandler)\n * @default 0\n */\n priority?: number;\n}\n```",
|
|
54492
|
+
"docs": "# Tooltip на канвасной таблице\n\n**tableConfig.tooltip + columnConfig.cellTooltip / headerCellTooltip**\n\nОдин общий тултип для элементов, отрисованных на канвасе (ячейки, заголовки, кнопки и т.д.). Тултип показывается при наведении на те канвас-элементы, которые явно участвуют в механике тултипа.\n\n## Принцип работы\n\n- На таблице работает **один тултип**: при наведении на разные элементы отображается один и тот же тултип-оверлей с нужным текстом/пропсами для текущего элемента.\n- Участие элемента в показе тултипа задаётся через проп **`portalHoverEnabled`** на Canvas-примитиве — без этого пропса наведение на элемент не будет передаваться в подсистему тултипа.\n\n## Три источника конфига (по приоритету)\n\n1. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. Строка или объект с `text`. Самый высокий приоритет. **Работает всегда.**\n2. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — конфиг на уровне колонки. Может быть строкой, объектом или функцией `(context) => config | null`. Для ячеек используется `cellTooltip`, для заголовков — `headerCellTooltip`. **Требует `tooltip.enabled: true` в `tableConfig`.**\n3. **Встроенный маппинг по `nodeId`** — внутренний словарь (например, иконка drag в заголовке → «Перетащить колонку»). **Работает всегда.**\n\n## Как включить тултип на элементе\n\n### Через `tooltip` на Canvas-примитиве\n\nВ `renderCell` / `renderHeaderCell` задать `portalHoverEnabled` и `tooltip` на нужном элементе:\n\n```tsx\nrenderCell: () => (\n <Canvas.Button\n portalHoverEnabled\n tooltip=\"Нажмите для перехода\"\n onClick={() => {}}\n >\n Подробнее\n </Canvas.Button>\n);\n```\n\n### Авто-тултип для обрезанного текста (`autoTooltip` на `Canvas.Text`)\n\nЧастный случай node-тултипа: `Canvas.Text` с пропом `autoTooltip` показывает тултип с полным текстом **только когда текст реально обрезан в многоточие** (однострочный ellipsis или многострочный clamp). `portalHoverEnabled` включается автоматически, `tooltip.enabled: true` в `tableConfig` не требуется — работает всегда, как и остальные node-тултипы.\n\n```tsx\nrenderCell: ({ row }) => (\n <Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip\n style={{ flexGrow: 1 }}\n >\n {row.longText}\n </Canvas.Text>\n);\n```\n\nПоведение настраивается объектом: `placement`, `view`, `mouseEnterDelay` / `mouseLeaveDelay`, трансформация текста через `text`, выключение через `enabled: false`. Подробности и правила — в [доке Canvas.Text](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvastext--docs), тип — `CanvasTextAutoTooltip`.\n\n> Действует только на `Canvas.Text` в canvas-разметке (`renderCell` / `renderHeaderCell`). Обычные текстовые ячейки (примитивные значения без `renderCell`) рисуются встроенным text-рендерером glide — авто-тултип на них пока не распространяется.\n\n### Через `cellTooltip` / `headerCellTooltip` в `columnConfig`\n\nЗадать на уровне колонки — строкой, объектом или функцией. Не забудьте включить `tooltip.enabled: true`:\n\n```tsx\ntableConfig={{\n tooltip: { enabled: true },\n}}\ncolumnConfig={[\n {\n key: 'task',\n name: 'Title',\n headerCellTooltip: 'Название задачи',\n cellTooltip: ({ row }) => `Задача: ${row.task}`,\n },\n]}\n```\n\n## Ширина тултипа\n\nШирину тултипа можно задать глобально для всей таблицы через `tableConfig.tooltip`:\n\n```tsx\ntableConfig={{\n tooltip: { minWidth: 120, maxWidth: 440 },\n}}\n```\n\nЭта ширина применяется ко всем canvas-тултипам, включая авто-тултип `Canvas.Text`.\n\nЧисло трактуется как пиксели. Если нужна другая единица, передайте строку: `maxWidth: '20rem'`, `maxWidth: '50%'`.\n\nПриоритет от высокого к низкому:\n\n- ширина, заданная на самом тултипе (`tooltip` или `autoTooltip` на Canvas-элементе);\n- глобальная `tableConfig.tooltip.minWidth` / `maxWidth`;\n- дефолт компонента `Tooltip`.\n\nТо есть глобальное значение работает как значение по умолчанию, а точечное на элементе его перекрывает:\n\n```tsx\n// у этого тултипа своя ширина, глобальная не применится\n<Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip={{ maxWidth: 300 }}\n>\n {row.longText}\n</Canvas.Text>\n```\n\n## Формат конфига\n\n- **Строка** — используется как текст тултипа с дефолтными пропсами.\n- **Объект** `{ text: string, placement?, view?, mouseEnterDelay?, ... }` — текст и кастомные пропсы для `Tooltip`.\n- **`null`** — тултип для этого элемента не показывается (переход к следующему приоритету или без тултипа).\n\nПодробное описание типов и контракта — в разделе [API](/docs/локальные-компоненты-tablecanvas-tooltip-api--docs).",
|
|
54493
|
+
"apiDocs": "# Tooltip API\n\n## Источники конфига тултипа\n\nТултип может быть задан на **трёх уровнях** (проверяются по приоритету, первый непустой побеждает):\n\n1. **Встроенный маппинг по `nodeId`** — внутренний словарь `TOOLTIP_TEXTS` (например, `HEADER_TOOLTIP_DRAG_ID` → «Перетащить колонку»). **Работает всегда.** Наивысший приоритет — колоночный конфиг не может перебить внутренние тултипы UI таблицы.\n2. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. внутри `renderCell` / `renderHeaderCell`. Тип: `CanvasNodeTooltipConfig`. **Работает всегда.**\n3. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — на уровне конфигурации колонки. Может быть строкой, объектом или функцией `(context) => config | null`. **Работает только при `tooltip.enabled: true`.**\n\n**Формат конфига:** строка (только текст) или объект с обязательным полем `text` и опциональными пропсами `Tooltip` (`placement`, `view` и т.д.; без `opened`, `target`, `style`), а также `mouseEnterDelay` / `mouseLeaveDelay` для per-node задержек.\n\nПо умолчанию текст рендерится с `white-space: normal` — переносы строк (`\\n`) в `text` схлопываются в пробел. Чтобы сохранить переносы (например, в многострочных подсказках), добавьте в объектную форму конфига `preserveLineBreaks: true` — тогда к тексту тултипа применится `white-space: pre-line`. Флаг выключен по умолчанию и не меняет поведение существующих строковых тултипов.\n\n## Модуль tableConfig.tooltip\n\nГлобальные настройки тултипа вынесены в `tableConfig.tooltip` (тип `TableConfigTooltip`):\n\n- **tooltip.enabled** — включает колоночные/кастомные тултипы (`cellTooltip`, `headerCellTooltip`). По умолчанию `false`. Внутренние тултипы (проп `tooltip` на Canvas-элементе и маппинг по `nodeId`) работают всегда, независимо от `enabled`.\n- **tooltip.mouseEnterDelay** — глобальная задержка перед показом (мс, по умолчанию `500`). Per-node переопределяет.\n- **tooltip.mouseLeaveDelay** — глобальная задержка перед скрытием (мс, по умолчанию `0`). Per-node переопределяет.\n- **tooltip.minWidth** — глобальная минимальная ширина тултипа (число = px, строка с единицей отдаётся как есть). Действует на все canvas-тултипы, включая авто-тултип `Canvas.Text`. Per-node переопределяет.\n- **tooltip.maxWidth** — глобальная максимальная ширина тултипа (число = px, строка с единицей отдаётся как есть). Действует на все canvas-тултипы, включая авто-тултип `Canvas.Text`. Per-node переопределяет.\n\nПример:\n\n```tsx\ntableConfig={{\n tooltip: {\n enabled: true,\n mouseEnterDelay: 300,\n maxWidth: 440,\n },\n}}\n```\n\n## Колоночные cellTooltip / headerCellTooltip\n\nЗадаются в `columnConfig` на уровне колонки. Значение — строка, объект или функция. Требуют `tooltip.enabled: true` в `tableConfig`:\n\n```tsx\nconst columnConfig = [\n {\n key: 'task',\n name: 'Title',\n // Строка — простой текст\n headerCellTooltip: 'Название задачи',\n // Функция — динамический конфиг\n cellTooltip: ({ row, column }) => {\n return `${column.name}: ${row.task}`;\n },\n },\n];\n```\n\nКонтекст функции `cellTooltip` содержит: `row`, `column`, `ctxs`, `refTable`, `colInd`, `rowInd`, `theme`.\nКонтекст функции `headerCellTooltip` содержит: `column`, `ctxs`, `refTable`, `colInd`, `theme`.\n\n---\n\n## Типы\n\n### CanvasNodeTooltipConfig\n\nПроп `tooltip` на Canvas-элементах и базовый формат конфига. Строка (текст) или объект с `text` и опциональными пропсами Tooltip.\n\n```typescript\ntype CanvasNodeTooltipConfig =\n | string\n | (CanvasNodeTooltipProps & {\n /** Текст тултипа (только string, не ReactNode). */\n text: string;\n /** Задержка перед показом (мс). По умолчанию 0. */\n mouseEnterDelay?: number;\n /** Задержка перед скрытием после ухода мыши (мс). По умолчанию 0. */\n mouseLeaveDelay?: number;\n });\n```\n\n### CanvasNodeTooltipProps\n\nПропсы Tooltip, которые можно задать через объектную форму конфига. Управляемые внутренне поля (`opened`, `target`, `style`, `text`, `mouseEnterDelay`, `mouseLeaveDelay`, `hoverTimeout`, `trigger`) исключены.\n\n```typescript\ntype CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n /**\n * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n * @default 0\n */\n offsetX?: number;\n};\n```\n\n### TooltipConfigResult\n\nАлиас: `CanvasNodeTooltipConfig | null`. Используется как возвращаемый тип функциональной формы `cellTooltip` / `headerCellTooltip`.\n\n```typescript\ntype TooltipConfigResult = CanvasNodeTooltipConfig | null;\n```\n\n### TooltipData\n\nВнутренний результат резолвинга: текст, пропсы тултипа и per-node задержки. Возвращается из `resolveTooltipData` и передаётся в `usePortalHover`.\n\n```typescript\ninterface TooltipData {\n tooltipText: string;\n tooltipProps?: CanvasNodeTooltipProps;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n}\n```\n\n### TableConfigTooltip\n\nГлобальные настройки тултипа в `tableConfig.tooltip`.\n\n```typescript\ntype TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n```\n\n### CanvasPortalHoverDetail\n\nОбъект события hover по canvas-элементу. Содержит координаты, размеры, `nodeId`, `source` (`'header'` | `'cell'`), `tooltipFromNode` и `tooltipContext` (column, row, ctxs, refTable).\n\n```typescript\ninterface CanvasPortalHoverDetail<\n TContext extends TooltipContextShape = TooltipContextShape\n> {\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n node?: CanvasNode | null;\n nodeId?: string;\n source?: CanvasPortalSource;\n originId?: string;\n /** column, row, ctxs, refTable — тип задаётся generic TContext */\n tooltipContext?: TContext;\n /** Конфиг с ноды (проп tooltip на Canvas-элементе). */\n tooltipFromNode?: CanvasNodeTooltipConfig;\n /**\n * Приоритет события. usePortalHover не заменяет активный тултип с бо́льшим приоритетом.\n * - 1 — canvas-нода (CanvasHoverController)\n * - 0 — колоночный тултип (useItemHoveredHandler)\n * @default 0\n */\n priority?: number;\n}\n```",
|
|
53739
54494
|
"api": [
|
|
53740
54495
|
{
|
|
53741
54496
|
"typeName": "CanvasNodeTooltipConfig",
|
|
@@ -53743,7 +54498,7 @@
|
|
|
53743
54498
|
},
|
|
53744
54499
|
{
|
|
53745
54500
|
"typeName": "CanvasNodeTooltipProps",
|
|
53746
|
-
"source": "type CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n};"
|
|
54501
|
+
"source": "type CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n /**\n * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n * @default 0\n */\n offsetX?: number;\n};"
|
|
53747
54502
|
},
|
|
53748
54503
|
{
|
|
53749
54504
|
"typeName": "TooltipConfigResult",
|
|
@@ -53755,7 +54510,7 @@
|
|
|
53755
54510
|
},
|
|
53756
54511
|
{
|
|
53757
54512
|
"typeName": "TableConfigTooltip",
|
|
53758
|
-
"source": "type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n};"
|
|
54513
|
+
"source": "type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};"
|
|
53759
54514
|
},
|
|
53760
54515
|
{
|
|
53761
54516
|
"typeName": "CanvasPortalHoverDetail",
|
|
@@ -53765,33 +54520,39 @@
|
|
|
53765
54520
|
"stories": [
|
|
53766
54521
|
{
|
|
53767
54522
|
"exportName": "DefaultTooltipStory",
|
|
53768
|
-
"displayName": "Встроенный тултип
|
|
54523
|
+
"displayName": "Встроенный тултип (drag-иконка в шапке)",
|
|
53769
54524
|
"type": "full-code",
|
|
53770
54525
|
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleDefaultTooltip',\n)}"
|
|
53771
54526
|
},
|
|
53772
54527
|
{
|
|
53773
54528
|
"exportName": "ColumnTooltipStringStory",
|
|
53774
|
-
"displayName": "cellTooltip
|
|
54529
|
+
"displayName": "cellTooltip: строка",
|
|
53775
54530
|
"type": "full-code",
|
|
53776
54531
|
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleColumnTooltipString',\n)}"
|
|
53777
54532
|
},
|
|
53778
54533
|
{
|
|
53779
54534
|
"exportName": "ColumnTooltipObjectStory",
|
|
53780
|
-
"displayName": "cellTooltip
|
|
54535
|
+
"displayName": "cellTooltip: объект",
|
|
53781
54536
|
"type": "full-code",
|
|
53782
54537
|
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleColumnTooltipObject',\n)}"
|
|
53783
54538
|
},
|
|
53784
54539
|
{
|
|
53785
54540
|
"exportName": "ColumnTooltipMultilineStory",
|
|
53786
|
-
"displayName": "cellTooltip
|
|
54541
|
+
"displayName": "cellTooltip: preserveLineBreaks",
|
|
53787
54542
|
"type": "full-code",
|
|
53788
54543
|
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleColumnTooltipMultiline',\n)}"
|
|
53789
54544
|
},
|
|
53790
54545
|
{
|
|
53791
54546
|
"exportName": "ButtonWithTooltipStory",
|
|
53792
|
-
"displayName": "Canvas.Button tooltip
|
|
54547
|
+
"displayName": "Canvas.Button: tooltip",
|
|
53793
54548
|
"type": "full-code",
|
|
53794
54549
|
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { Canvas, ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleButtonWithTooltip',\n)}"
|
|
54550
|
+
},
|
|
54551
|
+
{
|
|
54552
|
+
"exportName": "GlobalTooltipWidthStory",
|
|
54553
|
+
"displayName": "Ширина тултипа: глобальная и своя",
|
|
54554
|
+
"type": "full-code",
|
|
54555
|
+
"code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n 'ExampleGlobalTooltipWidth',\n)}"
|
|
53795
54556
|
}
|
|
53796
54557
|
]
|
|
53797
54558
|
},
|
|
@@ -53836,7 +54597,7 @@
|
|
|
53836
54597
|
"legacy": true,
|
|
53837
54598
|
"summary": "Базовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.",
|
|
53838
54599
|
"docs": "# SimpleTable\n\nБазовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.\n\n## Ключевые особенности\n\n- Минимальная связка `rows`, `columnConfig` и `tableConfig`\n- Кастомный заголовок колонки через React-разметку\n- Пример render-функции ячейки для большого набора строк и колонок\n- Управление размерами таблицы через `tableConfig.containerStyle`\n\n## Особенности\n\n`MillionCells` показывает сценарий проверки виртуализации и производительности. Для новых сценариев больших таблиц предпочтительнее `TableCanvas`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-simple-api--docs).",
|
|
53839
|
-
"apiDocs": "# Simple Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
54600
|
+
"apiDocs": "# Simple Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
53840
54601
|
"api": [
|
|
53841
54602
|
{
|
|
53842
54603
|
"typeName": "TableProps",
|
|
@@ -53912,6 +54673,18 @@
|
|
|
53912
54673
|
"type": "full-code",
|
|
53913
54674
|
"code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'developer',\n name: 'Developer',\n },\n {\n key: 'tr1',\n name: 'TR',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n return (\n <Table\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n disableHiding: ['id'],\n pinning: true,\n disablePinning: ['developer'],\n reorderingAside: true,\n reorderingHeader: true,\n columnsLabel: {\n task: 'Задачи',\n },\n orderDefault: ['id', 'issueType', 'task'],\n hiddenDefault: ['tr1'],\n pinnedDefault: ['complete'],\n onConfirm: ({ order, hidden, pinned }, _setters) => {\n // eslint-disable-next-line no-alert\n alert(`\n order: ${order.join(', ')}\n pinned: ${pinned.join(', ')}\n hidden: ${hidden.join(', ')}\n `);\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
|
|
53914
54675
|
},
|
|
54676
|
+
{
|
|
54677
|
+
"exportName": "ColumnsControlDynamicColumn",
|
|
54678
|
+
"displayName": "ColumnsControl: динамическое добавление колонки",
|
|
54679
|
+
"type": "full-code",
|
|
54680
|
+
"code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n },\n {\n key: 'task',\n name: 'Title',\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [developerIsShown],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <Table\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n pinning: true,\n reorderingAside: true,\n reorderingHeader: true,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
|
|
54681
|
+
},
|
|
54682
|
+
{
|
|
54683
|
+
"exportName": "SimpleTableDynamicColumn",
|
|
54684
|
+
"displayName": "SimpleTable: динамическое добавление колонки",
|
|
54685
|
+
"type": "full-code",
|
|
54686
|
+
"code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n id\n <IconSber size=\"xs\" color=\"inherit\" />\n </div>\n ),\n },\n {\n key: 'task',\n name: 'Title',\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [developerIsShown],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <Table\n tableConfig={{ containerStyle: { height: 700 } }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
|
|
54687
|
+
},
|
|
53915
54688
|
{
|
|
53916
54689
|
"exportName": "ColumnsControlWithServiceColumnsForTest",
|
|
53917
54690
|
"displayName": "ID",
|
|
@@ -54806,7 +55579,7 @@
|
|
|
54806
55579
|
"legacy": true,
|
|
54807
55580
|
"summary": "Сортировка по колонкам",
|
|
54808
55581
|
"docs": "# Sorting\n\n## Ключевые особенности\n\n- Сортировка по колонкам\n- Строковый, числовой и кастомный компаратор\n- Ручная сортировка для серверных сценариев\n\nКомпонент `Table` поддерживает сортировку данных по колонкам.\n\n## Быстрый старт\n\nДля включения сортировки необходимо:\n\n1. Передать `sorting` в `tableConfig`\n2. Указать `sortingType` в конфигурации колонок\n\n```tsx\nconst sortingState = useState<readonly SortColumn[]>([]);\n\n<Table\n tableConfig={{\n sorting: {\n state: sortingState,\n },\n }}\n columnConfig={[\n { key: 'name', name: 'Название', sortingType: 'stringSort' },\n { key: 'amount', name: 'Сумма', sortingType: 'numberSort' },\n ]}\n rows={rows}\n/>;\n```\n\n## Стратегии сортировки\n\n<table>\n <thead>\n <tr>\n <th>sortingType</th>\n <th>Когда использовать</th>\n <th>Пример данных</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <code>stringSort</code>\n </td>\n <td>Текстовые поля, названия, описания</td>\n <td>\n <code>\"Яблоко\"</code>, <code>\"Apple\"</code>, <code>\"100 дней\"</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>numberSort</code>\n </td>\n <td>Числа, ID, коды (даже строковые)</td>\n <td>\n <code>\"42\"</code>, <code>\"1 000\"</code>, <code>\"3,14\"</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>Comparator<Row></code>\n </td>\n <td>Кастомная логика (enum-приоритеты, даты, и т.д.)</td>\n <td>\n <code>Critical → High → Medium → Low</code>\n </td>\n </tr>\n </tbody>\n</table>\n\n### stringSort\n\nСтроковое сравнение с учётом русской локали.\n\n- Строковые числа сортируются как числа: `\"2\" < \"10\"` (не посимвольно)\n- Регистр не влияет: `\"яблоко\"` = `\"Яблоко\"`\n- Пустые значения всегда внизу\n\nПорядок символов при ASC (локаль `'ru'`):\n\n<table>\n <thead>\n <tr>\n <th>Порядок</th>\n <th>Категория</th>\n <th>Пример</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>1</td>\n <td>Спецсимволы</td>\n <td>\n <code>\"#tag\"</code>, <code>\"@user\"</code>, <code>\"-\"</code>\n </td>\n </tr>\n <tr>\n <td>2</td>\n <td>Цифры</td>\n <td>\n <code>\"31.10\"</code>, <code>\"100\"</code>\n </td>\n </tr>\n <tr>\n <td>3</td>\n <td>Кириллица</td>\n <td>\n <code>\"Авто\"</code>, <code>\"Яблоко\"</code>\n </td>\n </tr>\n <tr>\n <td>4</td>\n <td>Латиница</td>\n <td>\n <code>\"Apple\"</code>, <code>\"MYCHANGE\"</code>\n </td>\n </tr>\n <tr>\n <td>—</td>\n <td>Пустые</td>\n <td>Всегда внизу</td>\n </tr>\n </tbody>\n</table>\n> Порядок между кириллицей и латиницей определяется русской локалью браузера — кириллица\nидёт первой.\n\n### numberSort\n\nЧисловое сравнение с поддержкой локальных форматов.\n\n<table>\n <thead>\n <tr>\n <th>Входное значение</th>\n <th>Результат</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <code>\"42\"</code>\n </td>\n <td>\n <code>42</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>\"1 000\"</code>\n </td>\n <td>\n <code>1000</code> (пробелы-разделители)\n </td>\n </tr>\n <tr>\n <td>\n <code>\"3,14\"</code>\n </td>\n <td>\n <code>3.14</code> (запятая как десятичный)\n </td>\n </tr>\n <tr>\n <td>\n <code>\"abc\"</code>, <code>\"\"</code>\n </td>\n <td>Уходят вниз</td>\n </tr>\n </tbody>\n</table>\n\n### Кастомный компаратор\n\nФункция `(a: Row, b: Row) => number`. Направление (ASC/DESC) применяется автоматически.\n\n```tsx\n{\n key: 'priority',\n name: 'Приоритет',\n sortingType: (a, b) => {\n const order = { Critical: 0, High: 1, Medium: 2, Low: 3 };\n return (order[a.priority] ?? 99) - (order[b.priority] ?? 99);\n },\n}\n```\n\n## Направление сортировки\n\nКлик по заголовку переключает направление циклически:\n\n**нет сортировки → ASC (↓) → DESC (↑) → нет сортировки**\n\n<table>\n <thead>\n <tr>\n <th>Иконка</th>\n <th>Направление</th>\n <th>Описание</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>↓</td>\n <td>ASC</td>\n <td>По возрастанию (от меньшего к большему)</td>\n </tr>\n <tr>\n <td>↑</td>\n <td>DESC</td>\n <td>По убыванию (от большего к меньшему)</td>\n </tr>\n <tr>\n <td>↕</td>\n <td>—</td>\n <td>Сортировка не активна</td>\n </tr>\n </tbody>\n</table>\n\nПустые значения (`null`, `undefined`, `\"\"`, строка из пробелов) всегда остаются внизу, независимо от направления.\n\n## Серверная сортировка\n\nЕсли сортировка выполняется на бэкенде, включите `manualSorting`. Таблица не будет сортировать данные сама, но будет обновлять `state` при кликах по заголовкам.\n\n```tsx\nconst [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);\n\n// Реагируем на изменение sortColumns и делаем запрос на сервер\nuseEffect(() => {\n fetchData({ sort: sortColumns });\n}, [sortColumns]);\n\n<Table\n tableConfig={{\n sorting: {\n state: [sortColumns, setSortColumns],\n manualSorting: true,\n },\n }}\n ...\n/>\n```\n\n## API\n\nПодробное описание типов доступно в разделе [API](?path=/docs/локальные-компоненты-table-sorting-api--docs).",
|
|
54809
|
-
"apiDocs": "# Sorting API\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n a: Row,\n b: Row,\n) => number;\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n`sortingType` настраивается в конфигурации колонки.\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
55582
|
+
"apiDocs": "# Sorting API\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n a: Row,\n b: Row,\n) => number;\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\n rowInstruments?: {\n getRowDropdownConfig: RowInstrumentsType<RowType>;\n /**\n * @default false\n */\n defaultOpened?: boolean;\n /**\n * @default true\n */\n showInControl?: boolean;\n /**\n * Внешний стейт видимости\n */\n openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n };\n fullScreenEnabled?: FullScreen;\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n SummaryRowType\n >;\n} & Pick<\n DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n | 'summaryRowHeight'\n | 'onFill'\n | 'onCopy'\n | 'onPaste'\n | 'onCellClick'\n | 'onCellDoubleClick'\n | 'onCellContextMenu'\n | 'onCellKeyDown'\n | 'onSelectedCellChange'\n | 'onScroll'\n | 'onColumnResize'\n | 'onColumnsReorder'\n | 'enableVirtualization'\n | 'rowClass'\n | 'data-testid'\n | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n`sortingType` настраивается в конфигурации колонки.\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
|
|
54810
55583
|
"api": [
|
|
54811
55584
|
{
|
|
54812
55585
|
"typeName": "Comparator",
|
|
@@ -55135,14 +55908,14 @@
|
|
|
55135
55908
|
},
|
|
55136
55909
|
"Table.ColumnConfig": {
|
|
55137
55910
|
"name": "ColumnConfig",
|
|
55138
|
-
"definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};",
|
|
55911
|
+
"definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};",
|
|
55139
55912
|
"importPath": "@daisforge/ui",
|
|
55140
55913
|
"importStatement": "import { ColumnConfig } from '@daisforge/ui';",
|
|
55141
55914
|
"sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
|
|
55142
55915
|
},
|
|
55143
55916
|
"TableCanvas.ColumnConfig": {
|
|
55144
55917
|
"name": "ColumnConfig",
|
|
55145
|
-
"definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n CustomCtxs extends ObjectForExtending = {},\n> = ColumnDefaultOmitted<Row, SummRow, CustomCtxs> & {\n renderCell?: (cellInfo: CellInfo<Row, SummRow, CustomCtxs>) => CellContent;\n renderCellPreview?: RenderCellPreview<Row, SummRow, CustomCtxs>;\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n /**\n * Текстовое представление ячейки для копирования в clipboard (Ctrl+C).\n * Если не задан, используется `row[column.key]?.toString()`.\n * Для кастомных canvas-ячеек (бейджи, кнопки) рекомендуется указывать явно.\n */\n copyData?: string | ((row: Row) => string);\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row, SummRow>;\n\n /**\n * Настройки колонки для дерева subRows (шеврон, свой контент и редактор на\n * вложенных уровнях). Работает только в виде дерева. При\n * `subRows.view: 'merged'` не действует: там листья рисуются как обычные\n * строки, вложенных уровней нет.\n */\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n renderSubRowCell?: RenderSubRowCell<ObjectForExtending>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any, any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n
|
|
55918
|
+
"definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n CustomCtxs extends ObjectForExtending = {},\n> = ColumnDefaultOmitted<Row, SummRow, CustomCtxs> & {\n renderCell?: (cellInfo: CellInfo<Row, SummRow, CustomCtxs>) => CellContent;\n renderCellPreview?: RenderCellPreview<Row, SummRow, CustomCtxs>;\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n /**\n * Текстовое представление ячейки для копирования в clipboard (Ctrl+C).\n * Если не задан, используется `row[column.key]?.toString()`.\n * Для кастомных canvas-ячеек (бейджи, кнопки) рекомендуется указывать явно.\n */\n copyData?: string | ((row: Row) => string);\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row, SummRow>;\n\n /**\n * Настройки колонки для дерева subRows (шеврон, свой контент и редактор на\n * вложенных уровнях). Работает только в виде дерева. При\n * `subRows.view: 'merged'` не действует: там листья рисуются как обычные\n * строки, вложенных уровней нет.\n */\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n renderSubRowCell?: RenderSubRowCell<ObjectForExtending>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any, any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n …",
|
|
55146
55919
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
55147
55920
|
"importStatement": "import { ColumnConfig } from '@daisforge/ui/components/TableCanvas';",
|
|
55148
55921
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
|
|
@@ -55170,7 +55943,7 @@
|
|
|
55170
55943
|
},
|
|
55171
55944
|
"HoverEffectsConfig": {
|
|
55172
55945
|
"name": "HoverEffectsConfig",
|
|
55173
|
-
"definition": "export type HoverEffectsConfig = {\n /**\n * Подсветка строки под
|
|
55946
|
+
"definition": "export type HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};",
|
|
55174
55947
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
55175
55948
|
"importStatement": "import { HoverEffectsConfig } from '@daisforge/ui/components/TableCanvas';",
|
|
55176
55949
|
"sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
|
|
@@ -55632,7 +56405,7 @@
|
|
|
55632
56405
|
},
|
|
55633
56406
|
"MergedCellsAlign": {
|
|
55634
56407
|
"name": "MergedCellsAlign",
|
|
55635
|
-
"definition": "export type MergedCellsAlign = {\n /** По горизонтали. @default из `
|
|
56408
|
+
"definition": "export type MergedCellsAlign = {\n /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n horizontal?: 'left' | 'center' | 'right';\n /** По вертикали. @default 'center' */\n vertical?: 'top' | 'center' | 'bottom';\n};",
|
|
55636
56409
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
55637
56410
|
"importStatement": "import { MergedCellsAlign } from '@daisforge/ui/components/TableCanvas';",
|
|
55638
56411
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/merged-cells.type.ts"
|
|
@@ -55875,6 +56648,13 @@
|
|
|
55875
56648
|
"importStatement": "import { BlockGradientScrollVariant } from '@daisforge/ui';",
|
|
55876
56649
|
"sourceFile": "packages/ui-kit/src/mixins/blockGradientScroll/types.ts"
|
|
55877
56650
|
},
|
|
56651
|
+
"TypographyWithAutoTooltipProps": {
|
|
56652
|
+
"name": "TypographyWithAutoTooltipProps",
|
|
56653
|
+
"definition": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n tooltipText?: React.ReactNode;\n tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
|
|
56654
|
+
"importPath": "@daisforge/ui",
|
|
56655
|
+
"importStatement": "import { TypographyWithAutoTooltipProps } from '@daisforge/ui';",
|
|
56656
|
+
"sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.types.ts"
|
|
56657
|
+
},
|
|
55878
56658
|
"DrawerProps": {
|
|
55879
56659
|
"name": "DrawerProps",
|
|
55880
56660
|
"definition": "export type DrawerProps = ComponentProps<typeof Drawer>;",
|
|
@@ -56015,13 +56795,6 @@
|
|
|
56015
56795
|
"importStatement": "import { NumberFormatCompProps } from '@daisforge/ui';",
|
|
56016
56796
|
"sourceFile": "packages/ui-kit/src/components/NumberFormat/NumberFormat.tsx"
|
|
56017
56797
|
},
|
|
56018
|
-
"TypographyWithAutoTooltipProps": {
|
|
56019
|
-
"name": "TypographyWithAutoTooltipProps",
|
|
56020
|
-
"definition": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n tooltipText?: React.ReactNode;\n tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
|
|
56021
|
-
"importPath": "@daisforge/ui",
|
|
56022
|
-
"importStatement": "import { TypographyWithAutoTooltipProps } from '@daisforge/ui';",
|
|
56023
|
-
"sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.types.ts"
|
|
56024
|
-
},
|
|
56025
56798
|
"BreadcrumbsPropsComp": {
|
|
56026
56799
|
"name": "BreadcrumbsPropsComp",
|
|
56027
56800
|
"definition": "export type BreadcrumbsPropsComp = ComponentProps<typeof Breadcrumbs>;",
|
|
@@ -56113,6 +56886,48 @@
|
|
|
56113
56886
|
"importNotice": "Тип \"BaseSwitchProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
56114
56887
|
"sourceFile": "packages/ui-kit/src/components/Switch/types.ts"
|
|
56115
56888
|
},
|
|
56889
|
+
"Table.Single": {
|
|
56890
|
+
"name": "Single",
|
|
56891
|
+
"definition": "type Single = {\n mode?: 'single';\n value: string;\n onChange: (v: string) => void;\n};",
|
|
56892
|
+
"internal": true,
|
|
56893
|
+
"importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
56894
|
+
"sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
|
|
56895
|
+
},
|
|
56896
|
+
"TableCanvas.Single": {
|
|
56897
|
+
"name": "Single",
|
|
56898
|
+
"definition": "type Single = {\n mode?: 'single';\n value: string;\n onChange: (v: string) => void;\n};",
|
|
56899
|
+
"internal": true,
|
|
56900
|
+
"importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
56901
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
|
|
56902
|
+
},
|
|
56903
|
+
"Table.Multiple": {
|
|
56904
|
+
"name": "Multiple",
|
|
56905
|
+
"definition": "type Multiple = {\n mode?: 'multiple';\n value: string[];\n onChange: (v: string[]) => void;\n};",
|
|
56906
|
+
"internal": true,
|
|
56907
|
+
"importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
56908
|
+
"sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
|
|
56909
|
+
},
|
|
56910
|
+
"TableCanvas.Multiple": {
|
|
56911
|
+
"name": "Multiple",
|
|
56912
|
+
"definition": "type Multiple = {\n mode?: 'multiple';\n value: string[];\n onChange: (v: string[]) => void;\n};",
|
|
56913
|
+
"internal": true,
|
|
56914
|
+
"importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
56915
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
|
|
56916
|
+
},
|
|
56917
|
+
"Table.SIZE": {
|
|
56918
|
+
"name": "SIZE",
|
|
56919
|
+
"definition": "export type SIZE = keyof typeof SIZES;",
|
|
56920
|
+
"importPath": "@daisforge/ui",
|
|
56921
|
+
"importStatement": "import { SIZE } from '@daisforge/ui';",
|
|
56922
|
+
"sourceFile": "packages/ui-kit/src/components/Table/styles/styles.constants.ts"
|
|
56923
|
+
},
|
|
56924
|
+
"TableGlide.SIZE": {
|
|
56925
|
+
"name": "SIZE",
|
|
56926
|
+
"definition": "export type SIZE = keyof GlideSizes;",
|
|
56927
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
56928
|
+
"importStatement": "import { SIZE } from '@daisforge/ui/components/TableCanvas';",
|
|
56929
|
+
"sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
|
|
56930
|
+
},
|
|
56116
56931
|
"Table.Prettify": {
|
|
56117
56932
|
"name": "Prettify",
|
|
56118
56933
|
"definition": "export type Prettify<T> = {\n [K in keyof T]: T[K];\n // eslint-disable-next-line @typescript-eslint/ban-types\n} & {};",
|
|
@@ -56136,7 +56951,7 @@
|
|
|
56136
56951
|
},
|
|
56137
56952
|
"TableCanvas.TableConfig": {
|
|
56138
56953
|
"name": "TableConfig",
|
|
56139
|
-
"definition": "export type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true
|
|
56954
|
+
"definition": "export type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true,…",
|
|
56140
56955
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
56141
56956
|
"importStatement": "import { TableConfig } from '@daisforge/ui/components/TableCanvas';",
|
|
56142
56957
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
|
|
@@ -56864,7 +57679,7 @@
|
|
|
56864
57679
|
},
|
|
56865
57680
|
"CanvasNodeTooltipProps": {
|
|
56866
57681
|
"name": "CanvasNodeTooltipProps",
|
|
56867
|
-
"definition": "export type CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n};",
|
|
57682
|
+
"definition": "export type CanvasNodeTooltipProps = Pick<\n TooltipProps,\n 'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n preserveLineBreaks?: boolean;\n /**\n * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n * @default 0\n */\n offsetX?: number;\n};",
|
|
56868
57683
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
56869
57684
|
"importStatement": "import { CanvasNodeTooltipProps } from '@daisforge/ui/components/TableCanvas';",
|
|
56870
57685
|
"sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/utils/portalHoverEvents.ts"
|
|
@@ -57200,7 +58015,7 @@
|
|
|
57200
58015
|
},
|
|
57201
58016
|
"TableCanvas.ColumnsControlConfig": {
|
|
57202
58017
|
"name": "ColumnsControlConfig",
|
|
57203
|
-
"definition": "export type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};",
|
|
58018
|
+
"definition": "export type ColumnsControlConfig = {\n enable: boolean;\n /**\n * @default enable\n */\n hiding?: boolean;\n /**\n * @default enable\n */\n pinning?: boolean;\n /**\n * @default enable\n */\n reorderingAside?: boolean;\n /**\n * reorderingHeader - активация изменения порядка колонок посредством перемещения шапок колонок таблицы\n */\n /**\n * @default enable\n */\n reorderingHeader?: boolean;\n onReorderingHeader?: (params: {\n newOrder: string[];\n sourceKey: string;\n targetKey: string;\n }) => void;\n\n columnsLabel?: Record<\n string,\n ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n >;\n\n /**\n * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n * видимые строки списка. false — отключить полностью; { minCount } —\n * включать, когда строк в списке не меньше порога.\n * @default { minCount: 30 }\n */\n virtualization?: boolean | { minCount?: number };\n\n orderDefault?: string[];\n\n pinnedDefault?: string[];\n disablePinning?: string[];\n\n hiddenDefault?: string[];\n disableHiding?: string[];\n /**\n * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n * ресайз на этой границе работает как обычно.\n * @default hiding\n */\n hiddenColumnsIndicator?: boolean;\n /**\n * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n * столбцы раскрылись и между какими видимыми колонками стояла линия.\n */\n onHiddenColumnsIndicatorExpand?: (\n info: HiddenColumnsIndicatorExpandInfo,\n ) => void;\n\n onConfirm?: (\n params: {\n pinned: string[];\n order: string[];\n hidden: string[];\n changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n },\n setters: {\n setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n },\n ) => void;\n /**\n * DomMetadata для кнопок закрепления столбцов\n */\n pinDomMetadata?: DomMetadata;\n /**\n * DomMetadata для свитчеров скрытия/показа столбцов\n */\n switchDomMetadata?: DomMetadata;\n};",
|
|
57204
58019
|
"internal": true,
|
|
57205
58020
|
"importNotice": "Тип \"ColumnsControlConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
57206
58021
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-column-control/types.ts"
|
|
@@ -57324,6 +58139,13 @@
|
|
|
57324
58139
|
"importNotice": "Тип \"ComboboxType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
57325
58140
|
"sourceFile": "packages/ui-kit/src/components/Combobox/index.ts"
|
|
57326
58141
|
},
|
|
58142
|
+
"GlideSizes": {
|
|
58143
|
+
"name": "GlideSizes",
|
|
58144
|
+
"definition": "export type GlideSizes = typeof SIZES;",
|
|
58145
|
+
"internal": true,
|
|
58146
|
+
"importNotice": "Тип \"GlideSizes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
58147
|
+
"sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
|
|
58148
|
+
},
|
|
57327
58149
|
"CellReadOnlyEditorGlideInstanceStaticProps": {
|
|
57328
58150
|
"name": "CellReadOnlyEditorGlideInstanceStaticProps",
|
|
57329
58151
|
"definition": "export type CellReadOnlyEditorGlideInstanceStaticProps = {\n formatOptions: ContentFormat | undefined;\n disableLeftOffset: boolean | undefined;\n contentAlign: 'right' | 'left' | 'center';\n};",
|
|
@@ -57345,20 +58167,6 @@
|
|
|
57345
58167
|
"importNotice": "Тип \"FillMeta\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
57346
58168
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
|
|
57347
58169
|
},
|
|
57348
|
-
"TableGlide.SIZE": {
|
|
57349
|
-
"name": "SIZE",
|
|
57350
|
-
"definition": "export type SIZE = keyof GlideSizes;",
|
|
57351
|
-
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
57352
|
-
"importStatement": "import { SIZE } from '@daisforge/ui/components/TableCanvas';",
|
|
57353
|
-
"sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
|
|
57354
|
-
},
|
|
57355
|
-
"Table.SIZE": {
|
|
57356
|
-
"name": "SIZE",
|
|
57357
|
-
"definition": "export type SIZE = keyof typeof SIZES;",
|
|
57358
|
-
"importPath": "@daisforge/ui",
|
|
57359
|
-
"importStatement": "import { SIZE } from '@daisforge/ui';",
|
|
57360
|
-
"sourceFile": "packages/ui-kit/src/components/Table/styles/styles.constants.ts"
|
|
57361
|
-
},
|
|
57362
58170
|
"RenderGroupHeaderArgs": {
|
|
57363
58171
|
"name": "RenderGroupHeaderArgs",
|
|
57364
58172
|
"definition": "export type RenderGroupHeaderArgs = Parameters<\n NonNullable<GlideProps['drawGroupHeader']>\n>[0];",
|
|
@@ -57800,6 +58608,13 @@
|
|
|
57800
58608
|
"importStatement": "import { CellsSelectionConfig } from '@daisforge/ui/components/TableCanvas';",
|
|
57801
58609
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
|
|
57802
58610
|
},
|
|
58611
|
+
"BordersConfig": {
|
|
58612
|
+
"name": "BordersConfig",
|
|
58613
|
+
"definition": "export type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};",
|
|
58614
|
+
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
58615
|
+
"importStatement": "import { BordersConfig } from '@daisforge/ui/components/TableCanvas';",
|
|
58616
|
+
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
|
|
58617
|
+
},
|
|
57803
58618
|
"CellTransferConfig": {
|
|
57804
58619
|
"name": "CellTransferConfig",
|
|
57805
58620
|
"definition": "export type CellTransferConfig = {\n /**\n * Явное включение/выключение всей фичи.\n * По умолчанию copy работает всегда, а paste и fill handle следуют\n * за `editModeEnabled`. При `false` отключается всё.\n */\n enabled?: boolean;\n /**\n * Переопределение хоткеев.\n * Можно передать один `HotkeyConfig` или массив альтернативных комбинаций.\n * По умолчанию: copy = Ctrl+C / Cmd+C, paste = Ctrl+V / Cmd+V.\n */\n hotkeys?: {\n /** Хоткей(и) для копирования */\n copy?: HotkeyConfig | HotkeyConfig[];\n /** Хоткей(и) для вставки */\n paste?: HotkeyConfig | HotkeyConfig[];\n };\n /** Настройки paste (readonly, overflow, broadcast, validation) */\n paste?: PasteConfig;\n /** Настройки fill handle. `true/false` — быстрое вкл/выкл без деталей */\n fillHandle?: boolean | FillHandleConfig;\n /**\n * Колбэк перед копированием.\n * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n * операцию (вернуть `false`).\n * Если onBeforeCopy нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforeCopy?: (data: string[][], meta: CopyMeta) => string[][] | false;\n /**\n * Колбэк перед вставкой.\n * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n * операцию (вернуть `false`).\n * Если onBeforePaste нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforePaste?: (data: string[][], meta: PasteMeta) => string[][] | false;\n /**\n * Колбэк перед fill handle (drag-to-fill).\n * Вызывается перед применением значений. Можно модифицировать данные\n * (вернуть новый `string[][]`) или отменить операцию (вернуть `false`).\n *\n * `meta.sourceCells` содержит полную информацию об исходных ячейках,\n * включая объекты строк (`row`) — позволяет получить source row\n * и использовать данные из соседних колонок.\n * Если onBeforeFill нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforeFill?: (data: string[][], meta: FillMeta) => string[][] | false;\n};",
|
|
@@ -57830,7 +58645,7 @@
|
|
|
57830
58645
|
},
|
|
57831
58646
|
"TableConfigTooltip": {
|
|
57832
58647
|
"name": "TableConfigTooltip",
|
|
57833
|
-
"definition": "export type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n};",
|
|
58648
|
+
"definition": "export type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};",
|
|
57834
58649
|
"importPath": "@daisforge/ui/components/TableCanvas",
|
|
57835
58650
|
"importStatement": "import { TableConfigTooltip } from '@daisforge/ui/components/TableCanvas';",
|
|
57836
58651
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
|
|
@@ -57877,13 +58692,6 @@
|
|
|
57877
58692
|
"importNotice": "Тип \"CellTransferCellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
57878
58693
|
"sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
|
|
57879
58694
|
},
|
|
57880
|
-
"GlideSizes": {
|
|
57881
|
-
"name": "GlideSizes",
|
|
57882
|
-
"definition": "export type GlideSizes = typeof SIZES;",
|
|
57883
|
-
"internal": true,
|
|
57884
|
-
"importNotice": "Тип \"GlideSizes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
|
|
57885
|
-
"sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
|
|
57886
|
-
},
|
|
57887
58695
|
"CrossAxisSizing": {
|
|
57888
58696
|
"name": "CrossAxisSizing",
|
|
57889
58697
|
"definition": "export type CrossAxisSizing = 'auto' | 'deferred-percent-stretch';",
|