@wallarm-org/design-system 0.40.0-rc-feature-AS-982.7 → 0.40.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.
Files changed (119) hide show
  1. package/dist/components/DropdownMenu/DropdownMenuCheckboxItem.d.ts +15 -0
  2. package/dist/components/DropdownMenu/DropdownMenuCheckboxItem.js +32 -0
  3. package/dist/components/DropdownMenu/DropdownMenuContent.js +6 -2
  4. package/dist/components/DropdownMenu/DropdownMenuItemIndicator.d.ts +2 -0
  5. package/dist/components/DropdownMenu/DropdownMenuItemIndicator.js +14 -0
  6. package/dist/components/DropdownMenu/DropdownMenuRadioGroup.d.ts +9 -0
  7. package/dist/components/DropdownMenu/DropdownMenuRadioGroup.js +17 -0
  8. package/dist/components/DropdownMenu/DropdownMenuRadioItem.d.ts +13 -0
  9. package/dist/components/DropdownMenu/DropdownMenuRadioItem.js +28 -0
  10. package/dist/components/DropdownMenu/classes.d.ts +1 -0
  11. package/dist/components/DropdownMenu/classes.js +2 -1
  12. package/dist/components/DropdownMenu/index.d.ts +3 -0
  13. package/dist/components/DropdownMenu/index.js +4 -1
  14. package/dist/components/FilterInput/FilterInput.d.ts +8 -5
  15. package/dist/components/FilterInput/FilterInputContext/types.d.ts +9 -12
  16. package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.d.ts +2 -4
  17. package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.js +0 -4
  18. package/dist/components/FilterInput/FilterInputErrors/parseFilterInputErrors.js +2 -1
  19. package/dist/components/FilterInput/FilterInputField/ChipsWithGaps.d.ts +1 -1
  20. package/dist/components/FilterInput/FilterInputField/ChipsWithGaps.js +1 -1
  21. package/dist/components/FilterInput/FilterInputField/FilterInputChip/FilterInputChip.d.ts +1 -1
  22. package/dist/components/FilterInput/FilterInputField/FilterInputChip/FilterInputChip.js +2 -2
  23. package/dist/components/FilterInput/FilterInputField/FilterInputField.js +40 -11
  24. package/dist/components/FilterInput/FilterInputMenu/FilterInputDateValueMenu/constants.d.ts +2 -2
  25. package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FilterInputFieldMenu.d.ts +1 -1
  26. package/dist/components/FilterInput/FilterInputMenu/FilterInputMenu.d.ts +1 -1
  27. package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.d.ts +6 -5
  28. package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuDisplayValues.d.ts +14 -4
  29. package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuState.d.ts +5 -3
  30. package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.d.ts +1 -1
  31. package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.js +2 -5
  32. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/{lib/deriveAutocompleteValues.d.ts → deriveAutocompleteValues.d.ts} +3 -3
  33. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/{lib/deriveAutocompleteValues.js → deriveAutocompleteValues.js} +1 -1
  34. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useBlurCommit.d.ts +16 -5
  35. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipActions.d.ts +2 -2
  36. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipActions.js +5 -5
  37. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipEditing.d.ts +8 -7
  38. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipEditing.js +12 -15
  39. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts +10 -9
  40. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js +83 -52
  41. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFocusManagement.d.ts +11 -9
  42. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFocusManagement.js +20 -47
  43. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useInputHandlers.d.ts +4 -6
  44. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useInputHandlers.js +15 -32
  45. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/{useMenuFlow/types.d.ts → useMenuFlow.d.ts} +17 -14
  46. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow.js +260 -0
  47. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuPositioning.d.ts +8 -25
  48. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuPositioning.js +22 -39
  49. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResetState.d.ts +19 -10
  50. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResetState.js +3 -3
  51. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/{lib/valueResolution.d.ts → valueCommitHelpers.d.ts} +7 -1
  52. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/{lib/valueResolution.js → valueCommitHelpers.js} +25 -3
  53. package/dist/components/FilterInput/hooks/useFilterInputExpression/buildChips.js +2 -1
  54. package/dist/components/FilterInput/hooks/useFilterInputPositioning.d.ts +4 -9
  55. package/dist/components/FilterInput/hooks/useFilterInputPositioning.js +6 -7
  56. package/dist/components/FilterInput/hooks/useFilterInputSelection/lib/dom.d.ts +4 -4
  57. package/dist/components/FilterInput/hooks/useFilterInputSelection/useFilterInputSelection.d.ts +2 -2
  58. package/dist/components/FilterInput/hooks/useFilterInputSelection/useSelectionClipboard.d.ts +5 -2
  59. package/dist/components/FilterInput/lib/applyAcceptChar.d.ts +4 -3
  60. package/dist/components/FilterInput/lib/applyKnownFieldHelpers.d.ts +25 -13
  61. package/dist/components/FilterInput/lib/constants.d.ts +34 -10
  62. package/dist/components/FilterInput/lib/dom.d.ts +11 -15
  63. package/dist/components/FilterInput/lib/dom.js +9 -14
  64. package/dist/components/FilterInput/lib/fields.d.ts +19 -10
  65. package/dist/components/FilterInput/lib/index.d.ts +1 -3
  66. package/dist/components/FilterInput/lib/index.js +2 -4
  67. package/dist/components/FilterInput/lib/menuFilterText.d.ts +17 -6
  68. package/dist/components/FilterInput/lib/operators.d.ts +21 -11
  69. package/dist/components/FilterInput/lib/serializeExpression.d.ts +12 -5
  70. package/dist/components/SimpleCharts/LineChart/LineChartLine.js +2 -6
  71. package/dist/components/SimpleCharts/LineChart/LineChartTooltip.js +3 -3
  72. package/dist/components/SimpleCharts/LineChart/LineChartXAxis.js +12 -3
  73. package/dist/components/SimpleCharts/LineChart/LineChartYAxis.js +6 -15
  74. package/dist/components/SimpleCharts/LineChart/LineChartZoomBrush.js +19 -8
  75. package/dist/components/SimpleCharts/LineChart/classes.js +1 -1
  76. package/dist/components/SimpleCharts/LineChart/constants.d.ts +1 -1
  77. package/dist/components/SimpleCharts/LineChart/constants.js +2 -2
  78. package/dist/components/SimpleCharts/LineChart/lib/formatRange.d.ts +5 -9
  79. package/dist/components/SimpleCharts/LineChart/lib/formatRange.js +1 -6
  80. package/dist/components/SimpleCharts/LineChart/lib/renderAxisTick.d.ts +13 -0
  81. package/dist/components/SimpleCharts/LineChart/lib/renderAxisTick.js +20 -0
  82. package/dist/components/SimpleCharts/LineChart/lib/sampleData.js +3 -3
  83. package/dist/components/SimpleCharts/hooks/useChartTimeFormatters.d.ts +0 -5
  84. package/dist/components/SimpleCharts/hooks/useChartTimeFormatters.js +1 -2
  85. package/dist/metadata/components.json +901 -9
  86. package/package.json +1 -1
  87. package/dist/components/FilterInput/FilterInputField/hooks/useSegmentEditKeyboard.d.ts +0 -37
  88. package/dist/components/FilterInput/FilterInputField/hooks/useSegmentEditKeyboard.js +0 -78
  89. package/dist/components/FilterInput/hooks/useAutoCleanupDetachedElement.d.ts +0 -12
  90. package/dist/components/FilterInput/hooks/useAutoCleanupDetachedElement.js +0 -22
  91. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/getInitialSegmentText.d.ts +0 -9
  92. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/getInitialSegmentText.js +0 -8
  93. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/index.d.ts +0 -3
  94. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/index.js +0 -4
  95. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useAutocompleteState.d.ts +0 -36
  96. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useAutocompleteState.js +0 -51
  97. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipCascade.d.ts +0 -46
  98. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipCascade.js +0 -103
  99. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/index.d.ts +0 -1
  100. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/index.js +0 -2
  101. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/types.js +0 -0
  102. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useFieldFlow.d.ts +0 -11
  103. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useFieldFlow.js +0 -95
  104. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useMenuFlow.d.ts +0 -20
  105. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useMenuFlow.js +0 -45
  106. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useOperatorFlow.d.ts +0 -11
  107. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useOperatorFlow.js +0 -87
  108. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useValueFlow.d.ts +0 -14
  109. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useValueFlow.js +0 -107
  110. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useSegmentEditFlow.d.ts +0 -36
  111. package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useSegmentEditFlow.js +0 -69
  112. package/dist/components/FilterInput/hooks/useFloatingRecomputeOn.d.ts +0 -14
  113. package/dist/components/FilterInput/hooks/useFloatingRecomputeOn.js +0 -18
  114. package/dist/components/FilterInput/hooks/useResizeTracker.d.ts +0 -10
  115. package/dist/components/FilterInput/hooks/useResizeTracker.js +0 -21
  116. package/dist/components/FilterInput/lib/segmentMenu.d.ts +0 -4
  117. package/dist/components/FilterInput/lib/segmentMenu.js +0 -7
  118. package/dist/components/FilterInput/lib/validation.d.ts +0 -9
  119. package/dist/components/FilterInput/lib/validation.js +0 -24
