@wallarm-org/design-system 0.78.1 → 0.79.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.
- package/dist/components/FilterInput/FilterInputErrors/parseFilterInputErrors.js +2 -2
- package/dist/components/FilterInput/FilterInputField/ChipsWithGaps.js +1 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.d.ts +21 -3
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.js +10 -75
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FlatValueMenu.d.ts +8 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FlatValueMenu.js +81 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/NestedValueMenu.d.ts +10 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/NestedValueMenu.js +145 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/NestedValueMenuItem.d.ts +26 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/NestedValueMenuItem.js +54 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuFooterHints.d.ts +12 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuFooterHints.js +69 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useNestedValueMenuState.d.ts +65 -0
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useNestedValueMenuState.js +293 -0
- package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.d.ts +3 -1
- package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.js +20 -1
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/deriveAutocompleteValues.js +3 -3
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/lib/valueResolution.js +5 -5
- package/dist/components/FilterInput/hooks/useFilterInputExpression/buildChips.js +2 -2
- package/dist/components/FilterInput/lib/buildValueMenuSections.d.ts +33 -0
- package/dist/components/FilterInput/lib/buildValueMenuSections.js +68 -0
- package/dist/components/FilterInput/lib/collapseValuesToLabels.d.ts +32 -0
- package/dist/components/FilterInput/lib/collapseValuesToLabels.js +55 -0
- package/dist/components/FilterInput/lib/fields.d.ts +19 -7
- package/dist/components/FilterInput/lib/fields.js +18 -4
- package/dist/components/FilterInput/lib/index.d.ts +3 -1
- package/dist/components/FilterInput/lib/index.js +3 -1
- package/dist/components/FilterInput/lib/validation.js +2 -2
- package/dist/components/FilterInput/types.d.ts +31 -2
- package/dist/metadata/components.json +2 -2
- package/package.json +1 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuFooter.d.ts +0 -6
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuFooter.js +0 -72
|
@@ -1,13 +1,27 @@
|
|
|
1
|
+
const isValueGroup = (option)=>Array.isArray(option?.children);
|
|
2
|
+
const collectLeaves = (options)=>{
|
|
3
|
+
if (!options) return [];
|
|
4
|
+
const leaves = [];
|
|
5
|
+
for (const option of options)if (isValueGroup(option)) leaves.push(...collectLeaves(option.children));
|
|
6
|
+
else leaves.push(option);
|
|
7
|
+
return leaves;
|
|
8
|
+
};
|
|
9
|
+
const findLeafInOptions = (options, key)=>{
|
|
10
|
+
if (!options) return;
|
|
11
|
+
for (const option of options)if (isValueGroup(option)) {
|
|
12
|
+
const found = findLeafInOptions(option.children, key);
|
|
13
|
+
if (found) return found;
|
|
14
|
+
} else if (String(option.value) === key) return option;
|
|
15
|
+
};
|
|
1
16
|
const findOptionByValue = (field, value)=>{
|
|
2
17
|
if (!field?.values || null == value) return;
|
|
3
|
-
|
|
4
|
-
return field.values.find((opt)=>String(opt.value) === key);
|
|
18
|
+
return findLeafInOptions(field.values, String(value));
|
|
5
19
|
};
|
|
6
20
|
const findValueLabelInFields = (value, fields)=>{
|
|
7
21
|
if (null == value) return;
|
|
8
22
|
const key = String(value);
|
|
9
23
|
for (const f of fields){
|
|
10
|
-
const opt = f.values
|
|
24
|
+
const opt = findLeafInOptions(f.values, key);
|
|
11
25
|
if (opt) return opt.label;
|
|
12
26
|
}
|
|
13
27
|
};
|
|
@@ -31,4 +45,4 @@ const hasStaticAllowlist = (field)=>{
|
|
|
31
45
|
if ((field.values?.length ?? 0) > 0) return true;
|
|
32
46
|
return (field.options?.length ?? 0) > 0;
|
|
33
47
|
};
|
|
34
|
-
export { findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist };
|
|
48
|
+
export { collectLeaves, findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist, isValueGroup };
|
|
@@ -4,11 +4,13 @@ export { applyAcceptChar } from './applyAcceptChar';
|
|
|
4
4
|
export { applyFieldValueTransforms } from './applyFieldValueTransforms';
|
|
5
5
|
export { applyKnownFieldHelpers, getKnownFieldSerializer } from './applyKnownFieldHelpers';
|
|
6
6
|
export { buildFieldMenuSections, type FieldMenuSection } from './buildFieldMenuSections';
|
|
7
|
+
export { buildValueMenuSections, type ValueMenuRow, type ValueMenuSection, } from './buildValueMenuSections';
|
|
8
|
+
export { type CollapseToken, collapseValues } from './collapseValuesToLabels';
|
|
7
9
|
export { chipIdToConditionIndex, findChipSplitIndex, incompleteTripletError, isEmptyFilterValue, } from './conditions';
|
|
8
10
|
export { CONNECTOR_ID_PATTERN, MENU_BASE_GUTTER, MENU_CHIP_GUTTER_OFFSET, NO_VALUE_OPERATORS, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, OPERATORS_BY_TYPE, QUERY_BAR_SELECTOR, VARIANT_LABELS, } from './constants';
|
|
9
11
|
export { COUNTRY_OPTIONS } from './country';
|
|
10
12
|
export { type AnchorBounds, buildAnchoredRect, isMenuRelated, toAnchorBounds } from './dom';
|
|
11
|
-
export { findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist, } from './fields';
|
|
13
|
+
export { collectLeaves, findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist, isValueGroup, } from './fields';
|
|
12
14
|
export { filterAndSort } from './filterSort';
|
|
13
15
|
export { getCurrentValueTokenText, getValueFilterText } from './menuFilterText';
|
|
14
16
|
export { getFieldOperators, getOperatorFromLabel, getOperatorLabel, isBetweenOperator, isBuildingComplete, isMultiSelectOperator, isNoValueOperator, isOperatorAllowedForField, isValueShapeCompatible, NO_VALUE_PLACEHOLDER, nextBuildingMenu, } from './operators';
|
|
@@ -3,11 +3,13 @@ export { applyAcceptChar } from "./applyAcceptChar.js";
|
|
|
3
3
|
export { applyFieldValueTransforms } from "./applyFieldValueTransforms.js";
|
|
4
4
|
export { applyKnownFieldHelpers, getKnownFieldSerializer } from "./applyKnownFieldHelpers.js";
|
|
5
5
|
export { buildFieldMenuSections } from "./buildFieldMenuSections.js";
|
|
6
|
+
export { buildValueMenuSections } from "./buildValueMenuSections.js";
|
|
7
|
+
export { collapseValues } from "./collapseValuesToLabels.js";
|
|
6
8
|
export { chipIdToConditionIndex, findChipSplitIndex, incompleteTripletError, isEmptyFilterValue } from "./conditions.js";
|
|
7
9
|
export { CONNECTOR_ID_PATTERN, MENU_BASE_GUTTER, MENU_CHIP_GUTTER_OFFSET, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, VARIANT_LABELS } from "./constants.js";
|
|
8
10
|
export { COUNTRY_OPTIONS } from "./country/index.js";
|
|
9
11
|
export { buildAnchoredRect, isMenuRelated, toAnchorBounds } from "./dom.js";
|
|
10
|
-
export { findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist } from "./fields.js";
|
|
12
|
+
export { collectLeaves, findOptionByValue, findValueLabelInFields, getFieldValues, hasFieldValues, hasStaticAllowlist, isValueGroup } from "./fields.js";
|
|
11
13
|
export { filterAndSort } from "./filterSort.js";
|
|
12
14
|
export { getCurrentValueTokenText, getValueFilterText } from "./menuFilterText.js";
|
|
13
15
|
export { NO_VALUE_PLACEHOLDER, getFieldOperators, getOperatorFromLabel, getOperatorLabel, isBetweenOperator, isBuildingComplete, isMultiSelectOperator, isNoValueOperator, isOperatorAllowedForField, isValueShapeCompatible, nextBuildingMenu } from "./operators.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isDatePreset } from "../FilterInputMenu/FilterInputDateValueMenu/constants.js";
|
|
2
|
-
import { getFieldValues, hasStaticAllowlist } from "./fields.js";
|
|
2
|
+
import { collectLeaves, getFieldValues, hasStaticAllowlist } from "./fields.js";
|
|
3
3
|
const isValueOfType = (value, type)=>{
|
|
4
4
|
switch(type){
|
|
5
5
|
case 'integer':
|
|
@@ -43,7 +43,7 @@ const getInvalidValueIndices = (field, values)=>{
|
|
|
43
43
|
return acc;
|
|
44
44
|
}, []);
|
|
45
45
|
if (field.getSuggestions) return [];
|
|
46
|
-
const allowlist = hasStaticAllowlist(field) ? getFieldValues(field) : null;
|
|
46
|
+
const allowlist = hasStaticAllowlist(field) ? collectLeaves(getFieldValues(field)) : null;
|
|
47
47
|
return values.reduce((acc, v, idx)=>{
|
|
48
48
|
if (null == v) return acc;
|
|
49
49
|
if (!isValueOfType(v, field.type)) {
|
|
@@ -50,10 +50,25 @@ export type FieldType = 'string' | 'integer' | 'date' | 'float' | 'boolean' | 'e
|
|
|
50
50
|
*/
|
|
51
51
|
export type FilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'like' | 'not_like' | 'in' | 'not_in' | 'is_null' | 'is_not_null' | 'between';
|
|
52
52
|
/**
|
|
53
|
-
* Value option for enum/select fields
|
|
53
|
+
* Value option for enum/select fields.
|
|
54
|
+
*
|
|
55
|
+
* A value option is one of two shapes:
|
|
56
|
+
* - a **leaf**: carries a committable `value` (the only thing that reaches the
|
|
57
|
+
* expression tree / backend);
|
|
58
|
+
* - a **group**: carries `children` and **no** `value` — a purely presentational
|
|
59
|
+
* node. Top-level groups render as section headers in the value menu; nested
|
|
60
|
+
* groups render as a submenu trigger row (e.g. an "Attack type" like
|
|
61
|
+
* `SQL injection` that opens a submenu of concrete leaf sub-types). Selecting
|
|
62
|
+
* or toggling a group is a bulk shortcut for its descendant leaves; the group
|
|
63
|
+
* itself is never committed. Nesting is recursive.
|
|
54
64
|
*/
|
|
55
65
|
export interface FieldValueOption {
|
|
56
|
-
|
|
66
|
+
/**
|
|
67
|
+
* The committable value. Present on **leaf** options only. Group options
|
|
68
|
+
* (those with `children`) omit it — they are presentational and never
|
|
69
|
+
* committed; only their descendant leaves reach the expression.
|
|
70
|
+
*/
|
|
71
|
+
value?: string | number | boolean;
|
|
57
72
|
label: string;
|
|
58
73
|
badge?: {
|
|
59
74
|
color: BadgeColor;
|
|
@@ -67,6 +82,20 @@ export interface FieldValueOption {
|
|
|
67
82
|
* share a label (two `request-id` rows with different paths).
|
|
68
83
|
*/
|
|
69
84
|
description?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Nested sub-values. When present, this option is a **group** (no own
|
|
87
|
+
* `value`): a section header at the top level, or a submenu trigger when
|
|
88
|
+
* nested. Recursive — a group's children may themselves be groups. Only the
|
|
89
|
+
* leaves (options without `children`) are committable.
|
|
90
|
+
*/
|
|
91
|
+
children?: FieldValueOption[];
|
|
92
|
+
/**
|
|
93
|
+
* Optional section-header label used to bucket top-level value options under
|
|
94
|
+
* a heading in the value menu (parallel to `FieldGroup` for the field menu).
|
|
95
|
+
* An alternative to wrapping options in a top-level group node; ignored for
|
|
96
|
+
* options nested inside a group.
|
|
97
|
+
*/
|
|
98
|
+
section?: string;
|
|
70
99
|
}
|
|
71
100
|
/**
|
|
72
101
|
* Field Metadata Interface
|
package/package.json
CHANGED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { DropdownMenuFooter } from "../../../DropdownMenu/index.js";
|
|
3
|
-
import { Kbd } from "../../../Kbd/Kbd.js";
|
|
4
|
-
import { KbdGroup } from "../../../Kbd/KbdGroup.js";
|
|
5
|
-
const ValueMenuFooter = ({ multiSelect })=>/*#__PURE__*/ jsx(DropdownMenuFooter, {
|
|
6
|
-
children: multiSelect ? /*#__PURE__*/ jsxs(Fragment, {
|
|
7
|
-
children: [
|
|
8
|
-
/*#__PURE__*/ jsxs("span", {
|
|
9
|
-
className: "flex items-center gap-4",
|
|
10
|
-
children: [
|
|
11
|
-
/*#__PURE__*/ jsx(KbdGroup, {
|
|
12
|
-
children: /*#__PURE__*/ jsx(Kbd, {
|
|
13
|
-
children: "↵"
|
|
14
|
-
})
|
|
15
|
-
}),
|
|
16
|
-
"to select"
|
|
17
|
-
]
|
|
18
|
-
}),
|
|
19
|
-
/*#__PURE__*/ jsxs("span", {
|
|
20
|
-
className: "flex items-center gap-4",
|
|
21
|
-
children: [
|
|
22
|
-
/*#__PURE__*/ jsxs(KbdGroup, {
|
|
23
|
-
children: [
|
|
24
|
-
/*#__PURE__*/ jsx(Kbd, {
|
|
25
|
-
children: "⌘"
|
|
26
|
-
}),
|
|
27
|
-
/*#__PURE__*/ jsx(Kbd, {
|
|
28
|
-
children: "↑"
|
|
29
|
-
}),
|
|
30
|
-
/*#__PURE__*/ jsx(Kbd, {
|
|
31
|
-
children: "↓"
|
|
32
|
-
})
|
|
33
|
-
]
|
|
34
|
-
}),
|
|
35
|
-
"to multi-select"
|
|
36
|
-
]
|
|
37
|
-
})
|
|
38
|
-
]
|
|
39
|
-
}) : /*#__PURE__*/ jsxs(Fragment, {
|
|
40
|
-
children: [
|
|
41
|
-
/*#__PURE__*/ jsxs("span", {
|
|
42
|
-
className: "flex items-center gap-4",
|
|
43
|
-
children: [
|
|
44
|
-
/*#__PURE__*/ jsxs(KbdGroup, {
|
|
45
|
-
children: [
|
|
46
|
-
/*#__PURE__*/ jsx(Kbd, {
|
|
47
|
-
children: "↑"
|
|
48
|
-
}),
|
|
49
|
-
/*#__PURE__*/ jsx(Kbd, {
|
|
50
|
-
children: "↓"
|
|
51
|
-
})
|
|
52
|
-
]
|
|
53
|
-
}),
|
|
54
|
-
"to navigate"
|
|
55
|
-
]
|
|
56
|
-
}),
|
|
57
|
-
/*#__PURE__*/ jsxs("span", {
|
|
58
|
-
className: "flex items-center gap-4",
|
|
59
|
-
children: [
|
|
60
|
-
/*#__PURE__*/ jsx(KbdGroup, {
|
|
61
|
-
children: /*#__PURE__*/ jsx(Kbd, {
|
|
62
|
-
children: "↵"
|
|
63
|
-
})
|
|
64
|
-
}),
|
|
65
|
-
"to select"
|
|
66
|
-
]
|
|
67
|
-
})
|
|
68
|
-
]
|
|
69
|
-
})
|
|
70
|
-
});
|
|
71
|
-
ValueMenuFooter.displayName = 'ValueMenuFooter';
|
|
72
|
-
export { ValueMenuFooter };
|