@wallarm-org/design-system 0.67.0 → 0.67.2

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.
@@ -5,7 +5,7 @@ import type { MenuFlowInternalDeps } from './types';
5
5
  * `handleCustomOperatorCommit` is the keyboard-typed path — it resolves the
6
6
  * typed text to a known operator (label / raw key / symbol) and delegates.
7
7
  */
8
- export declare const useOperatorFlow: ({ editing, selectedField, selectedOperator, insertIndex, upsertCondition, conditionsRef, resetState, setSelectedOperator, setMenuState, setBuildingMultiValue, setInputText, }: MenuFlowInternalDeps) => {
8
+ export declare const useOperatorFlow: ({ editing, selectedField, selectedOperator, insertIndex, upsertCondition, conditionsRef, resetState, setSelectedOperator, setMenuState, setBuildingMultiValue, setInputText, buildingSide, buildingBase, setBuildingBase, setBuildingSide, }: MenuFlowInternalDeps) => {
9
9
  handleOperatorSelect: (operator: FilterOperator) => void;
10
10
  handleCustomOperatorCommit: (customText: string) => void;
11
11
  };
@@ -1,7 +1,7 @@
1
1
  import { useCallback } from "react";
2
2
  import { SEGMENT_VARIANT } from "../../../FilterInputField/FilterInputChip/index.js";
3
3
  import { OPERATOR_SYMBOLS, chipIdToConditionIndex, getFieldOperators, getOperatorFromLabel, isNoValueOperator, isOperatorAllowedForField, isValueShapeCompatible } from "../../../lib/index.js";
4
- const useOperatorFlow = ({ editing, selectedField, selectedOperator, insertIndex, upsertCondition, conditionsRef, resetState, setSelectedOperator, setMenuState, setBuildingMultiValue, setInputText })=>{
4
+ const useOperatorFlow = ({ editing, selectedField, selectedOperator, insertIndex, upsertCondition, conditionsRef, resetState, setSelectedOperator, setMenuState, setBuildingMultiValue, setInputText, buildingSide, buildingBase, setBuildingBase, setBuildingSide })=>{
5
5
  const { editingChipId, editingSegment, editingSide, isBuildingEdit, setEditingSegment, setSegmentFilterText, clearEditing } = editing;
6
6
  const handleOperatorSelect = useCallback((operator)=>{
7
7
  if (!selectedField) return;
@@ -19,6 +19,14 @@ const useOperatorFlow = ({ editing, selectedField, selectedOperator, insertIndex
19
19
  return;
20
20
  }
21
21
  if (isNoValueOperator(operator)) {
22
+ if (1 === buildingSide && buildingBase && !editingChipId) {
23
+ upsertCondition(buildingBase.field, buildingBase.operator, buildingBase.value, null, insertIndex);
24
+ upsertCondition(selectedField, operator, null, null, void 0, void 0, void 0, 1);
25
+ setBuildingBase(null);
26
+ setBuildingSide(0);
27
+ resetState(true);
28
+ return;
29
+ }
22
30
  const isEditing = !!editingChipId;
23
31
  upsertCondition(selectedField, operator, null, editingChipId, isEditing ? void 0 : insertIndex, void 0, void 0, editingSide);
24
32
  resetState(!isEditing);
@@ -61,7 +69,11 @@ const useOperatorFlow = ({ editing, selectedField, selectedOperator, insertIndex
61
69
  setSelectedOperator,
62
70
  setMenuState,
63
71
  setBuildingMultiValue,
64
- setInputText
72
+ setInputText,
73
+ buildingSide,
74
+ buildingBase,
75
+ setBuildingBase,
76
+ setBuildingSide
65
77
  ]);
66
78
  const handleCustomOperatorCommit = useCallback((customText)=>{
67
79
  if (!selectedField || !customText.trim()) return;
@@ -86,10 +86,11 @@ const buildPairChip = (condition, field, fields)=>{
86
86
  if (!condition.pair || !field?.pairedField) return;
87
87
  const pf = field.pairedField;
88
88
  const { operator, value, error } = condition.pair;
89
+ const displayValue = operator && isNoValueOperator(operator) ? NO_VALUE_PLACEHOLDER : resolveValueLabel(value, pf, fields) ?? String(value ?? '');
89
90
  return {
90
91
  attribute: pf.label || pf.name,
91
92
  operator: operator ? getOperatorLabel(operator, pf.type || DEFAULT_FIELD_TYPE) : void 0,
92
- value: resolveValueLabel(value, pf, fields) ?? String(value ?? ''),
93
+ value: displayValue,
93
94
  ...error && {
94
95
  error
95
96
  }
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useMemo, useState } from "react";
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
2
  import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
3
3
  import { CONNECTOR_ID_PATTERN, chipIdToConditionIndex, validateValueForField } from "../../lib/index.js";
4
4
  import { applyExternalErrors } from "./applyExternalErrors.js";
@@ -94,13 +94,24 @@ const addConnectorIfNeeded = (connectors, newConditionsLength, editingChipId, at
94
94
  };
95
95
  const useFilterInputExpression = ({ fields, value, onChange, error, externalErrors })=>{
96
96
  const [state, setState] = useState(EMPTY_STATE);
97
+ const stateRef = useRef(state);
98
+ const applyState = useCallback((next, emit)=>{
99
+ stateRef.current = next;
100
+ setState(next);
101
+ if (emit) onChange?.(buildExpression(next.conditions, next.connectors, fields));
102
+ }, [
103
+ onChange,
104
+ fields
105
+ ]);
97
106
  useEffect(()=>{
98
107
  if (void 0 !== value) {
99
108
  const result = expressionToConditions(value, fields);
100
- setState({
109
+ const next = {
101
110
  conditions: revalidateConditions(result.conditions, fields),
102
111
  connectors: result.connectors
103
- });
112
+ };
113
+ stateRef.current = next;
114
+ setState(next);
104
115
  }
105
116
  }, [
106
117
  value,
@@ -114,9 +125,10 @@ const useFilterInputExpression = ({ fields, value, onChange, error, externalErro
114
125
  externalErrors
115
126
  ]);
116
127
  const upsertCondition = useCallback((field, operator, val, editingChipId, atIndex, error, dateOrigin, side)=>{
117
- if (1 === side) return void setState((prev)=>{
128
+ const prev = stateRef.current;
129
+ if (1 === side) {
118
130
  const idx = null != editingChipId ? chipIdToConditionIndex(editingChipId) : prev.conditions.length - 1;
119
- if (null == idx || idx < 0 || idx >= prev.conditions.length) return prev;
131
+ if (null == idx || idx < 0 || idx >= prev.conditions.length) return;
120
132
  const base = prev.conditions[idx];
121
133
  const updated = [
122
134
  ...prev.conditions
@@ -136,89 +148,74 @@ const useFilterInputExpression = ({ fields, value, onChange, error, externalErro
136
148
  }
137
149
  }
138
150
  };
139
- const next = {
151
+ applyState({
140
152
  conditions: updated,
141
153
  connectors: prev.connectors
142
- };
143
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
144
- return next;
145
- });
154
+ }, true);
155
+ return;
156
+ }
146
157
  const condition = buildCondition(field, operator, val, error, dateOrigin);
147
- setState((prev)=>{
148
- const newConditions = applyCondition(prev.conditions, condition, editingChipId, atIndex);
149
- const newConnectors = addConnectorIfNeeded(prev.connectors, newConditions.length, editingChipId, atIndex, prev.conditions.length);
150
- const next = {
151
- conditions: newConditions,
152
- connectors: newConnectors
153
- };
154
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
155
- return next;
156
- });
158
+ const newConditions = applyCondition(prev.conditions, condition, editingChipId, atIndex);
159
+ const newConnectors = addConnectorIfNeeded(prev.connectors, newConditions.length, editingChipId, atIndex, prev.conditions.length);
160
+ applyState({
161
+ conditions: newConditions,
162
+ connectors: newConnectors
163
+ }, true);
157
164
  }, [
158
- onChange,
159
- fields
165
+ applyState
160
166
  ]);
161
167
  const removeCondition = useCallback((chipId)=>{
162
168
  const idx = chipIdToConditionIndex(chipId);
163
169
  if (null === idx) return;
164
- setState((prev)=>{
165
- if (prev.conditions[idx]?.disabled) return prev;
166
- const newConditions = prev.conditions.filter((_, i)=>i !== idx);
167
- const newConnectors = removeConnectorAtConditionIndex(prev.connectors, idx);
168
- const next = {
169
- conditions: newConditions,
170
- connectors: newConnectors
171
- };
172
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
173
- return next;
174
- });
170
+ const prev = stateRef.current;
171
+ if (prev.conditions[idx]?.disabled) return;
172
+ const newConditions = prev.conditions.filter((_, i)=>i !== idx);
173
+ const newConnectors = removeConnectorAtConditionIndex(prev.connectors, idx);
174
+ applyState({
175
+ conditions: newConditions,
176
+ connectors: newConnectors
177
+ }, true);
175
178
  }, [
176
- onChange,
177
- fields
179
+ applyState
178
180
  ]);
179
181
  const removeConditionAtIndex = useCallback((idx)=>{
180
- setState((prev)=>{
181
- if (idx < 0 || idx >= prev.conditions.length) return prev;
182
- if (prev.conditions[idx]?.disabled) return prev;
183
- const newConditions = prev.conditions.filter((_, i)=>i !== idx);
184
- const newConnectors = removeConnectorAtConditionIndex(prev.connectors, idx);
185
- const next = {
186
- conditions: newConditions,
187
- connectors: newConnectors
188
- };
189
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
190
- return next;
191
- });
182
+ const prev = stateRef.current;
183
+ if (idx < 0 || idx >= prev.conditions.length) return;
184
+ if (prev.conditions[idx]?.disabled) return;
185
+ const newConditions = prev.conditions.filter((_, i)=>i !== idx);
186
+ const newConnectors = removeConnectorAtConditionIndex(prev.connectors, idx);
187
+ applyState({
188
+ conditions: newConditions,
189
+ connectors: newConnectors
190
+ }, true);
192
191
  }, [
193
- onChange,
194
- fields
192
+ applyState
195
193
  ]);
196
194
  const clearAll = useCallback(()=>{
197
- setState((prev)=>{
198
- const disabledConditions = prev.conditions.filter((c)=>c.disabled);
199
- if (0 === disabledConditions.length) {
200
- onChange?.(null);
201
- return EMPTY_STATE;
202
- }
203
- const next = {
204
- conditions: disabledConditions,
205
- connectors: []
206
- };
207
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
208
- return next;
209
- });
195
+ const prev = stateRef.current;
196
+ const disabledConditions = prev.conditions.filter((c)=>c.disabled);
197
+ if (0 === disabledConditions.length) {
198
+ applyState(EMPTY_STATE, false);
199
+ onChange?.(null);
200
+ return;
201
+ }
202
+ applyState({
203
+ conditions: disabledConditions,
204
+ connectors: []
205
+ }, true);
210
206
  }, [
211
- onChange,
212
- fields
207
+ applyState,
208
+ onChange
213
209
  ]);
214
210
  const replaceExpression = useCallback((expr)=>{
215
211
  const result = expressionToConditions(expr, fields);
216
- setState({
212
+ applyState({
217
213
  conditions: result.conditions,
218
214
  connectors: result.connectors
219
- });
215
+ }, false);
220
216
  onChange?.(expr);
221
217
  }, [
218
+ applyState,
222
219
  onChange,
223
220
  fields
224
221
  ]);
@@ -227,21 +224,17 @@ const useFilterInputExpression = ({ fields, value, onChange, error, externalErro
227
224
  if (!match) return;
228
225
  const condIdx = Number(match[1]);
229
226
  const connectorIdx = condIdx - 1;
230
- setState((prev)=>{
231
- const updated = [
232
- ...prev.connectors
233
- ];
234
- if (connectorIdx >= 0 && connectorIdx < updated.length) updated[connectorIdx] = value;
235
- const next = {
236
- conditions: prev.conditions,
237
- connectors: updated
238
- };
239
- onChange?.(buildExpression(next.conditions, next.connectors, fields));
240
- return next;
241
- });
227
+ const prev = stateRef.current;
228
+ const updated = [
229
+ ...prev.connectors
230
+ ];
231
+ if (connectorIdx >= 0 && connectorIdx < updated.length) updated[connectorIdx] = value;
232
+ applyState({
233
+ conditions: prev.conditions,
234
+ connectors: updated
235
+ }, true);
242
236
  }, [
243
- onChange,
244
- fields
237
+ applyState
245
238
  ]);
246
239
  return {
247
240
  conditions: state.conditions,
@@ -28,8 +28,8 @@ const OPERATOR_SYMBOLS = {
28
28
  not_like: '!~',
29
29
  in: 'IN',
30
30
  not_in: 'NOT IN',
31
- is_null: '= null',
32
- is_not_null: '!= null',
31
+ is_null: '!= null',
32
+ is_not_null: '= null',
33
33
  between: '<>'
34
34
  };
35
35
  const OPERATOR_LABELS = {
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.66.3",
3
- "generatedAt": "2026-06-24T13:26:24.868Z",
2
+ "version": "0.67.1",
3
+ "generatedAt": "2026-06-24T17:39:16.110Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "0.67.0",
3
+ "version": "0.67.2",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",