@@ -1,4 +1,4 @@
1
- import { NO_VALUE_PLACEHOLDER, chipIdToConditionIndex, getDateDisplayLabel, getFieldValues, getOperatorLabel, hasStaticAllowlist, isMultiSelectOperator, isNoValueOperator } from "../../../lib/index.js";
1
+ import { NO_VALUE_PLACEHOLDER, chipIdToConditionIndex, getDateDisplayLabel, getFieldValues, getOperatorLabel, hasStaticAllowlist, isMultiSelectOperator, isNoValueOperator } from "../../lib/index.js";
2
2
  const getEditingCondition = (editingChipId, conditions)=>{
3
3
  if (!editingChipId) return null;
4
4
  const idx = chipIdToConditionIndex(editingChipId);
@@ -9,14 +9,25 @@ interface UseBlurCommitDeps {
9
9
  handleCustomValueCommit: (text: string) => void;
10
10
  upsertCondition: UpsertCondition;
11
11
  resetState: () => void;
12
- /** Indirection ref breaking the useMenuFlow ↔ useBlurCommit cycle. */
12
+ /**
13
+ * Indirection ref consumed by useMenuFlow to break the circular dependency
14
+ * useMenuFlow ↔ useBlurCommit. The hook writes the latest commit fn here
15
+ * each render; useMenuFlow calls through it via `() => ref.current()`.
16
+ */
13
17
  commitBuildingOnBlurRef: RefObject<() => boolean>;
14
18
  }
15
19
  /**
16
- * Commit an incomplete building chip on blur/menu-close instead of discarding:
17
- * commit typed text as custom value, or persist as an error chip so it stays
18
- * editable. Re-entry-guarded: refs cleared synchronously so concurrent callers
19
- * (multiple onOpenChange + blur in one tick) don't create duplicate chips.
20
+ * Commit logic for an incomplete "building" chip on blur or menu close.
21
+ *
22
+ * Instead of discarding the in-progress chip when the user blurs or the menu
23
+ * closes, this either commits the typed text as a custom value (when there's an
24
+ * operator + text) or persists it as an error chip (so it remains visible and
25
+ * editable). Uses fresh refs to avoid stale closures.
26
+ *
27
+ * Re-entry guard: snapshots and clears the refs synchronously so concurrent
28
+ * callers (two `onOpenChange(false)` from Ark UI menus during a state transition,
29
+ * plus a blur in the same tick) short-circuit on re-entry instead of creating
30
+ * duplicate error chips.
20
31
  */
21
32
  export declare const useBlurCommit: ({ selectedField, selectedOperator, inputText, editingChipId, effectiveInsertIndexRef, handleCustomValueCommit, upsertCondition, resetState, commitBuildingOnBlurRef, }: UseBlurCommitDeps) => {
22
33
  commitBuildingOnBlur: () => boolean;
@@ -5,7 +5,7 @@ interface UseChipActionsDeps {
5
5
  inputRef: RefObject<HTMLInputElement | null>;
6
6
  removeCondition: (chipId: string) => void;
7
7
  clearAll: () => void;
8
- resetMenuAnchor: () => void;
8
+ resetMenuOffset: () => void;
9
9
  resetState: () => void;
10
10
  setInsertIndex: Dispatch<SetStateAction<number | null>>;
11
11
  setInsertAfterConnector: Dispatch<SetStateAction<boolean>>;
@@ -18,7 +18,7 @@ interface UseChipActionsDeps {
18
18
  * - clicking a gap between chips to insert a new condition there
19
19
  * - closing the menu (used by external consumers like the connector chip)
20
20
  */
21
- export declare const useChipActions: ({ effectiveInsertIndexRef, inputRef, removeCondition, clearAll, resetMenuAnchor, resetState, setInsertIndex, setInsertAfterConnector, setMenuState, }: UseChipActionsDeps) => {
21
+ export declare const useChipActions: ({ effectiveInsertIndexRef, inputRef, removeCondition, clearAll, resetMenuOffset, resetState, setInsertIndex, setInsertAfterConnector, setMenuState, }: UseChipActionsDeps) => {
22
22
  handleChipRemove: (chipId: string) => void;
23
23
  handleClear: () => void;
24
24
  handleGapClick: (conditionIndex: number, afterConnector: boolean) => void;
@@ -1,17 +1,17 @@
1
1
  import { useCallback } from "react";
2
2
  import { flushSync } from "react-dom";
3
3
  import { chipIdToConditionIndex } from "../../lib/index.js";
4
- const useChipActions = ({ effectiveInsertIndexRef, inputRef, removeCondition, clearAll, resetMenuAnchor, resetState, setInsertIndex, setInsertAfterConnector, setMenuState })=>{
4
+ const useChipActions = ({ effectiveInsertIndexRef, inputRef, removeCondition, clearAll, resetMenuOffset, resetState, setInsertIndex, setInsertAfterConnector, setMenuState })=>{
5
5
  const handleChipRemove = useCallback((chipId)=>{
6
6
  const chipCondIdx = chipIdToConditionIndex(chipId);
7
7
  if (null !== chipCondIdx && chipCondIdx < effectiveInsertIndexRef.current) setInsertIndex((prev)=>null != prev ? prev - 1 : prev);
8
8
  removeCondition(chipId);
9
- resetMenuAnchor();
9
+ resetMenuOffset();
10
10
  setMenuState('closed');
11
11
  inputRef.current?.focus();
12
12
  }, [
13
13
  removeCondition,
14
- resetMenuAnchor,
14
+ resetMenuOffset,
15
15
  inputRef,
16
16
  effectiveInsertIndexRef,
17
17
  setInsertIndex,
@@ -29,14 +29,14 @@ const useChipActions = ({ effectiveInsertIndexRef, inputRef, removeCondition, cl
29
29
  flushSync(()=>{
30
30
  setInsertIndex(conditionIndex);
31
31
  setInsertAfterConnector(afterConnector);
32
- resetMenuAnchor();
32
+ resetMenuOffset();
33
33
  setMenuState('closed');
34
34
  });
35
35
  setMenuState('field');
36
36
  inputRef.current?.focus();
37
37
  }, [
38
38
  resetState,
39
- resetMenuAnchor,
39
+ resetMenuOffset,
40
40
  inputRef,
41
41
  setInsertIndex,
42
42
  setInsertAfterConnector,
@@ -1,31 +1,32 @@
1
+ import type { RefObject } from 'react';
1
2
  import { type ChipSegment } from '../../FilterInputField/FilterInputChip';
2
3
  import type { Condition, FieldMetadata, FilterInputChipData, FilterOperator, MenuState, UpsertCondition } from '../../types';
3
4
  interface UseChipEditingOptions {
4
5
  conditions: Condition[];
5
6
  chips: FilterInputChipData[];
6
7
  fields: FieldMetadata[];
7
- setMenuAnchor: (el: HTMLElement | null) => void;
8
+ containerRef: RefObject<HTMLElement | null>;
9
+ setMenuOffset: (offset: number) => void;
8
10
  setSelectedField: (field: FieldMetadata | null) => void;
9
11
  setSelectedOperator: (op: FilterOperator | null) => void;
10
12
  setMenuState: (state: MenuState) => void;
11
13
  upsertCondition: UpsertCondition;
12
14
  }
13
15
  /**
14
- * Manages editing of existing filter chips. Chip click opens the appropriate
15
- * menu based on segment, then advances through field operator → value.
16
+ * Manages editing of existing filter chips.
17
+ * Handles chip click open appropriate menu based on segment,
18
+ * then advances through the full flow (field → operator → value).
16
19
  */
17
- export declare const useChipEditing: ({ conditions, chips, fields, setMenuAnchor, setSelectedField, setSelectedOperator, setMenuState, upsertCondition, }: UseChipEditingOptions) => {
20
+ export declare const useChipEditing: ({ conditions, chips, fields, containerRef, setMenuOffset, setSelectedField, setSelectedOperator, setMenuState, upsertCondition, }: UseChipEditingOptions) => {
18
21
  editingChipId: string | null;
19
22
  editingSegment: import("../../FilterInputField/FilterInputChip").SegmentVariant | null;
20
- isBuildingEdit: boolean;
21
23
  setEditingSegment: import("react").Dispatch<import("react").SetStateAction<import("../../FilterInputField/FilterInputChip").SegmentVariant | null>>;
22
24
  segmentFilterText: string;
23
25
  segmentMenuFilterText: string;
24
26
  setSegmentFilterText: (text: string) => void;
25
27
  resetSegmentTyping: () => void;
26
- handleChipClick: (chipId: string, segment: ChipSegment, anchorEl: HTMLElement) => void;
28
+ handleChipClick: (chipId: string, segment: ChipSegment, anchorRect: DOMRect) => void;
27
29
  startBuildingEdit: (segment: ChipSegment, currentText: string) => void;
28
- switchEditSegment: (segment: ChipSegment, currentText: string) => void;
29
30
  clearEditing: () => void;
30
31
  };
31
32
  export {};
@@ -1,10 +1,15 @@
1
1
  import { useCallback, useMemo, useRef, useState } from "react";
2
2
  import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
3
- import { SEGMENT_TO_MENU, chipIdToConditionIndex, getOperatorFromLabel, isNoValueOperator } from "../../lib/index.js";
3
+ import { chipIdToConditionIndex, getOperatorFromLabel, isNoValueOperator } from "../../lib/index.js";
4
4
  const getConditionByChipId = (chipId, conditions)=>{
5
5
  const idx = chipIdToConditionIndex(chipId);
6
6
  return null !== idx ? conditions[idx] ?? null : null;
7
7
  };
8
+ const SEGMENT_TO_MENU = {
9
+ attribute: 'field',
10
+ operator: 'operator',
11
+ value: 'value'
12
+ };
8
13
  const getFirstIncompleteSegment = (condition, fields)=>{
9
14
  const field = fields.find((f)=>f.name === condition.field);
10
15
  if (!field || condition.error === SEGMENT_VARIANT.attribute) return SEGMENT_VARIANT.attribute;
@@ -12,7 +17,7 @@ const getFirstIncompleteSegment = (condition, fields)=>{
12
17
  if (null === condition.value || '' === condition.value || condition.error === SEGMENT_VARIANT.value) return SEGMENT_VARIANT.value;
13
18
  return null;
14
19
  };
15
- const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedField, setSelectedOperator, setMenuState, upsertCondition })=>{
20
+ const useChipEditing = ({ conditions, chips, fields, containerRef, setMenuOffset, setSelectedField, setSelectedOperator, setMenuState, upsertCondition })=>{
16
21
  const [editingChipId, setEditingChipId] = useState(null);
17
22
  const [editingSegment, setEditingSegment] = useState(null);
18
23
  const [segmentFilterText, setSegmentFilterText] = useState('');
@@ -23,7 +28,7 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
23
28
  chipsRef.current = chips;
24
29
  const fieldsRef = useRef(fields);
25
30
  fieldsRef.current = fields;
26
- const handleChipClick = useCallback((chipId, segment, anchorEl)=>{
31
+ const handleChipClick = useCallback((chipId, segment, anchorRect)=>{
27
32
  const condition = getConditionByChipId(chipId, conditionsRef.current);
28
33
  if (!condition) return;
29
34
  const field = fieldsRef.current.find((f)=>f.name === condition.field);
@@ -34,7 +39,8 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
34
39
  const targetSegment = incompleteSegment ?? (isPlaceholderValueClick ? SEGMENT_VARIANT.operator : segment);
35
40
  if (!field && targetSegment !== SEGMENT_VARIANT.attribute) return;
36
41
  if (incompleteSegment && field) upsertCondition(field, condition.operator, condition.value, chipId);
37
- setMenuAnchor(anchorEl);
42
+ const containerRect = containerRef.current?.getBoundingClientRect();
43
+ setMenuOffset(containerRect ? anchorRect.left - containerRect.left : 0);
38
44
  setEditingChipId(chipId);
39
45
  setSelectedField(field ?? null);
40
46
  const rawOperator = targetSegment === SEGMENT_VARIANT.value || targetSegment === SEGMENT_VARIANT.operator ? getOperatorFromLabel(chip.operator || '', field?.type ?? 'string') ?? condition.operator : null;
@@ -49,7 +55,8 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
49
55
  setUserHasTyped(false);
50
56
  setMenuState(SEGMENT_TO_MENU[targetSegment]);
51
57
  }, [
52
- setMenuAnchor,
58
+ containerRef,
59
+ setMenuOffset,
53
60
  setSelectedField,
54
61
  setSelectedOperator,
55
62
  setMenuState,
@@ -67,11 +74,6 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
67
74
  setSegmentFilterText(currentText);
68
75
  setUserHasTyped(false);
69
76
  }, []);
70
- const switchEditSegment = useCallback((segment, currentText)=>{
71
- setEditingSegment(segment);
72
- setSegmentFilterText(currentText);
73
- setUserHasTyped(false);
74
- }, []);
75
77
  const handleSegmentFilterChange = useCallback((text)=>{
76
78
  setSegmentFilterText(text);
77
79
  setUserHasTyped(true);
@@ -81,11 +83,9 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
81
83
  }, []);
82
84
  const segmentDisplayText = segmentFilterText;
83
85
  const segmentMenuFilterText = userHasTyped ? segmentFilterText : '';
84
- const isBuildingEdit = null === editingChipId && null !== editingSegment;
85
86
  return useMemo(()=>({
86
87
  editingChipId,
87
88
  editingSegment,
88
- isBuildingEdit,
89
89
  setEditingSegment,
90
90
  segmentFilterText: segmentDisplayText,
91
91
  segmentMenuFilterText,
@@ -93,19 +93,16 @@ const useChipEditing = ({ conditions, chips, fields, setMenuAnchor, setSelectedF
93
93
  resetSegmentTyping,
94
94
  handleChipClick,
95
95
  startBuildingEdit,
96
- switchEditSegment,
97
96
  clearEditing
98
97
  }), [
99
98
  editingChipId,
100
99
  editingSegment,
101
- isBuildingEdit,
102
100
  segmentDisplayText,
103
101
  segmentMenuFilterText,
104
102
  handleSegmentFilterChange,
105
103
  resetSegmentTyping,
106
104
  handleChipClick,
107
105
  startBuildingEdit,
108
- switchEditSegment,
109
106
  clearEditing
110
107
  ]);
111
108
  };
@@ -1,5 +1,6 @@
1
1
  import type { RefObject } from 'react';
2
- import type { Condition, FieldMetadata, FilterInputChipData, UpsertCondition } from '../../types';
2
+ import { type ChipSegment } from '../../FilterInputField/FilterInputChip';
3
+ import type { Condition, FieldMetadata, FilterInputChipData, FilterOperator, MenuState, UpsertCondition } from '../../types';
3
4
  interface UseFilterInputAutocompleteOptions {
4
5
  fields: FieldMetadata[];
5
6
  conditions: Condition[];
@@ -15,9 +16,9 @@ interface UseFilterInputAutocompleteOptions {
15
16
  }
16
17
  export declare const useFilterInputAutocomplete: ({ fields, conditions, chips, upsertCondition, removeCondition, removeConditionAtIndex, clearAll, setConnectorValue, containerRef, buildingChipRef, inputRef, }: UseFilterInputAutocompleteOptions) => {
17
18
  inputText: string;
18
- menuState: import("../../types").MenuState;
19
+ menuState: MenuState;
19
20
  selectedField: FieldMetadata | null;
20
- selectedOperator: import("../..").FilterOperator | null;
21
+ selectedOperator: FilterOperator | null;
21
22
  isBuilding: boolean;
22
23
  buildingChipData: import("../../FilterInputContext").BuildingChipData | null;
23
24
  menuPositioning: {
@@ -40,19 +41,19 @@ export declare const useFilterInputAutocomplete: ({ fields, conditions, chips, u
40
41
  inputRef: RefObject<HTMLInputElement | null>;
41
42
  handleInputChange: (e: import("react").ChangeEvent<HTMLInputElement>) => void;
42
43
  handleFieldSelect: (field: FieldMetadata) => void;
43
- handleOperatorSelect: (operator: import("../..").FilterOperator) => void;
44
+ handleOperatorSelect: (operator: FilterOperator) => void;
44
45
  handleValueSelect: (val: string | number | boolean) => void;
45
46
  handleMultiCommit: (values: Array<string | number | boolean>) => void;
46
47
  handleBuildingValueChange: (preview: string | undefined) => void;
47
48
  handleMultiSelectToggle: () => void;
48
49
  handleMenuClose: () => void;
49
50
  handleMenuDiscard: () => void;
50
- /** Hard reset for paste/clipboard flowsscraps in-progress building. */
51
+ /** Hard reset of autocomplete stateused by paste/clipboard flows where
52
+ * the conditions array is replaced and any in-progress building must be
53
+ * scrapped, regardless of inline-edit mode. */
51
54
  resetAutocompleteState: (continueBuilding?: boolean) => void;
52
- handleChipClick: (chipId: string, segment: import("../../FilterInputField").ChipSegment, anchorEl: HTMLElement) => void;
53
- handleBuildingChipClick: (segment: import("../../FilterInputField").ChipSegment, anchorEl: HTMLElement) => void;
54
- switchEditSegment: (targetSegment: import("../../FilterInputField").ChipSegment) => boolean;
55
- removeEditingChip: () => void;
55
+ handleChipClick: (chipId: string, segment: ChipSegment, anchorRect: DOMRect) => void;
56
+ handleBuildingChipClick: (segment: ChipSegment, anchorRect: DOMRect) => void;
56
57
  handleConnectorChange: (connectorId: string, value: "and" | "or") => void;
57
58
  handleChipRemove: (chipId: string) => void;
58
59
  handleClear: () => void;
@@ -1,36 +1,50 @@
1
+ import { useCallback, useRef, useState } from "react";
1
2
  import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
2
3
  import { useDateRange } from "../../FilterInputMenu/FilterInputDateValueMenu/hooks.js";
3
- import { deriveAutocompleteValues } from "./lib/index.js";
4
- import { useAutocompleteState } from "./useAutocompleteState.js";
4
+ import { applyAcceptChar, getOperatorLabel } from "../../lib/index.js";
5
+ import { deriveAutocompleteValues } from "./deriveAutocompleteValues.js";
5
6
  import { useBlurCommit } from "./useBlurCommit.js";
6
7
  import { useChipActions } from "./useChipActions.js";
7
- import { useChipCascade } from "./useChipCascade.js";
8
8
  import { useChipEditing } from "./useChipEditing.js";
9
9
  import { useFocusManagement } from "./useFocusManagement.js";
10
10
  import { useInputHandlers } from "./useInputHandlers.js";
11
- import { useMenuFlow } from "./useMenuFlow/index.js";
11
+ import { useMenuFlow } from "./useMenuFlow.js";
12
12
  import { useMenuPositioning } from "./useMenuPositioning.js";
13
13
  import { useResetState } from "./useResetState.js";
14
- import { useSegmentEditFlow } from "./useSegmentEditFlow.js";
15
14
  const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition, removeCondition, removeConditionAtIndex, clearAll, setConnectorValue, containerRef, buildingChipRef, inputRef })=>{
16
- const state = useAutocompleteState({
17
- conditions
18
- });
19
- const { inputText, setInputText, menuState, setMenuState, selectedField, setSelectedField, selectedOperator, setSelectedOperator, isFocused, setIsFocused, buildingMultiValue, setBuildingMultiValue, insertIndex, setInsertIndex, insertAfterConnector, setInsertAfterConnector, effectiveInsertIndex, effectiveInsertIndexRef, conditionsRef, conditionsLengthRef, blurCommitRef, segmentAttributeInputRef, segmentOperatorInputRef, segmentValueInputRef, commitBuildingOnBlurRef } = state;
20
- const { menuPositioning, setMenuAnchor, resetMenuAnchor } = useMenuPositioning({
15
+ const [inputText, setInputText] = useState('');
16
+ const [menuState, setMenuState] = useState('closed');
17
+ const [selectedField, setSelectedField] = useState(null);
18
+ const [selectedOperator, setSelectedOperator] = useState(null);
19
+ const [isFocused, setIsFocused] = useState(false);
20
+ const [buildingMultiValue, setBuildingMultiValue] = useState(void 0);
21
+ const [insertIndex, setInsertIndex] = useState(null);
22
+ const [insertAfterConnector, setInsertAfterConnector] = useState(false);
23
+ const effectiveInsertIndex = insertIndex ?? conditions.length;
24
+ const effectiveInsertIndexRef = useRef(effectiveInsertIndex);
25
+ effectiveInsertIndexRef.current = effectiveInsertIndex;
26
+ const conditionsRef = useRef(conditions);
27
+ conditionsRef.current = conditions;
28
+ const conditionsLengthRef = useRef(conditions.length);
29
+ conditionsLengthRef.current = conditions.length;
30
+ const blurCommitRef = useRef(null);
31
+ const segmentAttributeInputRef = useRef(null);
32
+ const segmentOperatorInputRef = useRef(null);
33
+ const segmentValueInputRef = useRef(null);
34
+ const commitBuildingOnBlurRef = useRef(()=>false);
35
+ const { menuPositioning, setMenuOffset, resetMenuOffset } = useMenuPositioning({
21
36
  containerRef,
22
37
  buildingChipRef,
23
38
  inputRef,
24
39
  isBuilding: null !== selectedField,
25
- insertIndex: effectiveInsertIndex,
26
- chipsCount: chips.length,
27
- isMenuOpen: 'closed' !== menuState
40
+ insertIndex: effectiveInsertIndex
28
41
  });
29
42
  const editing = useChipEditing({
30
43
  conditions,
31
44
  chips,
32
45
  fields,
33
- setMenuAnchor,
46
+ containerRef,
47
+ setMenuOffset,
34
48
  setSelectedField,
35
49
  setSelectedOperator,
36
50
  setMenuState,
@@ -42,7 +56,7 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
42
56
  dateRange,
43
57
  containerRef,
44
58
  inputRef,
45
- resetMenuAnchor,
59
+ resetMenuOffset,
46
60
  setInputText,
47
61
  setSelectedField,
48
62
  setSelectedOperator,
@@ -69,24 +83,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
69
83
  setMenuState,
70
84
  setBuildingMultiValue
71
85
  });
72
- const { switchEditSegment, removeEditingChip, stepBackBuildingMenu } = useChipCascade({
73
- editing,
74
- chips,
75
- fields,
76
- conditionsRef,
77
- effectiveInsertIndexRef,
78
- selectedField,
79
- selectedOperator,
80
- buildingMultiValue,
81
- upsertCondition,
82
- removeCondition,
83
- resetState,
84
- setInputText,
85
- setMenuState,
86
- setSelectedOperator,
87
- setBuildingMultiValue,
88
- setInsertIndex
89
- });
90
86
  const { handleInputChange, handleInputClick, handleKeyDown, menuRef } = useInputHandlers({
91
87
  inputText,
92
88
  menuState,
@@ -101,12 +97,11 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
101
97
  setInputText,
102
98
  setMenuState,
103
99
  setInsertIndex,
104
- resetMenuAnchor,
100
+ resetMenuOffset,
105
101
  removeConditionAtIndex,
106
102
  handleFieldSelect,
107
103
  handleOperatorSelect,
108
- handleCustomValueCommit,
109
- stepBackBuildingMenu
104
+ handleCustomValueCommit
110
105
  });
111
106
  const { commitBuildingOnBlur, hasIncompleteBuilding } = useBlurCommit({
112
107
  selectedField,
@@ -137,7 +132,7 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
137
132
  hasIncompleteBuilding,
138
133
  setIsFocused,
139
134
  setMenuState,
140
- resetMenuAnchor,
135
+ resetMenuOffset,
141
136
  resetState
142
137
  });
143
138
  const { handleChipRemove, handleClear, handleGapClick, closeAutocompleteMenu } = useChipActions({
@@ -145,24 +140,12 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
145
140
  inputRef,
146
141
  removeCondition,
147
142
  clearAll,
148
- resetMenuAnchor,
143
+ resetMenuOffset,
149
144
  resetState,
150
145
  setInsertIndex,
151
146
  setInsertAfterConnector,
152
147
  setMenuState
153
148
  });
154
- const { handleSegmentFilterChange, cancelSegmentEdit, handleMenuDiscard, handleBuildingChipClick } = useSegmentEditFlow({
155
- editing,
156
- selectedField,
157
- selectedOperator,
158
- buildingMultiValue,
159
- resetState,
160
- setSelectedField,
161
- setSelectedOperator,
162
- setInputText,
163
- setMenuState,
164
- setMenuAnchor
165
- });
166
149
  const { isBuilding, buildingChipData, editingMultiValues, editingSingleValue, editingDateRange } = deriveAutocompleteValues({
167
150
  editingChipId: editing.editingChipId,
168
151
  selectedField,
@@ -172,6 +155,56 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
172
155
  dateRangeFromValue: dateRange.fromValue,
173
156
  segmentFilterText: editing.editingSegment === SEGMENT_VARIANT.value ? editing.segmentMenuFilterText : void 0
174
157
  });
158
+ const handleSegmentFilterChange = useCallback((text)=>{
159
+ const accept = selectedField?.acceptChar;
160
+ const next = editing.editingSegment === SEGMENT_VARIANT.value && accept ? applyAcceptChar(text, accept) : text;
161
+ editing.setSegmentFilterText(next);
162
+ }, [
163
+ selectedField,
164
+ editing
165
+ ]);
166
+ const cancelSegmentEdit = useCallback(()=>{
167
+ const isBuildingEdit = !editing.editingChipId && null !== editing.editingSegment;
168
+ if (isBuildingEdit) {
169
+ editing.clearEditing();
170
+ setMenuState('closed');
171
+ return;
172
+ }
173
+ setSelectedField(null);
174
+ setSelectedOperator(null);
175
+ editing.clearEditing();
176
+ setMenuState('closed');
177
+ }, [
178
+ editing
179
+ ]);
180
+ const handleMenuDiscard = useCallback(()=>{
181
+ const isBuildingEdit = !editing.editingChipId && null !== editing.editingSegment;
182
+ if (isBuildingEdit) {
183
+ editing.clearEditing();
184
+ setMenuState('closed');
185
+ return;
186
+ }
187
+ resetState();
188
+ }, [
189
+ editing,
190
+ resetState
191
+ ]);
192
+ const handleBuildingChipClick = useCallback((segment, anchorRect)=>{
193
+ if (!selectedField) return;
194
+ const containerRect = containerRef.current?.getBoundingClientRect();
195
+ setMenuOffset(containerRect ? anchorRect.left - containerRect.left : 0);
196
+ const initialText = segment === SEGMENT_VARIANT.attribute ? selectedField.label : segment === SEGMENT_VARIANT.operator ? selectedOperator ? getOperatorLabel(selectedOperator, selectedField.type) : '' : buildingMultiValue ?? '';
197
+ editing.startBuildingEdit(segment, initialText);
198
+ setInputText('');
199
+ setMenuState(segment === SEGMENT_VARIANT.attribute ? 'field' : segment === SEGMENT_VARIANT.operator ? 'operator' : 'value');
200
+ }, [
201
+ selectedField,
202
+ selectedOperator,
203
+ buildingMultiValue,
204
+ containerRef,
205
+ setMenuOffset,
206
+ editing
207
+ ]);
175
208
  return {
176
209
  inputText,
177
210
  menuState,
@@ -196,8 +229,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
196
229
  resetAutocompleteState: resetState,
197
230
  handleChipClick: editing.handleChipClick,
198
231
  handleBuildingChipClick,
199
- switchEditSegment,
200
- removeEditingChip,
201
232
  handleConnectorChange: setConnectorValue,
202
233
  handleChipRemove,
203
234
  handleClear,
@@ -6,30 +6,32 @@ interface UseFocusManagementDeps {
6
6
  isFocused: boolean;
7
7
  conditionsLength: number;
8
8
  inputText: string;
9
- /** In-progress building-chip state — refocus resumes at next missing segment. */
9
+ /** In-progress building-chip state — needed so refocus resumes at the next
10
+ * missing segment instead of (incorrectly) reopening the field menu. */
10
11
  selectedField: FieldMetadata | null;
11
12
  selectedOperator: FilterOperator | null;
12
13
  containerRef: RefObject<HTMLElement | null>;
13
14
  inputRef: RefObject<HTMLInputElement | null>;
14
15
  editingSegment: ChipSegment | null;
15
- /** Direct ref to the attribute segment input when editing. */
16
+ /** Direct ref to the attribute segment <input> when editing — avoids querySelector. */
16
17
  segmentAttributeInputRef: RefObject<HTMLInputElement | null>;
17
- /** Direct ref to the operator segment input when editing. */
18
+ /** Direct ref to the operator segment <input> when editing — avoids querySelector. */
18
19
  segmentOperatorInputRef: RefObject<HTMLInputElement | null>;
19
- /** Direct ref to the value segment input when editing. */
20
+ /** Direct ref to the value segment <input> when editing — avoids querySelector. */
20
21
  segmentValueInputRef: RefObject<HTMLInputElement | null>;
21
- /** Set by FilterInputValueMenu — commits multi-select checked values on blur. */
22
+ /** Ref set by FilterInputValueMenu — calls commitChecked() for multi-select before blur reset. Returns true if committed. */
22
23
  blurCommitRef: RefObject<(() => boolean) | null>;
23
- /** Commits a building chip's freeform value on blur. Returns true if committed. */
24
+ /** Tries to commit a building chip's freeform value on blur. Returns true if committed. */
24
25
  commitBuildingOnBlur: () => boolean;
25
- /** In-progress building chip exists blur/close must preserve it (skip resetState). */
26
+ /** True if there's an in-progress building chip that the blur/close path
27
+ * must preserve (skip resetState). */
26
28
  hasIncompleteBuilding: () => boolean;
27
29
  setIsFocused: (focused: boolean) => void;
28
30
  setMenuState: (state: MenuState) => void;
29
- resetMenuAnchor: () => void;
31
+ resetMenuOffset: () => void;
30
32
  resetState: (continueBuilding?: boolean) => void;
31
33
  }
32
- export declare const useFocusManagement: ({ menuState, isFocused, conditionsLength, inputText, selectedField, selectedOperator, containerRef, inputRef, editingSegment, segmentAttributeInputRef, segmentOperatorInputRef, segmentValueInputRef, blurCommitRef, commitBuildingOnBlur, hasIncompleteBuilding, setIsFocused, setMenuState, resetMenuAnchor, resetState, }: UseFocusManagementDeps) => {
34
+ export declare const useFocusManagement: ({ menuState, isFocused, conditionsLength, inputText, selectedField, selectedOperator, containerRef, inputRef, editingSegment, segmentAttributeInputRef, segmentOperatorInputRef, segmentValueInputRef, blurCommitRef, commitBuildingOnBlur, hasIncompleteBuilding, setIsFocused, setMenuState, resetMenuOffset, resetState, }: UseFocusManagementDeps) => {
33
35
  handleFocus: (e: FocusEvent) => void;
34
36
  handleBlur: (e: FocusEvent) => void;
35
37
  };
@@ -1,7 +1,7 @@
1
- import { useCallback, useEffect, useMemo, useRef } from "react";
1
+ import { useCallback, useEffect, useRef } from "react";
2
2
  import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
3
3
  import { isMenuRelated, nextBuildingMenu } from "../../lib/index.js";
4
- const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText, selectedField, selectedOperator, containerRef, inputRef, editingSegment, segmentAttributeInputRef, segmentOperatorInputRef, segmentValueInputRef, blurCommitRef, commitBuildingOnBlur, hasIncompleteBuilding, setIsFocused, setMenuState, resetMenuAnchor, resetState })=>{
4
+ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText, selectedField, selectedOperator, containerRef, inputRef, editingSegment, segmentAttributeInputRef, segmentOperatorInputRef, segmentValueInputRef, blurCommitRef, commitBuildingOnBlur, hasIncompleteBuilding, setIsFocused, setMenuState, resetMenuOffset, resetState })=>{
5
5
  const handleFocus = useCallback((e)=>{
6
6
  if (e.target?.closest?.('[data-slot="filter-input-connector-chip"]')) return;
7
7
  setIsFocused(true);
@@ -46,10 +46,10 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
46
46
  return;
47
47
  }
48
48
  if (selectedField) {
49
- resetMenuAnchor();
49
+ resetMenuOffset();
50
50
  setMenuState(nextBuildingMenu(selectedField, selectedOperator));
51
51
  } else if (0 === conditionsLength && '' === inputText) {
52
- resetMenuAnchor();
52
+ resetMenuOffset();
53
53
  setMenuState('field');
54
54
  }
55
55
  prevFocusedRef.current = isFocused;
@@ -60,18 +60,9 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
60
60
  selectedField,
61
61
  selectedOperator,
62
62
  editingSegment,
63
- resetMenuAnchor,
63
+ resetMenuOffset,
64
64
  setMenuState
65
65
  ]);
66
- const segmentInputRefsMap = useMemo(()=>({
67
- [SEGMENT_VARIANT.attribute]: segmentAttributeInputRef,
68
- [SEGMENT_VARIANT.operator]: segmentOperatorInputRef,
69
- [SEGMENT_VARIANT.value]: segmentValueInputRef
70
- }), [
71
- segmentAttributeInputRef,
72
- segmentOperatorInputRef,
73
- segmentValueInputRef
74
- ]);
75
66
  useEffect(()=>{
76
67
  if ('closed' === menuState) return;
77
68
  if (!isFocused) return;
@@ -83,11 +74,18 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
83
74
  if (!container) return;
84
75
  const active = document.activeElement;
85
76
  if (active && !container.contains(active) && !isMenuRelated(active)) return;
86
- const dest = editingSegment ? segmentInputRefsMap[editingSegment]?.current ?? null : inputRef.current;
87
- if (!dest) return;
88
- if (document.activeElement === dest) return;
89
- dest.focus();
90
- if (editingSegment) dest.select();
77
+ if (editingSegment) {
78
+ const segmentInputRefs = {
79
+ [SEGMENT_VARIANT.attribute]: segmentAttributeInputRef,
80
+ [SEGMENT_VARIANT.operator]: segmentOperatorInputRef,
81
+ [SEGMENT_VARIANT.value]: segmentValueInputRef
82
+ };
83
+ const segmentInput = segmentInputRefs[editingSegment]?.current ?? null;
84
+ if (segmentInput && document.activeElement !== segmentInput) {
85
+ segmentInput.focus();
86
+ segmentInput.select();
87
+ }
88
+ } else if (document.activeElement !== inputRef.current) inputRef.current?.focus();
91
89
  });
92
90
  });
93
91
  return ()=>{
@@ -100,34 +98,9 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
100
98
  inputRef,
101
99
  editingSegment,
102
100
  containerRef,
103
- segmentInputRefsMap
104
- ]);
105
- useEffect(()=>{
106
- if ('closed' === menuState) return;
107
- if (!isFocused) return;
108
- const handleFocusIn = (e)=>{
109
- const targetEl = e.target;
110
- if (!targetEl) return;
111
- const menu = targetEl.closest('[data-filter-input-menu]');
112
- if (!menu) return;
113
- if (menu.querySelector('[data-scope="date-picker"]')) return;
114
- const tag = targetEl.tagName;
115
- if ('BUTTON' === tag || 'INPUT' === tag || 'TEXTAREA' === tag || 'SELECT' === tag) return;
116
- const dest = editingSegment ? segmentInputRefsMap[editingSegment]?.current : inputRef.current;
117
- if (!dest) return;
118
- if (document.activeElement === dest) return;
119
- dest.focus({
120
- preventScroll: true
121
- });
122
- };
123
- document.addEventListener('focusin', handleFocusIn);
124
- return ()=>document.removeEventListener('focusin', handleFocusIn);
125
- }, [
126
- menuState,
127
- isFocused,
128
- editingSegment,
129
- inputRef,
130
- segmentInputRefsMap
101
+ segmentAttributeInputRef,
102
+ segmentOperatorInputRef,
103
+ segmentValueInputRef
131
104
  ]);
132
105
  return {
133
106
  handleFocus,