@lowdefy/blocks-table 0.0.0-experimental-20260929110023
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/LICENSE +201 -0
- package/README.md +12 -0
- package/dist/blocks/Table/Table.js +25 -0
- package/dist/blocks/Table/Table.lazy.js +33 -0
- package/dist/blocks/Table/TableFallback.js +35 -0
- package/dist/blocks/Table/e2e.js +47 -0
- package/dist/blocks/Table/gallery.yaml +836 -0
- package/dist/blocks/Table/meta.js +964 -0
- package/dist/blocks/Table/tests/Table.e2e.yaml +434 -0
- package/dist/blocks/Table/tests/TableFeatures.e2e.yaml +291 -0
- package/dist/blocks/Table/tests/TableLinkTarget.e2e.yaml +25 -0
- package/dist/blocks/Table/tests/TableParity.e2e.yaml +101 -0
- package/dist/blocks/Table/tests/bulk.e2e.yaml +271 -0
- package/dist/blocks/Table/tests/deals.yaml +30 -0
- package/dist/blocks/Table/tests/deals_columns.yaml +37 -0
- package/dist/blocks/Table/tests/editing.e2e.yaml +501 -0
- package/dist/blocks/Table/tests/expandable.e2e.yaml +87 -0
- package/dist/blocks/Table/tests/filtering.e2e.yaml +251 -0
- package/dist/blocks/Table/tests/grouping.e2e.yaml +272 -0
- package/dist/blocks/Table/tests/grouping_deals.yaml +24 -0
- package/dist/blocks/Table/tests/grouping_deals_columns.yaml +32 -0
- package/dist/blocks/Table/tests/headerMenu.e2e.yaml +134 -0
- package/dist/blocks/Table/tests/parity_properties.yaml +144 -0
- package/dist/blocks/Table/tests/people.yaml +39 -0
- package/dist/blocks/Table/tests/people_columns.yaml +22 -0
- package/dist/blocks/Table/tests/polish.e2e.yaml +372 -0
- package/dist/blocks/Table/tests/server-mongodb.e2e.yaml +169 -0
- package/dist/blocks/Table/tests/server.e2e.yaml +267 -0
- package/dist/blocks/Table/tests/toolbar.e2e.yaml +140 -0
- package/dist/blocks/Table/tests/tree.e2e.yaml +245 -0
- package/dist/blocks/Table/tests/views.e2e.yaml +235 -0
- package/dist/blocks/TableInput/TableInput.js +24 -0
- package/dist/blocks/TableInput/TableInput.lazy.js +17 -0
- package/dist/blocks/TableInput/TableInputRoot.js +65 -0
- package/dist/blocks/TableInput/e2e.js +16 -0
- package/dist/blocks/TableInput/gallery.yaml +153 -0
- package/dist/blocks/TableInput/meta.js +93 -0
- package/dist/blocks/TableInput/tests/TableInput.e2e.yaml +272 -0
- package/dist/blocks.js +16 -0
- package/dist/core/Body.js +112 -0
- package/dist/core/Cell.js +86 -0
- package/dist/core/Chevron.js +32 -0
- package/dist/core/EmptyState.js +32 -0
- package/dist/core/Grid.js +219 -0
- package/dist/core/GroupHeaderRow.js +81 -0
- package/dist/core/HeaderCell.js +58 -0
- package/dist/core/HeaderRow.js +76 -0
- package/dist/core/HeaderTitle.js +49 -0
- package/dist/core/LazyCell.js +71 -0
- package/dist/core/LoadingRows.js +38 -0
- package/dist/core/RenderProbeContext.js +19 -0
- package/dist/core/Row.js +98 -0
- package/dist/core/SkeletonRow.js +42 -0
- package/dist/core/SummaryRow.js +86 -0
- package/dist/core/TableRoot.js +195 -0
- package/dist/core/aggregateShortLabels.js +25 -0
- package/dist/core/applyLayoutVars.js +22 -0
- package/dist/core/buildGroupSegments.js +36 -0
- package/dist/core/collectBodyOverlays.js +20 -0
- package/dist/core/collectCellLeads.js +21 -0
- package/dist/core/collectClaimedViewKeys.js +26 -0
- package/dist/core/collectGridHandlers.js +29 -0
- package/dist/core/collectHeaderParts.js +20 -0
- package/dist/core/collectRowRenderers.js +21 -0
- package/dist/core/collectSliceDefinitions.js +29 -0
- package/dist/core/computeLayout.js +133 -0
- package/dist/core/createAccessor.js +39 -0
- package/dist/core/createApi.js +86 -0
- package/dist/core/createCellActivity.js +47 -0
- package/dist/core/createColumnDefs.js +42 -0
- package/dist/core/createFeatureActions.js +24 -0
- package/dist/core/createFeatureSet.js +39 -0
- package/dist/core/createInitialState.js +63 -0
- package/dist/core/createKeyIndex.js +26 -0
- package/dist/core/createMethodStubs.js +30 -0
- package/dist/core/createSliceHandlers.js +26 -0
- package/dist/core/createStableCoreRowModel.js +91 -0
- package/dist/core/createTanstackFeatures.js +24 -0
- package/dist/core/createTextMeasure.js +106 -0
- package/dist/core/densityHeights.js +20 -0
- package/dist/core/deriveValue.js +53 -0
- package/dist/core/dispatchGridEvent.js +21 -0
- package/dist/core/distributeFlex.js +28 -0
- package/dist/core/getCellFit.js +34 -0
- package/dist/core/getHeaderCellProps.js +21 -0
- package/dist/core/getHeaderLevels.js +50 -0
- package/dist/core/getRecordCount.js +23 -0
- package/dist/core/getSummaryLabel.js +35 -0
- package/dist/core/getValueSignature.js +26 -0
- package/dist/core/isDataItem.js +21 -0
- package/dist/core/isDefaultViewColumns.js +36 -0
- package/dist/core/isRowEqual.js +40 -0
- package/dist/core/isSameSignature.js +19 -0
- package/dist/core/lazyCellTypes.js +33 -0
- package/dist/core/lazyComponent.js +30 -0
- package/dist/core/loadOptionalFeature.js +35 -0
- package/dist/core/normalizeViewColumn.js +29 -0
- package/dist/core/pickViewPart.js +23 -0
- package/dist/core/renderRegion.js +21 -0
- package/dist/core/resolveMountValue.js +31 -0
- package/dist/core/resolveViewColumns.js +65 -0
- package/dist/core/someColumnConfig.js +30 -0
- package/dist/core/stabilizeData.js +90 -0
- package/dist/core/table.css +557 -0
- package/dist/core/useFeatureData.js +35 -0
- package/dist/core/useFeatureFragments.js +55 -0
- package/dist/core/useFeatureItems.js +78 -0
- package/dist/core/useFeatureMethods.js +29 -0
- package/dist/core/useFeatureRows.js +36 -0
- package/dist/core/useFeatureSet.js +54 -0
- package/dist/core/useForeignKeys.js +38 -0
- package/dist/core/useGridFeatures.js +26 -0
- package/dist/core/useStableConfig.js +34 -0
- package/dist/core/useSummary.js +73 -0
- package/dist/core/useTableConfig.js +189 -0
- package/dist/core/useTableState.js +150 -0
- package/dist/core/useViewportSize.js +40 -0
- package/dist/e2e.js +16 -0
- package/dist/features/bulk/BulkBar.js +46 -0
- package/dist/features/bulk/bulk.css +57 -0
- package/dist/features/bulk/bulkFeature.js +28 -0
- package/dist/features/bulk/countSelection.js +27 -0
- package/dist/features/bulk/createSelectAllMatching.js +43 -0
- package/dist/features/bulk/useBulkBar.js +42 -0
- package/dist/features/clipboard/clipboardFeature.js +24 -0
- package/dist/features/clipboard/createPasteCells.js +61 -0
- package/dist/features/clipboard/getCopyText.js +57 -0
- package/dist/features/clipboard/handleCopyKeyDown.js +37 -0
- package/dist/features/clipboard/parseTsv.js +70 -0
- package/dist/features/clipboard/pasteFeature.js +26 -0
- package/dist/features/clipboard/planPaste.js +101 -0
- package/dist/features/clipboard/serializeTsv.js +25 -0
- package/dist/features/clipboard/usePasteListener.js +45 -0
- package/dist/features/columnManager/ColumnManager.js +253 -0
- package/dist/features/columnManager/ColumnManagerPopover.js +37 -0
- package/dist/features/columnManager/DragHandleIcon.js +39 -0
- package/dist/features/columnManager/LazyColumnManagerPopover.js +19 -0
- package/dist/features/columnManager/applyManagerRegions.js +43 -0
- package/dist/features/columnManager/boundaryIds.js +21 -0
- package/dist/features/columnManager/buildManagerSequence.js +38 -0
- package/dist/features/columnManager/columnManager.css +155 -0
- package/dist/features/columnManager/columnManagerFeature.js +37 -0
- package/dist/features/columnManager/createCloseColumnManager.js +21 -0
- package/dist/features/columnManager/createOpenColumnManager.js +21 -0
- package/dist/features/columnManager/createResetColumns.js +43 -0
- package/dist/features/columnManager/getColumnManagerMenuItems.js +26 -0
- package/dist/features/columnManager/getListRoom.js +31 -0
- package/dist/features/columnManager/getManagerEntries.js +31 -0
- package/dist/features/columnManager/moveSequenceEntry.js +25 -0
- package/dist/features/columnManager/sequenceToRegions.js +38 -0
- package/dist/features/columnManager/snapListHeight.js +35 -0
- package/dist/features/columnManager/updateScrollHints.js +23 -0
- package/dist/features/columnManager/useColumnManager.js +36 -0
- package/dist/features/density/densityFeature.js +39 -0
- package/dist/features/density/densityToValue.js +23 -0
- package/dist/features/density/getViewWrapColumn.js +53 -0
- package/dist/features/density/initDensity.js +27 -0
- package/dist/features/density/initWrap.js +23 -0
- package/dist/features/editing/AddRowButton.js +28 -0
- package/dist/features/editing/CellEditor.js +284 -0
- package/dist/features/editing/EditMarker.js +38 -0
- package/dist/features/editing/EditingLayer.js +148 -0
- package/dist/features/editing/RowControlsCell.js +89 -0
- package/dist/features/editing/RowControlsHeader.js +18 -0
- package/dist/features/editing/SelectedTag.js +33 -0
- package/dist/features/editing/addChangeRow.js +34 -0
- package/dist/features/editing/applyChangeUpdates.js +28 -0
- package/dist/features/editing/applyChanges.js +90 -0
- package/dist/features/editing/applyMoveOverlay.js +44 -0
- package/dist/features/editing/applyMoveToChanges.js +66 -0
- package/dist/features/editing/applyOverlay.js +41 -0
- package/dist/features/editing/coerceCellValue.js +187 -0
- package/dist/features/editing/collectRawColumns.js +38 -0
- package/dist/features/editing/computeEditTargets.js +108 -0
- package/dist/features/editing/computeRowMove.js +78 -0
- package/dist/features/editing/createAddRow.js +68 -0
- package/dist/features/editing/createCancelEdit.js +29 -0
- package/dist/features/editing/createCommitEdit.js +124 -0
- package/dist/features/editing/createDeleteRow.js +39 -0
- package/dist/features/editing/createEditSpecs.js +80 -0
- package/dist/features/editing/createEmptyChanges.js +23 -0
- package/dist/features/editing/createMoveRow.js +65 -0
- package/dist/features/editing/createNewRow.js +32 -0
- package/dist/features/editing/createResetChanges.js +29 -0
- package/dist/features/editing/createSaveCellEdit.js +113 -0
- package/dist/features/editing/createSaveRowMove.js +90 -0
- package/dist/features/editing/createStartEdit.js +57 -0
- package/dist/features/editing/createStepHistory.js +33 -0
- package/dist/features/editing/createUndoStack.js +67 -0
- package/dist/features/editing/createValueStore.js +34 -0
- package/dist/features/editing/createWriteCell.js +34 -0
- package/dist/features/editing/createWriteChanges.js +43 -0
- package/dist/features/editing/editing.css +223 -0
- package/dist/features/editing/editingFeature.js +66 -0
- package/dist/features/editing/findCellByKey.js +23 -0
- package/dist/features/editing/findInvalidCells.js +41 -0
- package/dist/features/editing/findNextEditableCell.js +54 -0
- package/dist/features/editing/focusCell.js +28 -0
- package/dist/features/editing/fromDateValue.js +29 -0
- package/dist/features/editing/fromEditorDraft.js +45 -0
- package/dist/features/editing/generateRowKey.js +25 -0
- package/dist/features/editing/getDataGap.js +28 -0
- package/dist/features/editing/getEditOptions.js +33 -0
- package/dist/features/editing/getEditorKind.js +36 -0
- package/dist/features/editing/getEventError.js +24 -0
- package/dist/features/editing/getKeyField.js +23 -0
- package/dist/features/editing/getReorderBlock.js +33 -0
- package/dist/features/editing/handleEditDoubleClick.js +34 -0
- package/dist/features/editing/handleEditKeyDown.js +123 -0
- package/dist/features/editing/handleRowControlsClick.js +29 -0
- package/dist/features/editing/handleRowDragPointerDown.js +95 -0
- package/dist/features/editing/isCellEditable.js +20 -0
- package/dist/features/editing/isPrintableKey.js +22 -0
- package/dist/features/editing/isSameTargets.js +19 -0
- package/dist/features/editing/matchOption.js +21 -0
- package/dist/features/editing/needsEditing.js +26 -0
- package/dist/features/editing/normalizeChanges.js +37 -0
- package/dist/features/editing/positionBetween.js +30 -0
- package/dist/features/editing/pruneOverlay.js +39 -0
- package/dist/features/editing/removeChangeRow.js +48 -0
- package/dist/features/editing/reorderByKeys.js +34 -0
- package/dist/features/editing/rowControlsColumn.js +33 -0
- package/dist/features/editing/setChangeField.js +72 -0
- package/dist/features/editing/setRowField.js +23 -0
- package/dist/features/editing/sortByPosition.js +31 -0
- package/dist/features/editing/toDateValue.js +38 -0
- package/dist/features/editing/toEditorDraft.js +56 -0
- package/dist/features/editing/toSelectOptions.js +39 -0
- package/dist/features/editing/useEditingData.js +199 -0
- package/dist/features/editing/useEditingFragments.js +77 -0
- package/dist/features/editing/useEditingGrid.js +25 -0
- package/dist/features/editing/validateCellValue.js +25 -0
- package/dist/features/editing/valuesEqual.js +31 -0
- package/dist/features/editing/warnMissingEvent.js +23 -0
- package/dist/features/events/createActivateRow.js +54 -0
- package/dist/features/events/eventsFeature.js +35 -0
- package/dist/features/events/getBodyTarget.js +27 -0
- package/dist/features/events/getRowIndex.js +24 -0
- package/dist/features/events/handleAuxClick.js +38 -0
- package/dist/features/events/handlePointerDown.js +22 -0
- package/dist/features/events/handleRowClick.js +57 -0
- package/dist/features/events/handleRowDoubleClick.js +45 -0
- package/dist/features/events/isTextDrag.js +30 -0
- package/dist/features/events/openRowLink.js +29 -0
- package/dist/features/expandable/DetailRow.js +57 -0
- package/dist/features/expandable/ExpandToggle.js +34 -0
- package/dist/features/expandable/expandable.css +40 -0
- package/dist/features/expandable/expandableFeature.js +34 -0
- package/dist/features/expandable/handleExpandClick.js +25 -0
- package/dist/features/expandable/needsExpandable.js +20 -0
- package/dist/features/expandable/normalizeExpandable.js +52 -0
- package/dist/features/expandable/useExpandableItems.js +101 -0
- package/dist/features/expansion/createToggleRowExpanded.js +52 -0
- package/dist/features/expansion/expansionFeature.js +31 -0
- package/dist/features/expansion/getExpandedIds.js +26 -0
- package/dist/features/expansion/initExpanded.js +22 -0
- package/dist/features/export/buildCsv.js +39 -0
- package/dist/features/export/createExportCsv.js +59 -0
- package/dist/features/export/exportFeature.js +25 -0
- package/dist/features/export/toCsvField.js +20 -0
- package/dist/features/filtering/ChoiceFilter.js +30 -0
- package/dist/features/filtering/CloseIcon.js +29 -0
- package/dist/features/filtering/ColumnFilter.js +192 -0
- package/dist/features/filtering/ColumnFilterPopover.js +38 -0
- package/dist/features/filtering/DateFilter.js +80 -0
- package/dist/features/filtering/DraftInput.js +37 -0
- package/dist/features/filtering/DraftInputNumber.js +36 -0
- package/dist/features/filtering/FilterBuilder.js +45 -0
- package/dist/features/filtering/FilterGroup.js +116 -0
- package/dist/features/filtering/FilterIcon.js +26 -0
- package/dist/features/filtering/FilterIndicator.js +40 -0
- package/dist/features/filtering/FilterLeaf.js +86 -0
- package/dist/features/filtering/LazyColumnFilterPopover.js +19 -0
- package/dist/features/filtering/LazyFilterBuilder.js +19 -0
- package/dist/features/filtering/NumberFilter.js +43 -0
- package/dist/features/filtering/OptionsFilter.js +72 -0
- package/dist/features/filtering/RelativeDateEditor.js +90 -0
- package/dist/features/filtering/TextFilter.js +51 -0
- package/dist/features/filtering/ValueEditor.js +210 -0
- package/dist/features/filtering/buildColumnFilter.js +95 -0
- package/dist/features/filtering/changeLeafOperator.js +46 -0
- package/dist/features/filtering/createApplyFiltering.js +78 -0
- package/dist/features/filtering/createClearFilters.js +24 -0
- package/dist/features/filtering/createCloseColumnFilter.js +28 -0
- package/dist/features/filtering/createConditionFilteredRowModel.js +40 -0
- package/dist/features/filtering/createDefaultLeaf.js +31 -0
- package/dist/features/filtering/createOpenColumnFilter.js +25 -0
- package/dist/features/filtering/createRowTest.js +32 -0
- package/dist/features/filtering/createSearchMatcher.js +35 -0
- package/dist/features/filtering/createSetFilter.js +27 -0
- package/dist/features/filtering/createSetSearch.js +29 -0
- package/dist/features/filtering/createUpdateColumnFilter.js +29 -0
- package/dist/features/filtering/defaultRelativeDate.js +20 -0
- package/dist/features/filtering/filterRowModel.js +66 -0
- package/dist/features/filtering/filtering.css +151 -0
- package/dist/features/filtering/filteringFeature.js +82 -0
- package/dist/features/filtering/filteringToValue.js +23 -0
- package/dist/features/filtering/formatFilterDate.js +24 -0
- package/dist/features/filtering/getColumnConditions.js +24 -0
- package/dist/features/filtering/getConditionKeys.js +31 -0
- package/dist/features/filtering/getDistinctOptions.js +52 -0
- package/dist/features/filtering/getFilterKind.js +37 -0
- package/dist/features/filtering/getFilterResultKey.js +26 -0
- package/dist/features/filtering/getFilterResults.js +53 -0
- package/dist/features/filtering/getFilteredKeys.js +31 -0
- package/dist/features/filtering/getFilteringHeaderProps.js +22 -0
- package/dist/features/filtering/getFilteringMenuItems.js +42 -0
- package/dist/features/filtering/getFilteringTableOptions.js +33 -0
- package/dist/features/filtering/getGroupOperator.js +23 -0
- package/dist/features/filtering/getOperatorLabel.js +50 -0
- package/dist/features/filtering/getPlainTitle.js +26 -0
- package/dist/features/filtering/getSearchColumns.js +23 -0
- package/dist/features/filtering/getSearchKey.js +19 -0
- package/dist/features/filtering/getSearchText.js +57 -0
- package/dist/features/filtering/getTopLevelConditions.js +25 -0
- package/dist/features/filtering/getValueShape.js +30 -0
- package/dist/features/filtering/handleFilterIndicatorClick.js +25 -0
- package/dist/features/filtering/initFilter.js +25 -0
- package/dist/features/filtering/initSearch.js +24 -0
- package/dist/features/filtering/isColumnCondition.js +22 -0
- package/dist/features/filtering/isCompleteLeaf.js +45 -0
- package/dist/features/filtering/isServerMode.js +21 -0
- package/dist/features/filtering/normalizeSearch.js +21 -0
- package/dist/features/filtering/parseColumnFilter.js +128 -0
- package/dist/features/filtering/parseFilterDate.js +24 -0
- package/dist/features/filtering/prepareFilterResult.js +63 -0
- package/dist/features/filtering/pruneCondition.js +35 -0
- package/dist/features/filtering/setColumnFilter.js +51 -0
- package/dist/features/filtering/textFilterOperators.js +26 -0
- package/dist/features/filtering/toRootGroup.js +34 -0
- package/dist/features/filtering/useDraft.js +65 -0
- package/dist/features/filtering/useFilteringState.js +32 -0
- package/dist/features/filtering/useSyncedState.js +45 -0
- package/dist/features/grouping/GroupCell.js +72 -0
- package/dist/features/grouping/GroupCheckbox.js +38 -0
- package/dist/features/grouping/GroupLabel.js +73 -0
- package/dist/features/grouping/GroupRow.js +103 -0
- package/dist/features/grouping/StickyGroupRow.js +136 -0
- package/dist/features/grouping/buildGroupTree.js +138 -0
- package/dist/features/grouping/buildStickyLevels.js +35 -0
- package/dist/features/grouping/countGroupSelection.js +26 -0
- package/dist/features/grouping/createAggregateColumns.js +38 -0
- package/dist/features/grouping/createCollapseAllGroups.js +26 -0
- package/dist/features/grouping/createExpandAllGroups.js +23 -0
- package/dist/features/grouping/createGroupLevels.js +46 -0
- package/dist/features/grouping/createSetCollapsedGroups.js +27 -0
- package/dist/features/grouping/createSetGroup.js +35 -0
- package/dist/features/grouping/createSetGroupKeys.js +27 -0
- package/dist/features/grouping/createToggleGroup.js +38 -0
- package/dist/features/grouping/createToggleGroupSelected.js +49 -0
- package/dist/features/grouping/findGroupIndices.js +25 -0
- package/dist/features/grouping/flattenGroups.js +58 -0
- package/dist/features/grouping/getGroupLabel.js +34 -0
- package/dist/features/grouping/getStickyGroups.js +60 -0
- package/dist/features/grouping/groupRowsFeature.js +57 -0
- package/dist/features/grouping/grouping.css +128 -0
- package/dist/features/grouping/groupingFeature.js +48 -0
- package/dist/features/grouping/groupingHeaderMenuItems.js +44 -0
- package/dist/features/grouping/groupingToValue.js +26 -0
- package/dist/features/grouping/handleGroupClick.js +51 -0
- package/dist/features/grouping/handleGroupKeyDown.js +60 -0
- package/dist/features/grouping/initAggregates.js +36 -0
- package/dist/features/grouping/initCollapsedGroups.js +29 -0
- package/dist/features/grouping/initGrouping.js +34 -0
- package/dist/features/grouping/needsGroupRows.js +23 -0
- package/dist/features/grouping/orderGroups.js +49 -0
- package/dist/features/grouping/resolveAggregates.js +29 -0
- package/dist/features/grouping/toGroupIdentity.js +24 -0
- package/dist/features/grouping/toGroupKeys.js +24 -0
- package/dist/features/grouping/useGrouping.js +91 -0
- package/dist/features/headerMenu/HeaderMenuDropdown.js +86 -0
- package/dist/features/headerMenu/HeaderMenuTrigger.js +44 -0
- package/dist/features/headerMenu/LazyHeaderMenuDropdown.js +19 -0
- package/dist/features/headerMenu/MenuIcon.js +38 -0
- package/dist/features/headerMenu/collectHeaderMenuItems.js +69 -0
- package/dist/features/headerMenu/createAutosizeColumn.js +35 -0
- package/dist/features/headerMenu/createCloseHeaderMenu.js +28 -0
- package/dist/features/headerMenu/createOpenHeaderMenu.js +30 -0
- package/dist/features/headerMenu/focusHeaderControl.js +31 -0
- package/dist/features/headerMenu/freezeColumns.js +31 -0
- package/dist/features/headerMenu/getChromeMenuItems.js +144 -0
- package/dist/features/headerMenu/getVisibleOrder.js +19 -0
- package/dist/features/headerMenu/handleHeaderButtonPointerDown.js +27 -0
- package/dist/features/headerMenu/handleHeaderMenuClick.js +26 -0
- package/dist/features/headerMenu/handleHeaderMenuKeyDown.js +28 -0
- package/dist/features/headerMenu/headerMenu.css +122 -0
- package/dist/features/headerMenu/headerMenuFeature.js +46 -0
- package/dist/features/headerMenu/measureColumnWidth.js +51 -0
- package/dist/features/headerMenu/pinColumn.js +27 -0
- package/dist/features/headerMenu/sectionOrder.js +25 -0
- package/dist/features/headerMenu/useHeaderMenuState.js +27 -0
- package/dist/features/index.js +149 -0
- package/dist/features/keyboard/findCellElement.js +21 -0
- package/dist/features/keyboard/getNextCell.js +74 -0
- package/dist/features/keyboard/handleGridFocus.js +31 -0
- package/dist/features/keyboard/handleGridKeyDown.js +72 -0
- package/dist/features/keyboard/isCellRendered.js +22 -0
- package/dist/features/keyboard/keyboardFeature.js +26 -0
- package/dist/features/keyboard/useKeyboard.js +84 -0
- package/dist/features/lazyCells/getBodyRowKey.js +19 -0
- package/dist/features/lazyCells/handlePointerLeave.js +21 -0
- package/dist/features/lazyCells/handlePointerOver.js +22 -0
- package/dist/features/lazyCells/handleRowBlur.js +22 -0
- package/dist/features/lazyCells/handleRowFocus.js +26 -0
- package/dist/features/lazyCells/lazyCellsFeature.js +33 -0
- package/dist/features/lazyCells/useFastScroll.js +57 -0
- package/dist/features/ordering/getColumnClientBounds.js +32 -0
- package/dist/features/ordering/handleReorderPointerDown.js +137 -0
- package/dist/features/ordering/initColumnOrder.js +18 -0
- package/dist/features/ordering/moveKeys.js +27 -0
- package/dist/features/ordering/orderingFeature.js +35 -0
- package/dist/features/pagination/TablePagination.js +31 -0
- package/dist/features/pagination/initPageSize.js +28 -0
- package/dist/features/pagination/paginationFeature.js +36 -0
- package/dist/features/pagination/paginationToValue.js +24 -0
- package/dist/features/pagination/usePager.js +32 -0
- package/dist/features/pagination/usePagination.js +58 -0
- package/dist/features/pinning/initColumnPinning.js +21 -0
- package/dist/features/pinning/pinningFeature.js +33 -0
- package/dist/features/pinning/pinningToViewColumn.js +24 -0
- package/dist/features/queue/createAfterRowAction.js +40 -0
- package/dist/features/queue/findNextRowId.js +26 -0
- package/dist/features/queue/findRowAction.js +77 -0
- package/dist/features/queue/handleRowActionKey.js +44 -0
- package/dist/features/queue/queueFeature.js +27 -0
- package/dist/features/selection/SelectAllHeader.js +40 -0
- package/dist/features/selection/SelectCell.js +30 -0
- package/dist/features/selection/countSelectedRows.js +31 -0
- package/dist/features/selection/createClearSelection.js +29 -0
- package/dist/features/selection/createToggleAllRowsSelected.js +60 -0
- package/dist/features/selection/createToggleRowSelected.js +86 -0
- package/dist/features/selection/getRawRowKey.js +23 -0
- package/dist/features/selection/getSelectAllExcept.js +23 -0
- package/dist/features/selection/getSelectAllState.js +42 -0
- package/dist/features/selection/handleSelectionClick.js +30 -0
- package/dist/features/selection/initRowSelection.js +36 -0
- package/dist/features/selection/initSelectionMode.js +19 -0
- package/dist/features/selection/initSelectionView.js +35 -0
- package/dist/features/selection/isSelectAllValue.js +19 -0
- package/dist/features/selection/isSelectionViewCurrent.js +22 -0
- package/dist/features/selection/notifySelectionChange.js +32 -0
- package/dist/features/selection/pruneRowSelection.js +26 -0
- package/dist/features/selection/selectionFeature.js +69 -0
- package/dist/features/selection/selectionToValue.js +48 -0
- package/dist/features/selection/useSelection.js +77 -0
- package/dist/features/serverData/buildServerItems.js +109 -0
- package/dist/features/serverData/createBlockCache.js +205 -0
- package/dist/features/serverData/createRefresh.js +23 -0
- package/dist/features/serverData/createServerStore.js +360 -0
- package/dist/features/serverData/getBlockRange.js +29 -0
- package/dist/features/serverData/getListKey.js +20 -0
- package/dist/features/serverData/getNeededBlocks.js +45 -0
- package/dist/features/serverData/needsServerData.js +20 -0
- package/dist/features/serverData/normalizeServerData.js +41 -0
- package/dist/features/serverData/pickServerView.js +43 -0
- package/dist/features/serverData/readFetchResult.js +36 -0
- package/dist/features/serverData/serverData.css +21 -0
- package/dist/features/serverData/serverDataFeature.js +38 -0
- package/dist/features/serverData/serverRangeFeature.js +22 -0
- package/dist/features/serverData/useServerData.js +48 -0
- package/dist/features/serverData/useServerItems.js +35 -0
- package/dist/features/serverData/useServerRange.js +35 -0
- package/dist/features/serverData/useServerView.js +70 -0
- package/dist/features/sizing/ResizeHandle.js +24 -0
- package/dist/features/sizing/handleResizePointerDown.js +66 -0
- package/dist/features/sizing/initColumnSizing.js +23 -0
- package/dist/features/sizing/sizingFeature.js +39 -0
- package/dist/features/sizing/sizingToViewColumn.js +24 -0
- package/dist/features/sorting/SortIndicator.js +37 -0
- package/dist/features/sorting/buildSortKeys.js +52 -0
- package/dist/features/sorting/collectSortKeys.js +30 -0
- package/dist/features/sorting/createClearSort.js +21 -0
- package/dist/features/sorting/createIndexSortedRowModel.js +33 -0
- package/dist/features/sorting/createSetSort.js +43 -0
- package/dist/features/sorting/createSortKeyCollector.js +59 -0
- package/dist/features/sorting/createToggleSort.js +42 -0
- package/dist/features/sorting/getCachedSortKeys.js +19 -0
- package/dist/features/sorting/getSortHeaderProps.js +25 -0
- package/dist/features/sorting/getSortKeys.js +38 -0
- package/dist/features/sorting/handleSortClick.js +27 -0
- package/dist/features/sorting/initSorting.js +37 -0
- package/dist/features/sorting/isNumericSortType.js +21 -0
- package/dist/features/sorting/prepareSortKeys.js +92 -0
- package/dist/features/sorting/rankSortKeys.js +33 -0
- package/dist/features/sorting/setCachedSortKeys.js +24 -0
- package/dist/features/sorting/sortInSlices.js +69 -0
- package/dist/features/sorting/sortIndices.js +40 -0
- package/dist/features/sorting/sortKeysCache.js +19 -0
- package/dist/features/sorting/sortRowModel.js +84 -0
- package/dist/features/sorting/sortingFeature.js +62 -0
- package/dist/features/sorting/sortingToValue.js +27 -0
- package/dist/features/sorting/toFloatSortKeys.js +24 -0
- package/dist/features/sorting/yieldToMain.js +27 -0
- package/dist/features/toolbar/ColumnTitle.js +28 -0
- package/dist/features/toolbar/DensityToggle.js +53 -0
- package/dist/features/toolbar/FilterButton.js +56 -0
- package/dist/features/toolbar/GroupButton.js +51 -0
- package/dist/features/toolbar/OptionsQuickFilter.js +72 -0
- package/dist/features/toolbar/QuickFilter.js +46 -0
- package/dist/features/toolbar/RecordCount.js +27 -0
- package/dist/features/toolbar/SaveViewAs.js +66 -0
- package/dist/features/toolbar/SortButton.js +94 -0
- package/dist/features/toolbar/Toolbar.js +88 -0
- package/dist/features/toolbar/ToolbarCount.js +25 -0
- package/dist/features/toolbar/ToolbarIcon.js +28 -0
- package/dist/features/toolbar/ToolbarList.js +100 -0
- package/dist/features/toolbar/ToolbarSearch.js +63 -0
- package/dist/features/toolbar/ViewActions.js +41 -0
- package/dist/features/toolbar/ViewTabLabel.js +39 -0
- package/dist/features/toolbar/ViewTabMenu.js +48 -0
- package/dist/features/toolbar/ViewTabs.js +44 -0
- package/dist/features/toolbar/countConditions.js +25 -0
- package/dist/features/toolbar/formatRecordCount.js +19 -0
- package/dist/features/toolbar/getQuickFilterValues.js +25 -0
- package/dist/features/toolbar/getRootConditions.js +25 -0
- package/dist/features/toolbar/handleToolbarKeyDown.js +28 -0
- package/dist/features/toolbar/isDefaultSorting.js +26 -0
- package/dist/features/toolbar/isQuickFilterLeaf.js +20 -0
- package/dist/features/toolbar/moveItem.js +25 -0
- package/dist/features/toolbar/needsToolbar.js +21 -0
- package/dist/features/toolbar/normalizeToolbar.js +61 -0
- package/dist/features/toolbar/setQuickFilterValues.js +35 -0
- package/dist/features/toolbar/toolbar.css +185 -0
- package/dist/features/toolbar/toolbarFeature.js +27 -0
- package/dist/features/toolbar/useToolbar.js +41 -0
- package/dist/features/toolbar/validateQuickFilters.js +28 -0
- package/dist/features/transactions/applyTransactionToRows.js +56 -0
- package/dist/features/transactions/createApplyTransaction.js +26 -0
- package/dist/features/transactions/normalizeTransaction.js +49 -0
- package/dist/features/transactions/transactionsFeature.js +24 -0
- package/dist/features/transactions/useTransactionData.js +44 -0
- package/dist/features/tree/TreeToggle.js +39 -0
- package/dist/features/tree/buildTreeIndex.js +60 -0
- package/dist/features/tree/buildTreeItems.js +96 -0
- package/dist/features/tree/flattenTreeData.js +45 -0
- package/dist/features/tree/getDescendantIds.js +28 -0
- package/dist/features/tree/handleTreeClick.js +25 -0
- package/dist/features/tree/handleTreeKeyDown.js +58 -0
- package/dist/features/tree/needsTree.js +20 -0
- package/dist/features/tree/normalizeTree.js +41 -0
- package/dist/features/tree/rowNeedsChildren.js +25 -0
- package/dist/features/tree/tree.css +55 -0
- package/dist/features/tree/treeFeature.js +35 -0
- package/dist/features/tree/useTreeData.js +33 -0
- package/dist/features/tree/useTreeItems.js +61 -0
- package/dist/features/views/compactView.js +30 -0
- package/dist/features/views/createViewsApi.js +74 -0
- package/dist/features/views/decodeViewParam.js +30 -0
- package/dist/features/views/encodeViewParam.js +25 -0
- package/dist/features/views/findActiveView.js +23 -0
- package/dist/features/views/getStorageKey.js +20 -0
- package/dist/features/views/getViewKey.js +27 -0
- package/dist/features/views/getViewSliceDeps.js +27 -0
- package/dist/features/views/isViewDirty.js +34 -0
- package/dist/features/views/mountViewValue.js +36 -0
- package/dist/features/views/needsViews.js +23 -0
- package/dist/features/views/normalizePersist.js +27 -0
- package/dist/features/views/normalizeViews.js +41 -0
- package/dist/features/views/notifyViewSelect.js +29 -0
- package/dist/features/views/readMountPayload.js +31 -0
- package/dist/features/views/readPersistedView.js +45 -0
- package/dist/features/views/sanitizePersistedView.js +49 -0
- package/dist/features/views/stableStringify.js +27 -0
- package/dist/features/views/useViews.js +136 -0
- package/dist/features/views/viewKeys.js +28 -0
- package/dist/features/views/viewsFeature.js +26 -0
- package/dist/features/views/writePersistedView.js +42 -0
- package/dist/features/virtualization/computeRowOffsets.js +29 -0
- package/dist/features/virtualization/computeWindow.js +92 -0
- package/dist/features/virtualization/createScrollToRow.js +36 -0
- package/dist/features/virtualization/firstIndexAbove.js +30 -0
- package/dist/features/virtualization/getMeasureKey.js +23 -0
- package/dist/features/virtualization/isMeasuredColumn.js +20 -0
- package/dist/features/virtualization/isSameRange.js +18 -0
- package/dist/features/virtualization/positionedRowsFeature.js +22 -0
- package/dist/features/virtualization/scrollToCell.js +49 -0
- package/dist/features/virtualization/shiftRowOffsets.js +35 -0
- package/dist/features/virtualization/usePositionedRows.js +37 -0
- package/dist/features/virtualization/useRowOffsets.js +123 -0
- package/dist/features/virtualization/useScrollWindow.js +114 -0
- package/dist/features/virtualization/useTanstackRowWindow.js +43 -0
- package/dist/features/virtualization/useVirtualization.js +64 -0
- package/dist/features/virtualization/virtualizationFeature.js +24 -0
- package/dist/features/virtualization/writeScrollEdges.js +33 -0
- package/dist/features/visibility/initColumnVisibility.js +22 -0
- package/dist/features/visibility/visibilityFeature.js +31 -0
- package/dist/features/visibility/visibilityToViewColumn.js +20 -0
- package/dist/metas.js +16 -0
- package/dist/types.js +17 -0
- package/package.json +91 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import decodeViewParam from './decodeViewParam.js';
|
|
17
|
+
import getStorageKey from './getStorageKey.js';
|
|
18
|
+
function readStored({ persist }) {
|
|
19
|
+
if (persist.storage === 'url') {
|
|
20
|
+
return decodeViewParam(new URLSearchParams(window.location.search).get(persist.key));
|
|
21
|
+
}
|
|
22
|
+
// A private window, blocked site data or a malformed entry means no persisted view, never an
|
|
23
|
+
// error.
|
|
24
|
+
try {
|
|
25
|
+
const text = window.localStorage.getItem(getStorageKey(persist.key));
|
|
26
|
+
if (type.isNone(text)) return null;
|
|
27
|
+
const payload = JSON.parse(text);
|
|
28
|
+
return type.isObject(payload) ? payload : null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// The persisted payload `{ view, activeView }`, or null.
|
|
34
|
+
function readPersistedView({ persist }) {
|
|
35
|
+
if (type.isNone(persist)) return null;
|
|
36
|
+
const payload = readStored({
|
|
37
|
+
persist
|
|
38
|
+
});
|
|
39
|
+
if (type.isNone(payload)) return null;
|
|
40
|
+
return {
|
|
41
|
+
view: type.isObject(payload.view) ? payload.view : {},
|
|
42
|
+
activeView: type.isString(payload.activeView) ? payload.activeView : null
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export default readPersistedView;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import viewKeys from './viewKeys.js';
|
|
17
|
+
const KNOWN_KEYS = new Set(viewKeys);
|
|
18
|
+
// A stored view comes from an older config or a hand-edited URL. The brief's fallback rules apply:
|
|
19
|
+
// unknown view keys are dropped, column entries for columns that no longer exist are dropped, and
|
|
20
|
+
// declared columns missing from a stored column layout are appended hidden. A view without
|
|
21
|
+
// `columns` keeps following the configured layout.
|
|
22
|
+
function sanitizePersistedView({ view, columnKeys }) {
|
|
23
|
+
if (!type.isObject(view)) return null;
|
|
24
|
+
const sanitized = {};
|
|
25
|
+
Object.keys(view).forEach((key)=>{
|
|
26
|
+
if (KNOWN_KEYS.has(key)) sanitized[key] = view[key];
|
|
27
|
+
});
|
|
28
|
+
if (!type.isArray(view.columns)) {
|
|
29
|
+
delete sanitized.columns;
|
|
30
|
+
return sanitized;
|
|
31
|
+
}
|
|
32
|
+
const declared = new Set(columnKeys);
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
const columns = [];
|
|
35
|
+
view.columns.forEach((entry)=>{
|
|
36
|
+
if (!type.isObject(entry) || !declared.has(entry.key) || seen.has(entry.key)) return;
|
|
37
|
+
seen.add(entry.key);
|
|
38
|
+
columns.push(entry);
|
|
39
|
+
});
|
|
40
|
+
columnKeys.forEach((key)=>{
|
|
41
|
+
if (!seen.has(key)) columns.push({
|
|
42
|
+
key,
|
|
43
|
+
hidden: true
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
sanitized.columns = columns;
|
|
47
|
+
return sanitized;
|
|
48
|
+
}
|
|
49
|
+
export default sanitizePersistedView;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
// JSON with object keys sorted, so two views that differ only in key order compare equal.
|
|
17
|
+
function stableStringify(value) {
|
|
18
|
+
if (type.isArray(value)) {
|
|
19
|
+
return `[${value.map((item)=>stableStringify(item ?? null)).join(',')}]`;
|
|
20
|
+
}
|
|
21
|
+
if (type.isObject(value)) {
|
|
22
|
+
const entries = Object.keys(value).filter((key)=>!type.isUndefined(value[key])).sort().map((key)=>`${JSON.stringify(key)}:${stableStringify(value[key])}`);
|
|
23
|
+
return `{${entries.join(',')}}`;
|
|
24
|
+
}
|
|
25
|
+
return JSON.stringify(value ?? null);
|
|
26
|
+
}
|
|
27
|
+
export default stableStringify;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { useEffect, useMemo, useRef, useState } from 'react';
|
|
16
|
+
import { type } from '@lowdefy/helpers';
|
|
17
|
+
import compactView from './compactView.js';
|
|
18
|
+
import createViewsApi from './createViewsApi.js';
|
|
19
|
+
import findActiveView from './findActiveView.js';
|
|
20
|
+
import getViewKey from './getViewKey.js';
|
|
21
|
+
import getViewSliceDeps from './getViewSliceDeps.js';
|
|
22
|
+
import isViewDirty from './isViewDirty.js';
|
|
23
|
+
import normalizeViews from './normalizeViews.js';
|
|
24
|
+
import readMountPayload from './readMountPayload.js';
|
|
25
|
+
import useStableConfig from '../../core/useStableConfig.js';
|
|
26
|
+
import writePersistedView from './writePersistedView.js';
|
|
27
|
+
// Saved views (D7) and view persistence (D6). The active view is block UI state: it starts from
|
|
28
|
+
// the persisted payload, then `activeView`, then the first view, and follows `activeView` when the
|
|
29
|
+
// app changes it. The current view is compared with the active saved view for the dirty strip,
|
|
30
|
+
// and written to storage after every view change.
|
|
31
|
+
function useViews({ api, config, state }) {
|
|
32
|
+
const viewsConfig = useStableConfig(api.properties.views);
|
|
33
|
+
const views = useMemo(()=>normalizeViews(viewsConfig), [
|
|
34
|
+
viewsConfig
|
|
35
|
+
]);
|
|
36
|
+
const activeProp = api.properties.activeView;
|
|
37
|
+
// By key: an object id (`{ _oid }`) is a new object every time the engine evaluates it.
|
|
38
|
+
const activePropKey = type.isNone(activeProp) ? null : getViewKey(activeProp);
|
|
39
|
+
const { persist } = config;
|
|
40
|
+
const enabled = views.length > 0 || persist !== null;
|
|
41
|
+
const mount = useRef(null);
|
|
42
|
+
if (mount.current === null) {
|
|
43
|
+
const payload = readMountPayload({
|
|
44
|
+
config
|
|
45
|
+
});
|
|
46
|
+
const mountedActive = findActiveView({
|
|
47
|
+
views,
|
|
48
|
+
id: payload?.activeView ?? activeProp
|
|
49
|
+
});
|
|
50
|
+
mount.current = {
|
|
51
|
+
activeId: payload?.activeView ?? activeProp ?? null,
|
|
52
|
+
// Views that load after mount (from a request) load the active one, unless the table
|
|
53
|
+
// mounted with a value of its own or a persisted view.
|
|
54
|
+
pendingLoad: type.isNone(api.value) && payload === null && mountedActive === null
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const [activeId, setActiveId] = useState(mount.current.activeId);
|
|
58
|
+
const pendingLoad = useRef(mount.current.pendingLoad);
|
|
59
|
+
const lastActiveProp = useRef(activePropKey);
|
|
60
|
+
const active = useMemo(()=>findActiveView({
|
|
61
|
+
views,
|
|
62
|
+
id: activeId
|
|
63
|
+
}), [
|
|
64
|
+
views,
|
|
65
|
+
activeId
|
|
66
|
+
]);
|
|
67
|
+
const viewDeps = getViewSliceDeps(state);
|
|
68
|
+
const currentView = useMemo(()=>enabled ? api.getValue().view : null, [
|
|
69
|
+
enabled,
|
|
70
|
+
...viewDeps
|
|
71
|
+
]);
|
|
72
|
+
const defaults = useMemo(()=>enabled ? api.resolveValue(null).view : null, [
|
|
73
|
+
enabled,
|
|
74
|
+
config
|
|
75
|
+
]);
|
|
76
|
+
const savedView = useMemo(()=>active === null ? null : api.resolveValue({
|
|
77
|
+
view: active.view
|
|
78
|
+
}).view, [
|
|
79
|
+
active,
|
|
80
|
+
config
|
|
81
|
+
]);
|
|
82
|
+
const dirty = savedView !== null && isViewDirty({
|
|
83
|
+
current: currentView,
|
|
84
|
+
saved: savedView,
|
|
85
|
+
defaults
|
|
86
|
+
});
|
|
87
|
+
const viewsApi = createViewsApi({
|
|
88
|
+
api,
|
|
89
|
+
active,
|
|
90
|
+
currentView,
|
|
91
|
+
dirty,
|
|
92
|
+
setActiveId,
|
|
93
|
+
views
|
|
94
|
+
});
|
|
95
|
+
api.views = viewsApi;
|
|
96
|
+
useEffect(()=>{
|
|
97
|
+
if (lastActiveProp.current === activePropKey) return;
|
|
98
|
+
lastActiveProp.current = activePropKey;
|
|
99
|
+
pendingLoad.current = true;
|
|
100
|
+
setActiveId(activeProp ?? null);
|
|
101
|
+
}, [
|
|
102
|
+
activePropKey
|
|
103
|
+
]);
|
|
104
|
+
useEffect(()=>{
|
|
105
|
+
if (!pendingLoad.current || active === null) return;
|
|
106
|
+
pendingLoad.current = false;
|
|
107
|
+
if (dirty) viewsApi.load(active);
|
|
108
|
+
}, [
|
|
109
|
+
active
|
|
110
|
+
]);
|
|
111
|
+
const lastWritten = useRef(null);
|
|
112
|
+
useEffect(()=>{
|
|
113
|
+
if (persist === null) return;
|
|
114
|
+
const payload = {
|
|
115
|
+
view: compactView({
|
|
116
|
+
view: currentView,
|
|
117
|
+
defaults
|
|
118
|
+
}),
|
|
119
|
+
activeView: active?.key ?? null
|
|
120
|
+
};
|
|
121
|
+
const json = JSON.stringify(payload);
|
|
122
|
+
if (json === lastWritten.current) return;
|
|
123
|
+
lastWritten.current = json;
|
|
124
|
+
writePersistedView({
|
|
125
|
+
persist,
|
|
126
|
+
payload
|
|
127
|
+
});
|
|
128
|
+
}, [
|
|
129
|
+
currentView,
|
|
130
|
+
active,
|
|
131
|
+
defaults,
|
|
132
|
+
persist
|
|
133
|
+
]);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
export default useViews;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // The parts of a table view (design D6). Stored and loaded views keep only these.
|
|
16
|
+
const viewKeys = [
|
|
17
|
+
'columns',
|
|
18
|
+
'sort',
|
|
19
|
+
'filter',
|
|
20
|
+
'search',
|
|
21
|
+
'group',
|
|
22
|
+
'collapsedGroups',
|
|
23
|
+
'aggregates',
|
|
24
|
+
'density',
|
|
25
|
+
'wrap',
|
|
26
|
+
'pageSize'
|
|
27
|
+
];
|
|
28
|
+
export default viewKeys;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import mountViewValue from './mountViewValue.js';
|
|
16
|
+
import notifyViewSelect from './notifyViewSelect.js';
|
|
17
|
+
import useViews from './useViews.js';
|
|
18
|
+
// Saved views and view persistence. `mountValue` supplies the view a table mounts with when it
|
|
19
|
+
// has no value: the persisted view, else the active saved view.
|
|
20
|
+
const viewsFeature = {
|
|
21
|
+
name: 'views',
|
|
22
|
+
mountValue: mountViewValue,
|
|
23
|
+
onCommit: notifyViewSelect,
|
|
24
|
+
useFeature: useViews
|
|
25
|
+
};
|
|
26
|
+
export default viewsFeature;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import encodeViewParam from './encodeViewParam.js';
|
|
17
|
+
import getStorageKey from './getStorageKey.js';
|
|
18
|
+
function isEmptyPayload(payload) {
|
|
19
|
+
return Object.keys(payload.view).length === 0 && type.isNone(payload.activeView);
|
|
20
|
+
}
|
|
21
|
+
// Writes the payload `{ view, activeView }`. The URL is replaced, never pushed: a view tweak is
|
|
22
|
+
// not a navigation, so Back still leaves the page.
|
|
23
|
+
function writePersistedView({ persist, payload }) {
|
|
24
|
+
if (persist.storage === 'url') {
|
|
25
|
+
const url = new URL(window.location.href);
|
|
26
|
+
if (isEmptyPayload(payload)) {
|
|
27
|
+
url.searchParams.delete(persist.key);
|
|
28
|
+
} else {
|
|
29
|
+
url.searchParams.set(persist.key, encodeViewParam(payload));
|
|
30
|
+
}
|
|
31
|
+
if (url.href !== window.location.href) {
|
|
32
|
+
window.history.replaceState(window.history.state, '', url.href);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
window.localStorage.setItem(getStorageKey(persist.key), JSON.stringify(payload));
|
|
38
|
+
} catch {
|
|
39
|
+
// Blocked or full storage: the view lives for the session only.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export default writePersistedView;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // Each display item's top offset in the body, and the body height last (`rows.length + 1`
|
|
16
|
+
// entries), for lists whose items are not all one row high: `heightOf(item, index)` gives an
|
|
17
|
+
// item's measured height or estimate, undefined for one row.
|
|
18
|
+
function computeRowOffsets({ rows, rowHeight, heightOf }) {
|
|
19
|
+
const count = rows.length;
|
|
20
|
+
const offsets = new Float64Array(count + 1);
|
|
21
|
+
let top = 0;
|
|
22
|
+
for(let i = 0; i < count; i++){
|
|
23
|
+
offsets[i] = top;
|
|
24
|
+
top += heightOf(rows[i], i) ?? rowHeight;
|
|
25
|
+
}
|
|
26
|
+
offsets[count] = top;
|
|
27
|
+
return offsets;
|
|
28
|
+
}
|
|
29
|
+
export default computeRowOffsets;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import firstIndexAbove from './firstIndexAbove.js';
|
|
16
|
+
// Centre columns rendered beyond each edge of the viewport (MUI's column buffer).
|
|
17
|
+
const COLUMN_OVERSCAN_PX = 150;
|
|
18
|
+
function clamp(value, min, max) {
|
|
19
|
+
return Math.min(max, Math.max(min, value));
|
|
20
|
+
}
|
|
21
|
+
function fixedRowRange({ rowCount, rowHeight, top, bottom }) {
|
|
22
|
+
const rowStart = clamp(Math.floor(top / rowHeight), 0, rowCount);
|
|
23
|
+
const rowEnd = clamp(Math.ceil(bottom / rowHeight), rowStart, rowCount);
|
|
24
|
+
return {
|
|
25
|
+
rowStart,
|
|
26
|
+
rowEnd
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// With `rowOffsets` (each item's top, and the total height last): the first item whose bottom is
|
|
30
|
+
// below `top`, up to the first item whose top is below `bottom`.
|
|
31
|
+
function offsetRowRange({ rowOffsets: offsets, rowCount, top, bottom }) {
|
|
32
|
+
const rowStart = clamp(firstIndexAbove({
|
|
33
|
+
offsets: offsets.subarray(1),
|
|
34
|
+
value: top
|
|
35
|
+
}), 0, rowCount);
|
|
36
|
+
const rowEnd = clamp(firstIndexAbove({
|
|
37
|
+
offsets: offsets.subarray(0, rowCount),
|
|
38
|
+
value: bottom
|
|
39
|
+
}), rowStart, rowCount);
|
|
40
|
+
return {
|
|
41
|
+
rowStart,
|
|
42
|
+
rowEnd
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// The rendered row and centre-column ranges for a scroll position. Row overscan is measured in
|
|
46
|
+
// pixels and leans in the scroll direction: one body height ahead, a quarter behind (D10.3).
|
|
47
|
+
// `rowOffsets` (see useRowOffsets) replaces the fixed row height when items differ in height.
|
|
48
|
+
function computeWindow({ direction, headerHeight, layout, rowCount, rowHeight, rowOffsets, scrollLeft, scrollTop, viewportHeight, viewportWidth, virtualColumns, virtualRows }) {
|
|
49
|
+
let rowStart = 0;
|
|
50
|
+
let rowEnd = rowCount;
|
|
51
|
+
if (virtualRows) {
|
|
52
|
+
const bodyHeight = Math.max(rowHeight, viewportHeight - headerHeight);
|
|
53
|
+
const lead = bodyHeight;
|
|
54
|
+
const trail = Math.round(bodyHeight / 4);
|
|
55
|
+
let before = trail;
|
|
56
|
+
let after = trail;
|
|
57
|
+
if (direction < 0) before = lead;
|
|
58
|
+
if (direction > 0) after = lead;
|
|
59
|
+
const bounds = {
|
|
60
|
+
rowCount,
|
|
61
|
+
top: scrollTop - before,
|
|
62
|
+
bottom: scrollTop + bodyHeight + after
|
|
63
|
+
};
|
|
64
|
+
({ rowStart, rowEnd } = rowOffsets ? offsetRowRange({
|
|
65
|
+
rowOffsets,
|
|
66
|
+
...bounds
|
|
67
|
+
}) : fixedRowRange({
|
|
68
|
+
rowHeight,
|
|
69
|
+
...bounds
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
let colStart = 0;
|
|
73
|
+
let colEnd = layout.center.length;
|
|
74
|
+
if (virtualColumns && colEnd > 0) {
|
|
75
|
+
const centerViewport = Math.max(0, viewportWidth - layout.startWidth - layout.endWidth);
|
|
76
|
+
colStart = firstIndexAbove({
|
|
77
|
+
offsets: layout.centerEnds,
|
|
78
|
+
value: scrollLeft - COLUMN_OVERSCAN_PX
|
|
79
|
+
});
|
|
80
|
+
colEnd = Math.max(colStart, firstIndexAbove({
|
|
81
|
+
offsets: layout.centerStarts,
|
|
82
|
+
value: scrollLeft + centerViewport + COLUMN_OVERSCAN_PX
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
colEnd,
|
|
87
|
+
colStart,
|
|
88
|
+
rowEnd,
|
|
89
|
+
rowStart
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export default computeWindow;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import scrollToCell from './scrollToCell.js';
|
|
17
|
+
import isDataItem from '../../core/isDataItem.js';
|
|
18
|
+
// Block method `scrollToRow({ rowKey, align })`; returns false when no loaded row has that key.
|
|
19
|
+
function createScrollToRow(api) {
|
|
20
|
+
return function scrollToRow({ rowKey, align } = {}) {
|
|
21
|
+
if (type.isNone(rowKey)) {
|
|
22
|
+
throw new Error('scrollToRow requires "rowKey".');
|
|
23
|
+
}
|
|
24
|
+
const id = String(rowKey);
|
|
25
|
+
const index = api.rows.findIndex((row)=>isDataItem(row) && row.id === id);
|
|
26
|
+
if (index === -1) return false;
|
|
27
|
+
scrollToCell({
|
|
28
|
+
api,
|
|
29
|
+
row: index,
|
|
30
|
+
col: -1,
|
|
31
|
+
align: align ?? 'center'
|
|
32
|
+
});
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export default createScrollToRow;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // Binary search over ascending offsets: the first index whose offset is greater than `value`
|
|
16
|
+
// (or `offsets.length`).
|
|
17
|
+
function firstIndexAbove({ offsets, value }) {
|
|
18
|
+
let low = 0;
|
|
19
|
+
let high = offsets.length;
|
|
20
|
+
while(low < high){
|
|
21
|
+
const mid = low + high >>> 1;
|
|
22
|
+
if (offsets[mid] > value) {
|
|
23
|
+
high = mid;
|
|
24
|
+
} else {
|
|
25
|
+
low = mid + 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return low;
|
|
29
|
+
}
|
|
30
|
+
export default firstIndexAbove;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import isDataItem from '../../core/isDataItem.js';
|
|
16
|
+
// The key a display item's measured height is cached under (its element's `data-measure-key`):
|
|
17
|
+
// the row id for data rows, `kind:key` for other items, null for a row that is not loaded yet.
|
|
18
|
+
function getMeasureKey(item) {
|
|
19
|
+
if (item === undefined) return null;
|
|
20
|
+
if (isDataItem(item)) return item.id;
|
|
21
|
+
return `${item.kind}:${item.key}`;
|
|
22
|
+
}
|
|
23
|
+
export default getMeasureKey;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // Wrapped text and multi-line ellipsis make rows as tall as their content (D10.1).
|
|
16
|
+
function isMeasuredColumn(col) {
|
|
17
|
+
if (col.special) return false;
|
|
18
|
+
return col.column.wrap === true || col.column.ellipsis > 1;
|
|
19
|
+
}
|
|
20
|
+
export default isMeasuredColumn;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ function isSameRange(a, b) {
|
|
16
|
+
return a.rowStart === b.rowStart && a.rowEnd === b.rowEnd && a.colStart === b.colStart && a.colEnd === b.colEnd;
|
|
17
|
+
}
|
|
18
|
+
export default isSameRange;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import usePositionedRows from './usePositionedRows.js';
|
|
16
|
+
// The benchmark's comparison strategy (`rowWindowStrategy: 'positioned'`), with TanStack Virtual,
|
|
17
|
+
// loaded only when a table is mounted with it; the Lowdefy client never sets it.
|
|
18
|
+
const positionedRowsFeature = {
|
|
19
|
+
name: 'positionedRows',
|
|
20
|
+
useGridFeature: usePositionedRows
|
|
21
|
+
};
|
|
22
|
+
export default positionedRowsFeature;
|