@redsift/table 12.5.3-alpha.5 → 12.5.3-alpha.6

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/index.d.ts CHANGED
@@ -338,10 +338,22 @@ declare const DENSITY_MODEL_KEY = "densityModel";
338
338
  declare const COLUMN_ORDER_MODEL_KEY = "columnOrderModel";
339
339
  declare const ROW_GROUPING_MODEL_KEY = "rowGroupingModel";
340
340
  declare const AGGREGATION_MODEL_KEY = "aggregationModel";
341
+ /** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
341
342
  declare const PIVOT_MODEL_KEY = "pivotModel";
343
+ /** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
342
344
  declare const PIVOT_ACTIVE_KEY = "pivotActive";
343
345
  declare const CATEGORIES: readonly ["paginationModel", "filterModel", "sortModel", "visibilityModel", "dimension", "searchModel", "pinnedColumns", "densityModel", "columnOrderModel", "rowGroupingModel", "aggregationModel", "pivotModel", "pivotActive"];
344
346
  type Category = (typeof CATEGORIES)[number];
347
+ /**
348
+ * Build the localStorage key for a specific grid state category.
349
+ * Consumers can use this to read or clear individual state entries directly.
350
+ *
351
+ * @example
352
+ * ```ts
353
+ * const key = buildStorageKey({ id: pathname, version: 2, category: PIVOT_ACTIVE_KEY });
354
+ * localStorage.removeItem(key);
355
+ * ```
356
+ */
345
357
  declare const buildStorageKey: ({ id, version, category }: {
346
358
  id: string;
347
359
  version: number;
@@ -946,6 +958,104 @@ type DataGridModel = {
946
958
  declare const updateUrl: ({ filterModel, sortModel, paginationModel, columnsModel: columnsVisibilityModel, pinnedColumnsModel, density, columnOrderModel, defaultColumnOrder, rowGroupingModel, aggregationModel, pivotModel, pivotActive, }: DataGridModel, search: string, localStorageVersion: number, historyReplace: (newSearch: string) => void, columns: DataGridProps["columns"]) => void;
947
959
  declare const areFilterModelsEquivalent: (filterModel: GridFilterModel, filterModelToMatch: GridFilterModel) => boolean;
948
960
 
961
+ /**
962
+ * A React Router v5 / connected-react-router adapter for `StatefulDataGrid.useRouter`.
963
+ *
964
+ * Defers `history.replace` via `queueMicrotask` to avoid the
965
+ * "Cannot update during an existing state transition" warning
966
+ * that connected-react-router triggers when the grid synchronises
967
+ * URL state during render.
968
+ *
969
+ * @example
970
+ * ```tsx
971
+ * import { createReactRouterV5Adapter } from '@redsift/table';
972
+ *
973
+ * const useRouter = createReactRouterV5Adapter(history);
974
+ *
975
+ * <StatefulDataGrid useRouter={useRouter} … />
976
+ * ```
977
+ */
978
+ /** Minimal subset of React Router v5 `history` used by the adapter. */
979
+ interface ReactRouterV5History {
980
+ location: {
981
+ pathname: string;
982
+ search: string;
983
+ };
984
+ replace: (path: {
985
+ pathname: string;
986
+ search: string;
987
+ }) => void;
988
+ }
989
+ /**
990
+ * Create a `useRouter` hook compatible with `StatefulDataGrid` from a
991
+ * React Router v5 `history` object.
992
+ */
993
+ declare const createReactRouterV5Adapter: (history: ReactRouterV5History) => (() => {
994
+ pathname: string;
995
+ search: string;
996
+ historyReplace: (newSearch: string) => void;
997
+ });
998
+
999
+ interface UseLinkedFilterModelOptions {
1000
+ /** Starting filter model. Defaults to `{ items: [] }`. */
1001
+ initialFilterModel?: GridFilterModel;
1002
+ /**
1003
+ * Debounce window (ms) applied to changes coming from the DataGrid filter panel.
1004
+ * Card-driven changes via `setMultiSelect` / `setBoolean` are never debounced.
1005
+ * Defaults to `300`. Pass `0` to disable.
1006
+ */
1007
+ debounceMs?: number;
1008
+ /** Optional callback fired on every settled filter model change. */
1009
+ onChange?: (model: GridFilterModel) => void;
1010
+ }
1011
+ interface UseLinkedFilterModelReturn {
1012
+ /** Current filter model. Pass to DataGrid `filterModel` and read for DataCard derivations. */
1013
+ filterModel: GridFilterModel;
1014
+ /** Bind to DataGrid `onFilterModelChange`. Debounced for panel changes. */
1015
+ onFilterModelChange: (model: GridFilterModel) => void;
1016
+ /** Read selected values for an `isAnyOf` / `hasAnyOf` field. Empty array when not set. */
1017
+ getSelected: (field: string) => string[];
1018
+ /** Read the raw filter value for a field (e.g. boolean toggles). */
1019
+ getValue: (field: string) => unknown;
1020
+ /** Set a multi-select filter from a DataCard. Empty array clears the field. */
1021
+ setMultiSelect: (field: string, values: string[], operator?: string) => void;
1022
+ /** Set a boolean filter. Pass `null` to clear. */
1023
+ setBoolean: (field: string, value: boolean | null) => void;
1024
+ /** Remove a single field from the filter model. */
1025
+ clearField: (field: string) => void;
1026
+ /** Reset the filter model to the initial value. */
1027
+ reset: () => void;
1028
+ /**
1029
+ * Whether a field's filter was set externally (DataGrid filter panel) rather than
1030
+ * via this hook's setters. Useful for disabling the corresponding DataCard so the
1031
+ * panel and card don't fight over the same field.
1032
+ */
1033
+ isFieldExternallyControlled: (field: string) => boolean;
1034
+ }
1035
+ /**
1036
+ * Bridge a DataGrid `filterModel` and the DataCards that drive (and reflect) it.
1037
+ *
1038
+ * Without this hook, every drilldowned datagrid page hand-rolls the same plumbing:
1039
+ * derive selections from `filterModel`, write them back via raw `setFilterModel`
1040
+ * mutations, debounce panel changes, and track which fields the panel "owns" so
1041
+ * cards don't fight the panel for control. SOFA-6 shipped this logic ad hoc and
1042
+ * got it wrong (no debounce, prop-drilled state, no panel/card reconciliation).
1043
+ *
1044
+ * @example
1045
+ * const filter = useLinkedFilterModel();
1046
+ *
1047
+ * <DataCard.Listbox
1048
+ * values={filter.getSelected('Category')}
1049
+ * onChange={(values) => filter.setMultiSelect('Category', values)}
1050
+ * isDisabled={filter.isFieldExternallyControlled('Category')}
1051
+ * >
1052
+ * {…}
1053
+ * </DataCard.Listbox>
1054
+ *
1055
+ * <DataGrid filterModel={filter.filterModel} onFilterModelChange={filter.onFilterModelChange} />
1056
+ */
1057
+ declare function useLinkedFilterModel(options?: UseLinkedFilterModelOptions): UseLinkedFilterModelReturn;
1058
+
949
1059
  declare const BaseButton: React$1.JSXElementConstructor<any>;
950
1060
 
951
1061
  declare const BaseCheckbox: React$1.JSXElementConstructor<any>;
@@ -1151,4 +1261,4 @@ type ToolbarWrapperProps = {
1151
1261
  };
1152
1262
  declare const ToolbarWrapper: React$1.FC<ToolbarWrapperProps>;
1153
1263
 
1154
- export { AGGREGATION_MODEL_KEY, ARRAY_IS_EMPTY, ARRAY_IS_NOT_EMPTY, BaseButton, BaseCheckbox, BaseIcon, BaseIconButton, BaseTextField, CATEGORIES, COLUMN_ORDER_MODEL_KEY, CONTAINS_ANY_OF, Category, ColumnOptions, ColumnOrderModel, ColumnType, CompletionResponse, ControlledPagination, ControlledPaginationProps, DATE_IS_BETWEEN, DEFAULT_OPERATORS, DENSITY_MODEL_KEY, DETAIL_PANEL_TOGGLE_COL_DEF, DIMENSION_MODEL_KEY, DOES_NOT_CONTAIN, DOES_NOT_CONTAIN_ANY_OF, DOES_NOT_END_WITH, DOES_NOT_END_WITH_ANY_OF, DOES_NOT_EQUAL, DOES_NOT_HAVE, DOES_NOT_HAVE_ANY_OF, DOES_NOT_HAVE_ANY_OF_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, DOES_NOT_START_WITH, DOES_NOT_START_WITH_ANY_OF, DataGrid, DataGridModel, DataGridProps, DateOperatorName, EMPTY_ROW_SELECTION_MODEL, ENDS_WITH_ANY_OF, FILTER_MODEL_KEY, FILTER_SEARCH_KEY, FilterConfig, FilterConfigColumn, GridDensityValue, GridToolbarFilterSemanticField, GridToolbarFilterSemanticFieldProps, HAS, HAS_ALL_OF, HAS_ALL_OF_WITH_SELECT, HAS_ANY_OF, HAS_ANY_OF_WITH_SELECT, HAS_ONLY, HAS_ONLY_WITH_SELECT, HAS_WITH_SELECT, IS, IS_ANY_OF, IS_ANY_OF_I, IS_ANY_OF_I_WITH_SELECT, IS_ANY_OF_WITH_SELECT, IS_BETWEEN, IS_NOT, IS_NOT_ANY_OF, IS_NOT_ANY_OF_WITH_SELECT, IS_NOT_WITH_SELECT, IS_WITH_SELECT, LegacyRowSelectionModel, MultiSelectOperatorName, NumberOperatorName, PAGINATION_MODEL_KEY, PINNED_COLUMNS, PIVOT_ACTIVE_KEY, PIVOT_MODEL_KEY, PinnedColumns, PivotModel, ROW_GROUPING_MODEL_KEY, RowSelectionModelInput, SORT_MODEL_KEY, STARTS_WITH_ANY_OF, SelectionStatus, ServerSideControlledPagination, ServerSideControlledPaginationProps, SingleSelectOperatorName, StatefulDataGrid, StatefulDataGridProps, StringOperatorName, StyledDataGridProps, TagsOperatorName, TextCell, Toolbar, ToolbarWrapper, ToolbarWrapperProps, VISIBILITY_MODEL_KEY, areFilterModelsEquivalent, areSearchStringsEqual, buildQueryParamsString, buildStorageKey, clearAllVersionStorage, clearPreviousVersionStorage, convertFromDisplayFormat, convertToDisplayFormat, createColumn, createRowSelectionModel, customColumnTypes, decodeValue, encodeValue, fixServerSideHeaderCheckboxSelection, fromGridPivotModel, getAggregationFromString, getColumnOrderFromString, getColumnVisibilityFromString, getCompletion, getDecodedSearchFromUrl, getDensityFromString, getDensityModel, getFilterModelFromString, getFinalSearch, getGridDateOperatorsExtended, getGridNumericOperators, getGridStringArrayOperators, getGridStringArrayOperatorsWithSelect, getGridStringArrayOperatorsWithSelectOnStringArrayColumns, getGridStringOperators, getModelsParsedOrUpdateLocalStorage, getPaginationFromString, getPinnedColumnsFromString, getPivotActiveFromString, getPivotFromString, getRowGroupingFromString, getRsMultipleSelectColumnType, getRsMultipleSelectWithShortOperatorListColumnType, getRsNumberColumnType, getRsSingleSelectColumnType, getRsSingleSelectWithShortOperatorListColumnType, getRsStringColumnType, getSearchParamsFromAggregation, getSearchParamsFromColumnOrder, getSearchParamsFromColumnVisibility, getSearchParamsFromDensity, getSearchParamsFromFilterModel, getSearchParamsFromPagination, getSearchParamsFromPinnedColumns, getSearchParamsFromPivot, getSearchParamsFromPivotActive, getSearchParamsFromRowGrouping, getSearchParamsFromSorting, getSearchParamsFromTab, getSelectableRowIdsInPage, getSelectedIds, getSelectionCount, getSortingFromString, isOperatorValueValid, isRowSelected, isValueValid, makeCaseInsensitive, muiIconToDSIcon, normalizeRowSelectionModel, numberOperatorDecoder, numberOperatorEncoder, onServerSideSelectionStatusChange, operatorList, resetStatefulDataGridState, updateUrl, urlSearchParamsToString, wrapCaseInsensitive };
1264
+ export { AGGREGATION_MODEL_KEY, ARRAY_IS_EMPTY, ARRAY_IS_NOT_EMPTY, BaseButton, BaseCheckbox, BaseIcon, BaseIconButton, BaseTextField, CATEGORIES, COLUMN_ORDER_MODEL_KEY, CONTAINS_ANY_OF, Category, ColumnOptions, ColumnOrderModel, ColumnType, CompletionResponse, ControlledPagination, ControlledPaginationProps, DATE_IS_BETWEEN, DEFAULT_OPERATORS, DENSITY_MODEL_KEY, DETAIL_PANEL_TOGGLE_COL_DEF, DIMENSION_MODEL_KEY, DOES_NOT_CONTAIN, DOES_NOT_CONTAIN_ANY_OF, DOES_NOT_END_WITH, DOES_NOT_END_WITH_ANY_OF, DOES_NOT_EQUAL, DOES_NOT_HAVE, DOES_NOT_HAVE_ANY_OF, DOES_NOT_HAVE_ANY_OF_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, DOES_NOT_START_WITH, DOES_NOT_START_WITH_ANY_OF, DataGrid, DataGridModel, DataGridProps, DateOperatorName, EMPTY_ROW_SELECTION_MODEL, ENDS_WITH_ANY_OF, FILTER_MODEL_KEY, FILTER_SEARCH_KEY, FilterConfig, FilterConfigColumn, GridDensityValue, GridToolbarFilterSemanticField, GridToolbarFilterSemanticFieldProps, HAS, HAS_ALL_OF, HAS_ALL_OF_WITH_SELECT, HAS_ANY_OF, HAS_ANY_OF_WITH_SELECT, HAS_ONLY, HAS_ONLY_WITH_SELECT, HAS_WITH_SELECT, IS, IS_ANY_OF, IS_ANY_OF_I, IS_ANY_OF_I_WITH_SELECT, IS_ANY_OF_WITH_SELECT, IS_BETWEEN, IS_NOT, IS_NOT_ANY_OF, IS_NOT_ANY_OF_WITH_SELECT, IS_NOT_WITH_SELECT, IS_WITH_SELECT, LegacyRowSelectionModel, MultiSelectOperatorName, NumberOperatorName, PAGINATION_MODEL_KEY, PINNED_COLUMNS, PIVOT_ACTIVE_KEY, PIVOT_MODEL_KEY, PinnedColumns, PivotModel, ROW_GROUPING_MODEL_KEY, ReactRouterV5History, RowSelectionModelInput, SORT_MODEL_KEY, STARTS_WITH_ANY_OF, SelectionStatus, ServerSideControlledPagination, ServerSideControlledPaginationProps, SingleSelectOperatorName, StatefulDataGrid, StatefulDataGridProps, StringOperatorName, StyledDataGridProps, TagsOperatorName, TextCell, Toolbar, ToolbarWrapper, ToolbarWrapperProps, UseLinkedFilterModelOptions, UseLinkedFilterModelReturn, VISIBILITY_MODEL_KEY, areFilterModelsEquivalent, areSearchStringsEqual, buildQueryParamsString, buildStorageKey, clearAllVersionStorage, clearPreviousVersionStorage, convertFromDisplayFormat, convertToDisplayFormat, createColumn, createReactRouterV5Adapter, createRowSelectionModel, customColumnTypes, decodeValue, encodeValue, fixServerSideHeaderCheckboxSelection, fromGridPivotModel, getAggregationFromString, getColumnOrderFromString, getColumnVisibilityFromString, getCompletion, getDecodedSearchFromUrl, getDensityFromString, getDensityModel, getFilterModelFromString, getFinalSearch, getGridDateOperatorsExtended, getGridNumericOperators, getGridStringArrayOperators, getGridStringArrayOperatorsWithSelect, getGridStringArrayOperatorsWithSelectOnStringArrayColumns, getGridStringOperators, getModelsParsedOrUpdateLocalStorage, getPaginationFromString, getPinnedColumnsFromString, getPivotActiveFromString, getPivotFromString, getRowGroupingFromString, getRsMultipleSelectColumnType, getRsMultipleSelectWithShortOperatorListColumnType, getRsNumberColumnType, getRsSingleSelectColumnType, getRsSingleSelectWithShortOperatorListColumnType, getRsStringColumnType, getSearchParamsFromAggregation, getSearchParamsFromColumnOrder, getSearchParamsFromColumnVisibility, getSearchParamsFromDensity, getSearchParamsFromFilterModel, getSearchParamsFromPagination, getSearchParamsFromPinnedColumns, getSearchParamsFromPivot, getSearchParamsFromPivotActive, getSearchParamsFromRowGrouping, getSearchParamsFromSorting, getSearchParamsFromTab, getSelectableRowIdsInPage, getSelectedIds, getSelectionCount, getSortingFromString, isOperatorValueValid, isRowSelected, isValueValid, makeCaseInsensitive, muiIconToDSIcon, normalizeRowSelectionModel, numberOperatorDecoder, numberOperatorEncoder, onServerSideSelectionStatusChange, operatorList, resetStatefulDataGridState, updateUrl, urlSearchParamsToString, useLinkedFilterModel, wrapCaseInsensitive };
package/index.js CHANGED
@@ -4,6 +4,7 @@ import { GRID_DETAIL_PANEL_TOGGLE_COL_DEF, GridFilterInputMultipleValue, GridFil
4
4
  export { getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators } from '@mui/x-data-grid-premium';
5
5
  import { _ as _objectSpread2 } from './_internal/_rollupPluginBabelHelpers.js';
6
6
  import * as React from 'react';
7
+ import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
7
8
  import Box from '@mui/material/Box';
8
9
  import TextField from '@mui/material/TextField';
9
10
  import { Icon } from '@redsift/design-system';
@@ -415,5 +416,236 @@ function getOperatorsForType(type, compact) {
415
416
  }
416
417
  }
417
418
 
418
- export { DATE_IS_BETWEEN, DETAIL_PANEL_TOGGLE_COL_DEF, IS_ANY_OF_I, IS_ANY_OF_I_WITH_SELECT, createColumn, customColumnTypes, getGridDateOperatorsExtended, getRsMultipleSelectColumnType, getRsMultipleSelectWithShortOperatorListColumnType, getRsNumberColumnType, getRsSingleSelectColumnType, getRsSingleSelectWithShortOperatorListColumnType, getRsStringColumnType, makeCaseInsensitive, wrapCaseInsensitive };
419
+ /**
420
+ * A React Router v5 / connected-react-router adapter for `StatefulDataGrid.useRouter`.
421
+ *
422
+ * Defers `history.replace` via `queueMicrotask` to avoid the
423
+ * "Cannot update during an existing state transition" warning
424
+ * that connected-react-router triggers when the grid synchronises
425
+ * URL state during render.
426
+ *
427
+ * @example
428
+ * ```tsx
429
+ * import { createReactRouterV5Adapter } from '@redsift/table';
430
+ *
431
+ * const useRouter = createReactRouterV5Adapter(history);
432
+ *
433
+ * <StatefulDataGrid useRouter={useRouter} … />
434
+ * ```
435
+ */
436
+
437
+ /** Minimal subset of React Router v5 `history` used by the adapter. */
438
+
439
+ /**
440
+ * Create a `useRouter` hook compatible with `StatefulDataGrid` from a
441
+ * React Router v5 `history` object.
442
+ */
443
+ const createReactRouterV5Adapter = history => {
444
+ return () => ({
445
+ pathname: history.location.pathname,
446
+ search: history.location.search.replace(/^\?/, ''),
447
+ historyReplace: newSearch => {
448
+ queueMicrotask(() => {
449
+ history.replace({
450
+ pathname: history.location.pathname,
451
+ search: newSearch ? `?${newSearch}` : ''
452
+ });
453
+ });
454
+ }
455
+ });
456
+ };
457
+
458
+ const EMPTY_FILTER_MODEL = {
459
+ items: []
460
+ };
461
+ const sameItems = (a, b) => JSON.stringify(a.items) === JSON.stringify(b.items);
462
+ const filterOutField = (model, field) => model.items.filter(item => item.field !== field);
463
+ const nextItemId = (() => {
464
+ let id = 1;
465
+ return () => id++;
466
+ })();
467
+
468
+ /**
469
+ * Bridge a DataGrid `filterModel` and the DataCards that drive (and reflect) it.
470
+ *
471
+ * Without this hook, every drilldowned datagrid page hand-rolls the same plumbing:
472
+ * derive selections from `filterModel`, write them back via raw `setFilterModel`
473
+ * mutations, debounce panel changes, and track which fields the panel "owns" so
474
+ * cards don't fight the panel for control. SOFA-6 shipped this logic ad hoc and
475
+ * got it wrong (no debounce, prop-drilled state, no panel/card reconciliation).
476
+ *
477
+ * @example
478
+ * const filter = useLinkedFilterModel();
479
+ *
480
+ * <DataCard.Listbox
481
+ * values={filter.getSelected('Category')}
482
+ * onChange={(values) => filter.setMultiSelect('Category', values)}
483
+ * isDisabled={filter.isFieldExternallyControlled('Category')}
484
+ * >
485
+ * {…}
486
+ * </DataCard.Listbox>
487
+ *
488
+ * <DataGrid filterModel={filter.filterModel} onFilterModelChange={filter.onFilterModelChange} />
489
+ */
490
+ function useLinkedFilterModel() {
491
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
492
+ const {
493
+ initialFilterModel = EMPTY_FILTER_MODEL,
494
+ debounceMs = 300,
495
+ onChange
496
+ } = options;
497
+ const [filterModel, setFilterModel] = useState(initialFilterModel);
498
+
499
+ // Fields whose current filter was set by setMultiSelect / setBoolean (not the panel).
500
+ const cardOwnedFields = useRef(new Set());
501
+ // Marks the next onFilterModelChange as originating from a card setter so we skip debouncing.
502
+ const skipNextDebounce = useRef(false);
503
+ const debounceTimer = useRef(null);
504
+ const onChangeRef = useRef(onChange);
505
+ useEffect(() => {
506
+ onChangeRef.current = onChange;
507
+ }, [onChange]);
508
+ useEffect(() => {
509
+ return () => {
510
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
511
+ };
512
+ }, []);
513
+ const commit = useCallback(next => {
514
+ setFilterModel(prev => {
515
+ var _onChangeRef$current;
516
+ if (sameItems(prev, next)) return prev;
517
+ (_onChangeRef$current = onChangeRef.current) === null || _onChangeRef$current === void 0 ? void 0 : _onChangeRef$current.call(onChangeRef, next);
518
+ return next;
519
+ });
520
+ }, []);
521
+ const onFilterModelChange = useCallback(model => {
522
+ if (skipNextDebounce.current) {
523
+ skipNextDebounce.current = false;
524
+ // If the incoming model matches the current state, this is a DataGrid echo
525
+ // of a card setter — commit (no-op) and preserve card ownership.
526
+ if (sameItems(filterModel, model)) {
527
+ commit(model);
528
+ return;
529
+ }
530
+ // Otherwise a real panel change arrived — fall through to ownership logic.
531
+ }
532
+
533
+ // Panel change — drop card ownership for fields the panel now controls / has cleared,
534
+ // then debounce the commit.
535
+ const panelFields = new Set(model.items.map(item => item.field));
536
+ for (const field of Array.from(cardOwnedFields.current)) {
537
+ if (!panelFields.has(field)) cardOwnedFields.current.delete(field);
538
+ }
539
+ // If the panel touched a field the card previously owned, transfer ownership to the panel.
540
+ for (const field of panelFields) {
541
+ cardOwnedFields.current.delete(field);
542
+ }
543
+ if (debounceMs <= 0) {
544
+ commit(model);
545
+ return;
546
+ }
547
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
548
+ debounceTimer.current = setTimeout(() => {
549
+ debounceTimer.current = null;
550
+ commit(model);
551
+ }, debounceMs);
552
+ }, [commit, debounceMs, filterModel]);
553
+ const getSelected = useCallback(field => {
554
+ const item = filterModel.items.find(i => i.field === field);
555
+ if (!item || item.value === undefined || item.value === null) return [];
556
+ if (item.operator === 'isAnyOf' || item.operator === 'hasAnyOf') {
557
+ return Array.isArray(item.value) ? item.value : [String(item.value)];
558
+ }
559
+ return [];
560
+ }, [filterModel]);
561
+ const getValue = useCallback(field => {
562
+ var _filterModel$items$fi;
563
+ return (_filterModel$items$fi = filterModel.items.find(i => i.field === field)) === null || _filterModel$items$fi === void 0 ? void 0 : _filterModel$items$fi.value;
564
+ }, [filterModel]);
565
+ const setMultiSelect = useCallback(function (field, values) {
566
+ let operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'isAnyOf';
567
+ skipNextDebounce.current = true;
568
+ setFilterModel(prev => {
569
+ var _onChangeRef$current2;
570
+ const items = filterOutField(prev, field);
571
+ if (values.length > 0) {
572
+ items.push({
573
+ field,
574
+ id: nextItemId(),
575
+ operator,
576
+ value: values
577
+ });
578
+ cardOwnedFields.current.add(field);
579
+ } else {
580
+ cardOwnedFields.current.delete(field);
581
+ }
582
+ const next = _objectSpread2(_objectSpread2({}, prev), {}, {
583
+ items
584
+ });
585
+ if (sameItems(prev, next)) return prev;
586
+ (_onChangeRef$current2 = onChangeRef.current) === null || _onChangeRef$current2 === void 0 ? void 0 : _onChangeRef$current2.call(onChangeRef, next);
587
+ return next;
588
+ });
589
+ }, []);
590
+ const setBoolean = useCallback((field, value) => {
591
+ skipNextDebounce.current = true;
592
+ setFilterModel(prev => {
593
+ var _onChangeRef$current3;
594
+ const items = filterOutField(prev, field);
595
+ if (value !== null) {
596
+ items.push({
597
+ field,
598
+ id: nextItemId(),
599
+ operator: 'is',
600
+ value: String(value)
601
+ });
602
+ cardOwnedFields.current.add(field);
603
+ } else {
604
+ cardOwnedFields.current.delete(field);
605
+ }
606
+ const next = _objectSpread2(_objectSpread2({}, prev), {}, {
607
+ items
608
+ });
609
+ if (sameItems(prev, next)) return prev;
610
+ (_onChangeRef$current3 = onChangeRef.current) === null || _onChangeRef$current3 === void 0 ? void 0 : _onChangeRef$current3.call(onChangeRef, next);
611
+ return next;
612
+ });
613
+ }, []);
614
+ const clearField = useCallback(field => {
615
+ skipNextDebounce.current = true;
616
+ setFilterModel(prev => {
617
+ var _onChangeRef$current4;
618
+ const items = filterOutField(prev, field);
619
+ cardOwnedFields.current.delete(field);
620
+ const next = _objectSpread2(_objectSpread2({}, prev), {}, {
621
+ items
622
+ });
623
+ if (sameItems(prev, next)) return prev;
624
+ (_onChangeRef$current4 = onChangeRef.current) === null || _onChangeRef$current4 === void 0 ? void 0 : _onChangeRef$current4.call(onChangeRef, next);
625
+ return next;
626
+ });
627
+ }, []);
628
+ const reset = useCallback(() => {
629
+ skipNextDebounce.current = true;
630
+ cardOwnedFields.current.clear();
631
+ commit(initialFilterModel);
632
+ }, [commit, initialFilterModel]);
633
+ const isFieldExternallyControlled = useCallback(field => {
634
+ const hasFilter = filterModel.items.some(item => item.field === field);
635
+ return hasFilter && !cardOwnedFields.current.has(field);
636
+ }, [filterModel]);
637
+ return useMemo(() => ({
638
+ filterModel,
639
+ onFilterModelChange,
640
+ getSelected,
641
+ getValue,
642
+ setMultiSelect,
643
+ setBoolean,
644
+ clearField,
645
+ reset,
646
+ isFieldExternallyControlled
647
+ }), [filterModel, onFilterModelChange, getSelected, getValue, setMultiSelect, setBoolean, clearField, reset, isFieldExternallyControlled]);
648
+ }
649
+
650
+ export { DATE_IS_BETWEEN, DETAIL_PANEL_TOGGLE_COL_DEF, IS_ANY_OF_I, IS_ANY_OF_I_WITH_SELECT, createColumn, createReactRouterV5Adapter, customColumnTypes, getGridDateOperatorsExtended, getRsMultipleSelectColumnType, getRsMultipleSelectWithShortOperatorListColumnType, getRsNumberColumnType, getRsSingleSelectColumnType, getRsSingleSelectWithShortOperatorListColumnType, getRsStringColumnType, makeCaseInsensitive, useLinkedFilterModel, wrapCaseInsensitive };
419
651
  //# sourceMappingURL=index.js.map