@wallarm-org/design-system 0.66.3 → 0.67.1
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/dist/components/FilterInput/FilterInputContext/types.d.ts +6 -0
- package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.d.ts +2 -0
- package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.js +4 -0
- package/dist/components/FilterInput/FilterInputErrors/parseFilterInputErrors.js +11 -2
- package/dist/components/FilterInput/FilterInputField/ChipsWithGaps.js +4 -2
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/FilterInputChip.d.ts +7 -1
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/FilterInputChip.js +44 -6
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/PairSeparator.d.ts +3 -0
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/PairSeparator.js +16 -0
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/context/EditingContext.d.ts +2 -0
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/index.d.ts +3 -2
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/index.js +3 -2
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/segmentVariant.d.ts +2 -0
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/segmentVariant.js +2 -1
- package/dist/components/FilterInput/FilterInputField/FilterInputField.js +3 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/deriveAutocompleteValues.d.ts +8 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/deriveAutocompleteValues.js +22 -3
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useAutocompleteState.d.ts +10 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useAutocompleteState.js +6 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipEditing.d.ts +2 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useChipEditing.js +31 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts +2 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js +14 -3
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/types.d.ts +9 -0
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useOperatorFlow.d.ts +1 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useOperatorFlow.js +22 -7
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useValueFlow.d.ts +1 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useMenuFlow/useValueFlow.js +77 -13
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResetState.d.ts +3 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResetState.js +5 -1
- package/dist/components/FilterInput/hooks/useFilterInputExpression/buildChips.js +26 -1
- package/dist/components/FilterInput/hooks/useFilterInputExpression/expression.d.ts +9 -3
- package/dist/components/FilterInput/hooks/useFilterInputExpression/expression.js +75 -9
- package/dist/components/FilterInput/hooks/useFilterInputExpression/useFilterInputExpression.d.ts +1 -1
- package/dist/components/FilterInput/hooks/useFilterInputExpression/useFilterInputExpression.js +99 -71
- package/dist/components/FilterInput/lib/constants.js +2 -2
- package/dist/components/FilterInput/types.d.ts +25 -1
- package/dist/metadata/components.json +8 -2
- package/package.json +1 -1
package/dist/components/FilterInput/hooks/useFilterInputExpression/useFilterInputExpression.js
CHANGED
|
@@ -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
|
-
const result = expressionToConditions(value);
|
|
100
|
-
|
|
108
|
+
const result = expressionToConditions(value, fields);
|
|
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,
|
|
@@ -113,100 +124,117 @@ const useFilterInputExpression = ({ fields, value, onChange, error, externalErro
|
|
|
113
124
|
error,
|
|
114
125
|
externalErrors
|
|
115
126
|
]);
|
|
116
|
-
const upsertCondition = useCallback((field, operator, val, editingChipId, atIndex, error, dateOrigin)=>{
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
const upsertCondition = useCallback((field, operator, val, editingChipId, atIndex, error, dateOrigin, side)=>{
|
|
128
|
+
const prev = stateRef.current;
|
|
129
|
+
if (1 === side) {
|
|
130
|
+
const idx = null != editingChipId ? chipIdToConditionIndex(editingChipId) : prev.conditions.length - 1;
|
|
131
|
+
if (null == idx || idx < 0 || idx >= prev.conditions.length) return;
|
|
132
|
+
const base = prev.conditions[idx];
|
|
133
|
+
const updated = [
|
|
134
|
+
...prev.conditions
|
|
135
|
+
];
|
|
136
|
+
updated[idx] = {
|
|
137
|
+
...base,
|
|
138
|
+
pair: {
|
|
139
|
+
...operator && {
|
|
140
|
+
operator
|
|
141
|
+
},
|
|
142
|
+
value: val,
|
|
143
|
+
...error && {
|
|
144
|
+
error
|
|
145
|
+
},
|
|
146
|
+
...dateOrigin && {
|
|
147
|
+
dateOrigin
|
|
148
|
+
}
|
|
149
|
+
}
|
|
124
150
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
151
|
+
applyState({
|
|
152
|
+
conditions: updated,
|
|
153
|
+
connectors: prev.connectors
|
|
154
|
+
}, true);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const condition = buildCondition(field, operator, val, error, dateOrigin);
|
|
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);
|
|
128
164
|
}, [
|
|
129
|
-
|
|
165
|
+
applyState
|
|
130
166
|
]);
|
|
131
167
|
const removeCondition = useCallback((chipId)=>{
|
|
132
168
|
const idx = chipIdToConditionIndex(chipId);
|
|
133
169
|
if (null === idx) return;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
onChange?.(buildExpression(next.conditions, next.connectors));
|
|
143
|
-
return next;
|
|
144
|
-
});
|
|
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);
|
|
145
178
|
}, [
|
|
146
|
-
|
|
179
|
+
applyState
|
|
147
180
|
]);
|
|
148
181
|
const removeConditionAtIndex = useCallback((idx)=>{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
onChange?.(buildExpression(next.conditions, next.connectors));
|
|
159
|
-
return next;
|
|
160
|
-
});
|
|
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);
|
|
161
191
|
}, [
|
|
162
|
-
|
|
192
|
+
applyState
|
|
163
193
|
]);
|
|
164
194
|
const clearAll = useCallback(()=>{
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return next;
|
|
177
|
-
});
|
|
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);
|
|
178
206
|
}, [
|
|
207
|
+
applyState,
|
|
179
208
|
onChange
|
|
180
209
|
]);
|
|
181
210
|
const replaceExpression = useCallback((expr)=>{
|
|
182
|
-
const result = expressionToConditions(expr);
|
|
183
|
-
|
|
211
|
+
const result = expressionToConditions(expr, fields);
|
|
212
|
+
applyState({
|
|
184
213
|
conditions: result.conditions,
|
|
185
214
|
connectors: result.connectors
|
|
186
|
-
});
|
|
215
|
+
}, false);
|
|
187
216
|
onChange?.(expr);
|
|
188
217
|
}, [
|
|
189
|
-
|
|
218
|
+
applyState,
|
|
219
|
+
onChange,
|
|
220
|
+
fields
|
|
190
221
|
]);
|
|
191
222
|
const setConnectorValue = useCallback((connectorId, value)=>{
|
|
192
223
|
const match = connectorId.match(CONNECTOR_ID_PATTERN);
|
|
193
224
|
if (!match) return;
|
|
194
225
|
const condIdx = Number(match[1]);
|
|
195
226
|
const connectorIdx = condIdx - 1;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
onChange?.(buildExpression(next.conditions, next.connectors));
|
|
206
|
-
return next;
|
|
207
|
-
});
|
|
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);
|
|
208
236
|
}, [
|
|
209
|
-
|
|
237
|
+
applyState
|
|
210
238
|
]);
|
|
211
239
|
return {
|
|
212
240
|
conditions: state.conditions,
|
|
@@ -14,7 +14,10 @@ export type ChipErrorSegment = boolean | 'attribute' | 'value';
|
|
|
14
14
|
* Re-declared in several option interfaces — exported here to keep the source of
|
|
15
15
|
* truth single-rooted (changes to the signature reach all consumers).
|
|
16
16
|
*/
|
|
17
|
-
export type UpsertCondition = (field: FieldMetadata, operator: FilterOperator | undefined, val: string | number | boolean | null | Array<string | number | boolean>, editingChipId?: string | null, atIndex?: number, error?: ChipErrorSegment, dateOrigin?: 'relative' | 'absolute'
|
|
17
|
+
export type UpsertCondition = (field: FieldMetadata, operator: FilterOperator | undefined, val: string | number | boolean | null | Array<string | number | boolean>, editingChipId?: string | null, atIndex?: number, error?: ChipErrorSegment, dateOrigin?: 'relative' | 'absolute',
|
|
18
|
+
/** When 1, write the paired (second) triplet onto the target condition instead
|
|
19
|
+
* of replacing the base triplet. Defaults to 0 (base triplet). */
|
|
20
|
+
side?: 0 | 1) => void;
|
|
18
21
|
export interface FilterInputChipData {
|
|
19
22
|
id: string;
|
|
20
23
|
variant: FilterInputChipVariant;
|
|
@@ -30,6 +33,13 @@ export interface FilterInputChipData {
|
|
|
30
33
|
errorValueIndices?: number[];
|
|
31
34
|
/** When true, the chip cannot be edited or removed */
|
|
32
35
|
disabled?: boolean;
|
|
36
|
+
/** Second paired triplet (display) for two-step fields. */
|
|
37
|
+
pair?: {
|
|
38
|
+
attribute: string;
|
|
39
|
+
operator?: string;
|
|
40
|
+
value?: string;
|
|
41
|
+
error?: ChipErrorSegment;
|
|
42
|
+
};
|
|
33
43
|
}
|
|
34
44
|
/**
|
|
35
45
|
* Field Type for filter attributes
|
|
@@ -120,6 +130,13 @@ export interface FieldMetadata {
|
|
|
120
130
|
* emitting the query. Display in the chip is unaffected.
|
|
121
131
|
*/
|
|
122
132
|
serializeValue?: (value: string | number | boolean) => string | number | boolean;
|
|
133
|
+
/**
|
|
134
|
+
* When set, this field is a two-step paired field: the chip holds a second
|
|
135
|
+
* attribute/operator/value triplet. The paired segment is a full field
|
|
136
|
+
* definition (label, type, operators, values, validate, …). Nesting is one
|
|
137
|
+
* level only — a pairedField's own `pairedField` is ignored.
|
|
138
|
+
*/
|
|
139
|
+
pairedField?: FieldMetadata;
|
|
123
140
|
}
|
|
124
141
|
/**
|
|
125
142
|
* Expression Tree Types
|
|
@@ -139,6 +156,13 @@ export interface Condition {
|
|
|
139
156
|
dateOrigin?: 'relative' | 'absolute';
|
|
140
157
|
/** When true, the condition cannot be edited or removed */
|
|
141
158
|
disabled?: boolean;
|
|
159
|
+
/** Second paired triplet. Present only for fields with `pairedField`. */
|
|
160
|
+
pair?: {
|
|
161
|
+
operator?: FilterOperator;
|
|
162
|
+
value: string | number | boolean | null | Array<string | number | boolean>;
|
|
163
|
+
error?: ChipErrorSegment;
|
|
164
|
+
dateOrigin?: 'relative' | 'absolute';
|
|
165
|
+
};
|
|
142
166
|
}
|
|
143
167
|
/**
|
|
144
168
|
* Group Node - Represents a grouped expression with AND/OR logic
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"generatedAt": "2026-06-
|
|
2
|
+
"version": "0.67.0",
|
|
3
|
+
"generatedAt": "2026-06-24T17:08:52.641Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -29593,6 +29593,12 @@
|
|
|
29593
29593
|
"required": false,
|
|
29594
29594
|
"description": "When true, the chip cannot be edited or removed (dimmed appearance)"
|
|
29595
29595
|
},
|
|
29596
|
+
{
|
|
29597
|
+
"name": "pair",
|
|
29598
|
+
"type": "complex",
|
|
29599
|
+
"required": false,
|
|
29600
|
+
"description": "Second paired triplet (two-step fields). The paired attribute is fixed."
|
|
29601
|
+
},
|
|
29596
29602
|
{
|
|
29597
29603
|
"name": "defaultChecked",
|
|
29598
29604
|
"type": "boolean | undefined",
|