@wallarm-org/design-system 0.69.0-rc-feature-AS-1192.1 → 0.69.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 +5 -7
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/ChipSearchInput.js +1 -2
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/FilterInputChip.js +6 -9
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/classes.d.ts +1 -3
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/classes.js +1 -1
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/constants.d.ts +0 -3
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/constants.js +1 -2
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/model/useSizerWidth.d.ts +2 -5
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/model/useSizerWidth.js +4 -5
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.d.ts +0 -2
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.js +4 -2
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuItem.js +6 -14
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useBlurCommit.d.ts +1 -8
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useBlurCommit.js +3 -40
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts +4 -5
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js +2 -38
- package/dist/components/FilterInput/hooks/useFilterInputExpression/buildChips.js +5 -17
- package/dist/components/FilterInput/hooks/useFilterInputExpression/useFilterInputExpression.js +0 -5
- package/dist/components/FilterInput/lib/conditions.d.ts +1 -9
- package/dist/components/FilterInput/lib/conditions.js +1 -5
- package/dist/components/FilterInput/lib/index.d.ts +1 -1
- package/dist/components/FilterInput/lib/index.js +2 -2
- package/dist/components/FilterInput/types.d.ts +0 -8
- package/dist/components/Slider/Slider.d.ts +34 -0
- package/dist/components/Slider/Slider.figma.d.ts +1 -0
- package/dist/components/Slider/Slider.figma.js +123 -0
- package/dist/components/Slider/Slider.js +85 -0
- package/dist/components/Slider/SliderContext.d.ts +31 -0
- package/dist/components/Slider/SliderContext.js +9 -0
- package/dist/components/Slider/SliderControl.d.ts +9 -0
- package/dist/components/Slider/SliderControl.js +35 -0
- package/dist/components/Slider/SliderInput.d.ts +26 -0
- package/dist/components/Slider/SliderInput.js +69 -0
- package/dist/components/Slider/SliderMarks.d.ts +15 -0
- package/dist/components/Slider/SliderMarks.js +58 -0
- package/dist/components/Slider/SliderThumb.d.ts +19 -0
- package/dist/components/Slider/SliderThumb.js +58 -0
- package/dist/components/Slider/SliderValue.d.ts +14 -0
- package/dist/components/Slider/SliderValue.js +21 -0
- package/dist/components/Slider/classes.d.ts +52 -0
- package/dist/components/Slider/classes.js +14 -0
- package/dist/components/Slider/index.d.ts +8 -0
- package/dist/components/Slider/index.js +8 -0
- package/dist/components/Slider/types.d.ts +11 -0
- package/dist/components/Slider/types.js +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/metadata/components.json +905 -1
- package/package.json +1 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/valueOptionSearchText.d.ts +0 -7
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/valueOptionSearchText.js +0 -9
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResumeBuilding.d.ts +0 -31
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useResumeBuilding.js +0 -76
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { SEGMENT_VARIANT } from "../FilterInputField/FilterInputChip/index.js";
|
|
2
|
-
import { getFieldValues, hasStaticAllowlist,
|
|
2
|
+
import { getFieldValues, hasStaticAllowlist, isNoValueOperator, isValidFieldValue } from "../lib/index.js";
|
|
3
3
|
const isPairValueMissing = (condition)=>{
|
|
4
4
|
const pair = condition.pair;
|
|
5
5
|
if (!pair) return true;
|
|
6
6
|
if (pair.operator && isNoValueOperator(pair.operator)) return false;
|
|
7
|
-
|
|
7
|
+
const value = pair.value;
|
|
8
|
+
return null == value || '' === value || Array.isArray(value) && 0 === value.length;
|
|
8
9
|
};
|
|
9
10
|
const parseFilterInputErrors = (conditions, fields)=>{
|
|
10
11
|
const errors = [];
|
|
@@ -12,12 +13,9 @@ const parseFilterInputErrors = (conditions, fields)=>{
|
|
|
12
13
|
const field = fields.find((f)=>f.name === condition.field);
|
|
13
14
|
const baseIsNoValue = null != condition.operator && isNoValueOperator(condition.operator);
|
|
14
15
|
if (field?.pairedField && !baseIsNoValue && isPairValueMissing(condition)) errors.push(`${field.pairedField.label} is required`);
|
|
16
|
+
if (!condition.error) continue;
|
|
15
17
|
const label = field?.label || condition.field;
|
|
16
|
-
|
|
17
|
-
errors.push(`${label} is incomplete`);
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (condition.error) switch(condition.error){
|
|
18
|
+
switch(condition.error){
|
|
21
19
|
case SEGMENT_VARIANT.attribute:
|
|
22
20
|
errors.push(`Unknown field ${condition.field}`);
|
|
23
21
|
break;
|
|
@@ -20,7 +20,6 @@ const ChipSearchInput = ()=>{
|
|
|
20
20
|
ref: inputRef,
|
|
21
21
|
type: "text",
|
|
22
22
|
role: "combobox",
|
|
23
|
-
size: 1,
|
|
24
23
|
"aria-expanded": menuOpen,
|
|
25
24
|
"aria-invalid": error,
|
|
26
25
|
"aria-label": "Filter value",
|
|
@@ -32,7 +31,7 @@ const ChipSearchInput = ()=>{
|
|
|
32
31
|
style: {
|
|
33
32
|
width: `${inputWidth}px`
|
|
34
33
|
},
|
|
35
|
-
className: "h-22
|
|
34
|
+
className: "h-22 border-none bg-transparent p-0 text-sm shadow-none outline-none ring-0"
|
|
36
35
|
}),
|
|
37
36
|
/*#__PURE__*/ jsx("span", {
|
|
38
37
|
ref: sizerRef,
|
|
@@ -10,13 +10,11 @@ import { Segment } from "./Segment.js";
|
|
|
10
10
|
import { SEGMENT_VARIANT } from "./segmentVariant.js";
|
|
11
11
|
const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = false, valueParts, valueSeparator, errorValueIndices, building = false, disabled = false, pair, onRemove, onSegmentClick, onPairSegmentClick, className, ...props })=>{
|
|
12
12
|
const interactive = !disabled;
|
|
13
|
+
const hasError = !!error;
|
|
13
14
|
const internalRef = useRef(null);
|
|
14
15
|
const editing = useEditingContext();
|
|
15
16
|
const isEditingThisChip = null != editing && null != editing.editingSegment && (building ? null == editing.editingChipId : null != chipId && editing.editingChipId === chipId);
|
|
16
17
|
const activeSegment = isEditingThisChip ? editing.editingSegment : null;
|
|
17
|
-
const effectiveError = isEditingThisChip ? false : error;
|
|
18
|
-
const effectivePairError = isEditingThisChip ? void 0 : pair?.error;
|
|
19
|
-
const hasError = !!effectiveError || !!effectivePairError;
|
|
20
18
|
const handleSegmentClick = useCallback((segment, e)=>{
|
|
21
19
|
if (!onSegmentClick) return;
|
|
22
20
|
if (activeSegment === segment) return;
|
|
@@ -64,7 +62,7 @@ const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = fals
|
|
|
64
62
|
interactive,
|
|
65
63
|
disabled,
|
|
66
64
|
building
|
|
67
|
-
}),
|
|
65
|
+
}), 'max-w-[320px]', className),
|
|
68
66
|
"data-slot": "filter-input-condition-chip",
|
|
69
67
|
...building && {
|
|
70
68
|
'data-building': ''
|
|
@@ -74,7 +72,7 @@ const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = fals
|
|
|
74
72
|
/*#__PURE__*/ jsx(Segment, {
|
|
75
73
|
variant: SEGMENT_VARIANT.attribute,
|
|
76
74
|
className: "shrink-0",
|
|
77
|
-
error: true ===
|
|
75
|
+
error: true === error || error === SEGMENT_VARIANT.attribute,
|
|
78
76
|
onClick: interactive ? (e)=>handleSegmentClick(SEGMENT_VARIANT.attribute, e) : void 0,
|
|
79
77
|
onMouseDown: interactive && building ? handleSegmentMouseDown : void 0,
|
|
80
78
|
...segmentEditProps(SEGMENT_VARIANT.attribute),
|
|
@@ -90,8 +88,8 @@ const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = fals
|
|
|
90
88
|
}),
|
|
91
89
|
(value || baseActiveSegment === SEGMENT_VARIANT.value) && /*#__PURE__*/ jsx(Segment, {
|
|
92
90
|
variant: SEGMENT_VARIANT.value,
|
|
93
|
-
className:
|
|
94
|
-
error: baseActiveSegment !== SEGMENT_VARIANT.value && (true ===
|
|
91
|
+
className: "min-w-0",
|
|
92
|
+
error: baseActiveSegment !== SEGMENT_VARIANT.value && (true === error || error === SEGMENT_VARIANT.value),
|
|
95
93
|
valueParts: valueParts,
|
|
96
94
|
valueSeparator: valueSeparator,
|
|
97
95
|
errorValueIndices: errorValueIndices,
|
|
@@ -106,7 +104,6 @@ const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = fals
|
|
|
106
104
|
/*#__PURE__*/ jsx(Segment, {
|
|
107
105
|
variant: SEGMENT_VARIANT.attribute,
|
|
108
106
|
className: "shrink-0",
|
|
109
|
-
onClick: interactive && pair.error ? (e)=>handlePairSegmentClick(SEGMENT_VARIANT.value, e) : void 0,
|
|
110
107
|
children: pair.attribute
|
|
111
108
|
}),
|
|
112
109
|
(pair.operator || pairActiveSegment === SEGMENT_VARIANT.operator) && /*#__PURE__*/ jsx(Segment, {
|
|
@@ -119,7 +116,7 @@ const FilterInputChip = ({ ref, chipId, attribute, operator, value, error = fals
|
|
|
119
116
|
(null != pair.value || pairActiveSegment === SEGMENT_VARIANT.value) && /*#__PURE__*/ jsx(Segment, {
|
|
120
117
|
variant: SEGMENT_VARIANT.value,
|
|
121
118
|
className: "min-w-0",
|
|
122
|
-
error: pairActiveSegment !== SEGMENT_VARIANT.value && (true ===
|
|
119
|
+
error: pairActiveSegment !== SEGMENT_VARIANT.value && (true === pair.error || pair.error === SEGMENT_VARIANT.value),
|
|
123
120
|
onClick: interactive ? (e)=>handlePairSegmentClick('value', e) : void 0,
|
|
124
121
|
...segmentEditProps(SEGMENT_VARIANT.value, 1),
|
|
125
122
|
children: pair.value ?? ''
|
|
@@ -12,9 +12,7 @@ export declare const segmentTextVariants: (props?: ({
|
|
|
12
12
|
variant?: "value" | "operator" | "attribute" | null | undefined;
|
|
13
13
|
error?: boolean | null | undefined;
|
|
14
14
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
|
-
/** Remove button styles — hidden by default, shown on chip hover or button focus
|
|
16
|
-
* `pointer-events-none` while invisible stops it swallowing clicks meant for the
|
|
17
|
-
* chip/input and silently deleting the chip (AS-1179). */
|
|
15
|
+
/** Remove button styles — hidden by default, shown on chip hover or button focus */
|
|
18
16
|
export declare const removeButtonVariants: (props?: ({
|
|
19
17
|
error?: boolean | null | undefined;
|
|
20
18
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -68,7 +68,7 @@ const segmentTextVariants = cva('truncate text-sm', {
|
|
|
68
68
|
error: false
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
|
-
const removeButtonVariants = cva(`absolute -right-[13px] top-[-1px] bottom-[-1px] flex items-center justify-center p-0 cursor-pointer w-[18px] border border-solid border-l-0 rounded-r-8 opacity-0
|
|
71
|
+
const removeButtonVariants = cva(`absolute -right-[13px] top-[-1px] bottom-[-1px] flex items-center justify-center p-0 cursor-pointer w-[18px] border border-solid border-l-0 rounded-r-8 opacity-0 group-hover/chip:opacity-100 focus:opacity-100 transition-opacity ${hiddenWhenSelected}`, {
|
|
72
72
|
variants: {
|
|
73
73
|
error: {
|
|
74
74
|
true: 'border-border-danger bg-bg-light-danger text-text-danger',
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/** Minimum input width in px */
|
|
2
2
|
export declare const MIN_INPUT_WIDTH = 4;
|
|
3
|
-
/** Maximum input width in px — caps the content-sized input so a long value
|
|
4
|
-
* can't grow it past the chip; beyond this it scrolls content natively. */
|
|
5
|
-
export declare const MAX_INPUT_WIDTH = 280;
|
|
6
3
|
/** Extra pixels added to measured width to prevent text clipping */
|
|
7
4
|
export declare const WIDTH_OFFSET = 1;
|
|
8
5
|
/** Approximate width of a single character in px (text-sm fallback) */
|
package/dist/components/FilterInput/FilterInputField/FilterInputChip/model/useSizerWidth.d.ts
CHANGED
|
@@ -6,14 +6,11 @@ interface UseSizerWidthOptions {
|
|
|
6
6
|
text: string;
|
|
7
7
|
/** Minimum width floor (defaults to MIN_INPUT_WIDTH) */
|
|
8
8
|
minWidth?: number;
|
|
9
|
-
/** Maximum width ceiling (defaults to MAX_INPUT_WIDTH) */
|
|
10
|
-
maxWidth?: number;
|
|
11
9
|
}
|
|
12
10
|
/**
|
|
13
11
|
* Measures input width from a hidden sizer span.
|
|
14
12
|
* Falls back to character count * CHAR_WIDTH_PX when the DOM element is unavailable.
|
|
15
|
-
* Returns the measured width + WIDTH_OFFSET to prevent text clipping
|
|
16
|
-
* [minWidth, maxWidth] so a long value can't widen the input past the chip.
|
|
13
|
+
* Returns the measured width + WIDTH_OFFSET to prevent text clipping.
|
|
17
14
|
*/
|
|
18
|
-
export declare const useSizerWidth: ({ sizerRef, text, minWidth,
|
|
15
|
+
export declare const useSizerWidth: ({ sizerRef, text, minWidth, }: UseSizerWidthOptions) => number;
|
|
19
16
|
export {};
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import { CHAR_WIDTH_PX,
|
|
3
|
-
const useSizerWidth = ({ sizerRef, text, minWidth = MIN_INPUT_WIDTH
|
|
2
|
+
import { CHAR_WIDTH_PX, MIN_INPUT_WIDTH, WIDTH_OFFSET } from "../constants.js";
|
|
3
|
+
const useSizerWidth = ({ sizerRef, text, minWidth = MIN_INPUT_WIDTH })=>{
|
|
4
4
|
const [width, setWidth] = useState(minWidth);
|
|
5
5
|
useEffect(()=>{
|
|
6
6
|
const sizerWidth = sizerRef.current?.getBoundingClientRect().width ?? text.length * CHAR_WIDTH_PX;
|
|
7
|
-
setWidth(Math.
|
|
7
|
+
setWidth(Math.max(minWidth, sizerWidth));
|
|
8
8
|
}, [
|
|
9
9
|
text,
|
|
10
|
-
minWidth
|
|
11
|
-
maxWidth
|
|
10
|
+
minWidth
|
|
12
11
|
]);
|
|
13
12
|
return width + WIDTH_OFFSET;
|
|
14
13
|
};
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.js
CHANGED
|
@@ -8,9 +8,11 @@ import { useValueMenuDisplayValues } from "./useValueMenuDisplayValues.js";
|
|
|
8
8
|
import { useValueMenuState } from "./useValueMenuState.js";
|
|
9
9
|
import { ValueMenuFooter } from "./ValueMenuFooter.js";
|
|
10
10
|
import { ValueMenuItem } from "./ValueMenuItem.js";
|
|
11
|
-
import { valueOptionSearchText } from "./valueOptionSearchText.js";
|
|
12
11
|
const FilterInputValueMenu = ({ values, onSelect, onCommit, open = false, onOpenChange, onEscape, multiSelect = false, initialValues = [], highlightValue, width = 'standard', positioning, onBuildingValueChange, onItemToggle, inputRef, filterText = '', menuRef, blurCommitRef, className })=>{
|
|
13
|
-
const filteredValues = useMemo(()=>filterAndSort(values, filterText,
|
|
12
|
+
const filteredValues = useMemo(()=>filterAndSort(values, filterText, (v)=>[
|
|
13
|
+
v.label,
|
|
14
|
+
String(v.value)
|
|
15
|
+
]), [
|
|
14
16
|
values,
|
|
15
17
|
filterText
|
|
16
18
|
]);
|
|
@@ -15,21 +15,13 @@ const ValueMenuItem = ({ option, isChecked, isPending, multiSelect, onSelect, re
|
|
|
15
15
|
type: "secondary",
|
|
16
16
|
variant: "default",
|
|
17
17
|
children: option.badge.text
|
|
18
|
-
}) : /*#__PURE__*/
|
|
18
|
+
}) : /*#__PURE__*/ jsx("div", {
|
|
19
19
|
className: "min-w-0",
|
|
20
|
-
children:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}),
|
|
26
|
-
option.description && /*#__PURE__*/ jsx(Text, {
|
|
27
|
-
size: "xs",
|
|
28
|
-
color: "secondary",
|
|
29
|
-
truncate: true,
|
|
30
|
-
children: option.description
|
|
31
|
-
})
|
|
32
|
-
]
|
|
20
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
21
|
+
size: "sm",
|
|
22
|
+
truncate: true,
|
|
23
|
+
children: option.label
|
|
24
|
+
})
|
|
33
25
|
}),
|
|
34
26
|
multiSelect ? /*#__PURE__*/ jsx("div", {
|
|
35
27
|
className: "flex shrink-0 items-start justify-end py-2 ml-auto",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
2
|
import type { FieldMetadata, FilterOperator, UpsertCondition } from '../../types';
|
|
3
|
-
import type { BuildingBase } from './useAutocompleteState';
|
|
4
3
|
interface UseBlurCommitDeps {
|
|
5
4
|
selectedField: FieldMetadata | null;
|
|
6
5
|
selectedOperator: FilterOperator | null;
|
|
@@ -10,12 +9,6 @@ interface UseBlurCommitDeps {
|
|
|
10
9
|
handleCustomValueCommit: (text: string) => void;
|
|
11
10
|
upsertCondition: UpsertCondition;
|
|
12
11
|
resetState: () => void;
|
|
13
|
-
/** Which triplet is being built: 0 = base, 1 = paired second. */
|
|
14
|
-
buildingSide: 0 | 1;
|
|
15
|
-
setBuildingSide: (side: 0 | 1) => void;
|
|
16
|
-
/** Base triplet stashed while building a paired chip's second value. */
|
|
17
|
-
buildingBase: BuildingBase | null;
|
|
18
|
-
setBuildingBase: (base: BuildingBase | null) => void;
|
|
19
12
|
/** Indirection ref breaking the useMenuFlow ↔ useBlurCommit cycle. */
|
|
20
13
|
commitBuildingOnBlurRef: RefObject<() => boolean>;
|
|
21
14
|
/** Same indirection for force-commit (area-click → incomplete becomes error). */
|
|
@@ -27,7 +20,7 @@ interface UseBlurCommitDeps {
|
|
|
27
20
|
* editable. Re-entry-guarded: refs cleared synchronously so concurrent callers
|
|
28
21
|
* (multiple onOpenChange + blur in one tick) don't create duplicate chips.
|
|
29
22
|
*/
|
|
30
|
-
export declare const useBlurCommit: ({ selectedField, selectedOperator, inputText, editingChipId, effectiveInsertIndexRef, handleCustomValueCommit, upsertCondition, resetState,
|
|
23
|
+
export declare const useBlurCommit: ({ selectedField, selectedOperator, inputText, editingChipId, effectiveInsertIndexRef, handleCustomValueCommit, upsertCondition, resetState, commitBuildingOnBlurRef, commitBuildingForceRef, }: UseBlurCommitDeps) => {
|
|
31
24
|
commitBuildingOnBlur: () => boolean;
|
|
32
25
|
hasIncompleteBuilding: () => boolean;
|
|
33
26
|
};
|
|
@@ -1,34 +1,16 @@
|
|
|
1
1
|
import { useCallback, useLayoutEffect, useRef } from "react";
|
|
2
2
|
import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
|
|
3
3
|
import { isBuildingComplete, isNoValueOperator } from "../../lib/index.js";
|
|
4
|
-
const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChipId, effectiveInsertIndexRef, handleCustomValueCommit, upsertCondition, resetState,
|
|
4
|
+
const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChipId, effectiveInsertIndexRef, handleCustomValueCommit, upsertCondition, resetState, commitBuildingOnBlurRef, commitBuildingForceRef })=>{
|
|
5
5
|
const selectedFieldRef = useRef(selectedField);
|
|
6
6
|
const selectedOperatorRef = useRef(selectedOperator);
|
|
7
7
|
const inputTextRef = useRef(inputText);
|
|
8
|
-
const buildingSideRef = useRef(buildingSide);
|
|
9
|
-
const buildingBaseRef = useRef(buildingBase);
|
|
10
8
|
useLayoutEffect(()=>{
|
|
11
9
|
selectedFieldRef.current = selectedField;
|
|
12
10
|
selectedOperatorRef.current = selectedOperator;
|
|
13
11
|
inputTextRef.current = inputText;
|
|
14
|
-
buildingSideRef.current = buildingSide;
|
|
15
|
-
buildingBaseRef.current = buildingBase;
|
|
16
12
|
});
|
|
17
13
|
const committingRef = useRef(false);
|
|
18
|
-
const commitPairedBaseWithErroredValue = useCallback((base, field, operator)=>{
|
|
19
|
-
upsertCondition(base.field, base.operator, base.value, null, effectiveInsertIndexRef.current);
|
|
20
|
-
const pairError = operator ? SEGMENT_VARIANT.value : true;
|
|
21
|
-
upsertCondition(field, operator ?? void 0, null, void 0, void 0, pairError, void 0, 1);
|
|
22
|
-
setBuildingBase(null);
|
|
23
|
-
setBuildingSide(0);
|
|
24
|
-
resetState();
|
|
25
|
-
}, [
|
|
26
|
-
upsertCondition,
|
|
27
|
-
resetState,
|
|
28
|
-
effectiveInsertIndexRef,
|
|
29
|
-
setBuildingBase,
|
|
30
|
-
setBuildingSide
|
|
31
|
-
]);
|
|
32
14
|
const commitBuildingOnBlur = useCallback(()=>{
|
|
33
15
|
if (committingRef.current) return false;
|
|
34
16
|
const field = selectedFieldRef.current;
|
|
@@ -37,19 +19,6 @@ const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChip
|
|
|
37
19
|
if (!field) return false;
|
|
38
20
|
if (editingChipId) return false;
|
|
39
21
|
const hasTypedValue = !!operator && !isNoValueOperator(operator) && text.length > 0;
|
|
40
|
-
if (!hasTypedValue && 1 === buildingSideRef.current && buildingBaseRef.current) {
|
|
41
|
-
committingRef.current = true;
|
|
42
|
-
try {
|
|
43
|
-
const base = buildingBaseRef.current;
|
|
44
|
-
selectedFieldRef.current = null;
|
|
45
|
-
selectedOperatorRef.current = null;
|
|
46
|
-
inputTextRef.current = '';
|
|
47
|
-
commitPairedBaseWithErroredValue(base, field, operator);
|
|
48
|
-
return true;
|
|
49
|
-
} finally{
|
|
50
|
-
committingRef.current = false;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
22
|
if (!isBuildingComplete(field, operator, null) && !hasTypedValue) return false;
|
|
54
23
|
committingRef.current = true;
|
|
55
24
|
try {
|
|
@@ -71,8 +40,7 @@ const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChip
|
|
|
71
40
|
handleCustomValueCommit,
|
|
72
41
|
upsertCondition,
|
|
73
42
|
resetState,
|
|
74
|
-
effectiveInsertIndexRef
|
|
75
|
-
commitPairedBaseWithErroredValue
|
|
43
|
+
effectiveInsertIndexRef
|
|
76
44
|
]);
|
|
77
45
|
useLayoutEffect(()=>{
|
|
78
46
|
commitBuildingOnBlurRef.current = commitBuildingOnBlur;
|
|
@@ -100,10 +68,6 @@ const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChip
|
|
|
100
68
|
handleCustomValueCommit(text);
|
|
101
69
|
return true;
|
|
102
70
|
}
|
|
103
|
-
if (1 === buildingSideRef.current && buildingBaseRef.current) {
|
|
104
|
-
commitPairedBaseWithErroredValue(buildingBaseRef.current, field, operator);
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
71
|
if (isBuildingComplete(field, operator, null)) {
|
|
108
72
|
upsertCondition(field, operator, null, void 0, effectiveInsertIndexRef.current);
|
|
109
73
|
resetState();
|
|
@@ -121,8 +85,7 @@ const useBlurCommit = ({ selectedField, selectedOperator, inputText, editingChip
|
|
|
121
85
|
handleCustomValueCommit,
|
|
122
86
|
upsertCondition,
|
|
123
87
|
resetState,
|
|
124
|
-
effectiveInsertIndexRef
|
|
125
|
-
commitPairedBaseWithErroredValue
|
|
88
|
+
effectiveInsertIndexRef
|
|
126
89
|
]);
|
|
127
90
|
useLayoutEffect(()=>{
|
|
128
91
|
commitBuildingForceRef.current = commitBuildingForce;
|
package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
|
-
import { type ChipSegment } from '../../FilterInputField/FilterInputChip';
|
|
3
2
|
import type { Condition, FieldMetadata, FilterInputChipData, UpsertCondition } from '../../types';
|
|
4
3
|
interface UseFilterInputAutocompleteOptions {
|
|
5
4
|
fields: FieldMetadata[];
|
|
@@ -50,10 +49,10 @@ export declare const useFilterInputAutocomplete: ({ fields, conditions, chips, u
|
|
|
50
49
|
handleMenuDiscard: () => void;
|
|
51
50
|
/** Hard reset for paste/clipboard flows — scraps in-progress building. */
|
|
52
51
|
resetAutocompleteState: (continueBuilding?: boolean) => void;
|
|
53
|
-
handleChipClick: (chipId: string, segment: ChipSegment, anchorEl: HTMLElement) => void;
|
|
54
|
-
handlePairChipClick: (chipId: string, segment: ChipSegment, anchorEl: HTMLElement) => void;
|
|
55
|
-
handleBuildingChipClick: (segment: ChipSegment, anchorEl: HTMLElement) => void;
|
|
56
|
-
switchEditSegment: (targetSegment: ChipSegment) => boolean;
|
|
52
|
+
handleChipClick: (chipId: string, segment: import("../../FilterInputField").ChipSegment, anchorEl: HTMLElement) => void;
|
|
53
|
+
handlePairChipClick: (chipId: string, segment: import("../../FilterInputField").ChipSegment, anchorEl: HTMLElement) => void;
|
|
54
|
+
handleBuildingChipClick: (segment: import("../../FilterInputField").ChipSegment, anchorEl: HTMLElement) => void;
|
|
55
|
+
switchEditSegment: (targetSegment: import("../../FilterInputField").ChipSegment) => boolean;
|
|
57
56
|
removeEditingChip: () => void;
|
|
58
57
|
handleConnectorChange: (connectorId: string, value: "and" | "or") => void;
|
|
59
58
|
handleChipRemove: (chipId: string) => void;
|
package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
1
|
import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
|
|
3
2
|
import { useDateRange } from "../../FilterInputMenu/FilterInputDateValueMenu/hooks.js";
|
|
4
3
|
import { deriveAutocompleteValues } from "./lib/index.js";
|
|
@@ -12,7 +11,6 @@ import { useInputHandlers } from "./useInputHandlers.js";
|
|
|
12
11
|
import { useMenuFlow } from "./useMenuFlow/index.js";
|
|
13
12
|
import { useMenuPositioning } from "./useMenuPositioning.js";
|
|
14
13
|
import { useResetState } from "./useResetState.js";
|
|
15
|
-
import { useResumeBuilding } from "./useResumeBuilding.js";
|
|
16
14
|
import { useSegmentEditFlow } from "./useSegmentEditFlow.js";
|
|
17
15
|
const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition, removeCondition, removeConditionAtIndex, clearAll, setConnectorValue, containerRef, buildingChipRef, inputRef })=>{
|
|
18
16
|
const state = useAutocompleteState({
|
|
@@ -125,10 +123,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
125
123
|
handleCustomValueCommit,
|
|
126
124
|
upsertCondition,
|
|
127
125
|
resetState,
|
|
128
|
-
buildingSide,
|
|
129
|
-
setBuildingSide,
|
|
130
|
-
buildingBase,
|
|
131
|
-
setBuildingBase,
|
|
132
126
|
commitBuildingOnBlurRef,
|
|
133
127
|
commitBuildingForceRef
|
|
134
128
|
});
|
|
@@ -176,36 +170,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
176
170
|
setMenuState,
|
|
177
171
|
setMenuAnchor
|
|
178
172
|
});
|
|
179
|
-
const tryResumeBuilding = useResumeBuilding({
|
|
180
|
-
conditions,
|
|
181
|
-
fields,
|
|
182
|
-
removeConditionAtIndex,
|
|
183
|
-
setInsertIndex,
|
|
184
|
-
setBuildingBase,
|
|
185
|
-
setBuildingSide,
|
|
186
|
-
setSelectedField,
|
|
187
|
-
setSelectedOperator,
|
|
188
|
-
setBuildingMultiValue,
|
|
189
|
-
setInputText,
|
|
190
|
-
setMenuState,
|
|
191
|
-
resetMenuAnchor,
|
|
192
|
-
clearEditing: editing.clearEditing,
|
|
193
|
-
inputRef
|
|
194
|
-
});
|
|
195
|
-
const handleChipClick = useCallback((chipId, segment, anchorEl)=>{
|
|
196
|
-
if (tryResumeBuilding(chipId)) return;
|
|
197
|
-
editing.handleChipClick(chipId, segment, anchorEl);
|
|
198
|
-
}, [
|
|
199
|
-
tryResumeBuilding,
|
|
200
|
-
editing.handleChipClick
|
|
201
|
-
]);
|
|
202
|
-
const handlePairChipClick = useCallback((chipId, segment, anchorEl)=>{
|
|
203
|
-
if (tryResumeBuilding(chipId)) return;
|
|
204
|
-
editing.handlePairChipClick(chipId, segment, anchorEl);
|
|
205
|
-
}, [
|
|
206
|
-
tryResumeBuilding,
|
|
207
|
-
editing.handlePairChipClick
|
|
208
|
-
]);
|
|
209
173
|
const { isBuilding, buildingChipData, editingMultiValues, editingSingleValue, editingDateRange } = deriveAutocompleteValues({
|
|
210
174
|
editingChipId: editing.editingChipId,
|
|
211
175
|
selectedField,
|
|
@@ -240,8 +204,8 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
240
204
|
handleMenuClose,
|
|
241
205
|
handleMenuDiscard,
|
|
242
206
|
resetAutocompleteState: resetState,
|
|
243
|
-
handleChipClick,
|
|
244
|
-
handlePairChipClick,
|
|
207
|
+
handleChipClick: editing.handleChipClick,
|
|
208
|
+
handlePairChipClick: editing.handlePairChipClick,
|
|
245
209
|
handleBuildingChipClick,
|
|
246
210
|
switchEditSegment,
|
|
247
211
|
removeEditingChip,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SEGMENT_VARIANT } from "../../FilterInputField/FilterInputChip/index.js";
|
|
2
|
-
import { NO_VALUE_PLACEHOLDER, canBorrowCrossFieldLabel, findOptionByValue, findValueLabelInFields, getDateDisplayLabel, getInvalidValueIndices, getOperatorLabel,
|
|
2
|
+
import { NO_VALUE_PLACEHOLDER, canBorrowCrossFieldLabel, findOptionByValue, findValueLabelInFields, getDateDisplayLabel, getInvalidValueIndices, getOperatorLabel, isNoValueOperator } from "../../lib/index.js";
|
|
3
3
|
const INVALID_DATE = 'Invalid Date';
|
|
4
4
|
const DATE_RANGE_SEPARATOR = ' – ';
|
|
5
5
|
const MULTI_VALUE_SEPARATOR = ', ';
|
|
@@ -84,35 +84,23 @@ const buildMultiValueChip = (baseChip, condition, field, fields, chipError)=>{
|
|
|
84
84
|
};
|
|
85
85
|
};
|
|
86
86
|
const buildPairChip = (condition, field, fields)=>{
|
|
87
|
-
if (!field?.pairedField) return;
|
|
88
|
-
if (null != condition.operator && isNoValueOperator(condition.operator)) return;
|
|
87
|
+
if (!condition.pair || !field?.pairedField) return;
|
|
89
88
|
const pf = field.pairedField;
|
|
90
|
-
if (!condition.pair) {
|
|
91
|
-
const baseComplete = null != condition.operator && !isEmptyFilterValue(condition.value);
|
|
92
|
-
if (!baseComplete) return;
|
|
93
|
-
return {
|
|
94
|
-
attribute: pf.label || pf.name,
|
|
95
|
-
value: '',
|
|
96
|
-
error: SEGMENT_VARIANT.value
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
89
|
const { operator, value, error } = condition.pair;
|
|
100
90
|
const displayValue = operator && isNoValueOperator(operator) ? NO_VALUE_PLACEHOLDER : resolveValueLabel(value, pf, fields) ?? String(value ?? '');
|
|
101
|
-
const valueRequiredButMissing = !(operator && isNoValueOperator(operator)) && isEmptyFilterValue(value);
|
|
102
|
-
const pairError = error || (valueRequiredButMissing ? SEGMENT_VARIANT.value : void 0);
|
|
103
91
|
return {
|
|
104
92
|
attribute: pf.label || pf.name,
|
|
105
93
|
operator: operator ? getOperatorLabel(operator, pf.type || DEFAULT_FIELD_TYPE) : void 0,
|
|
106
94
|
value: displayValue,
|
|
107
|
-
...
|
|
108
|
-
error
|
|
95
|
+
...error && {
|
|
96
|
+
error
|
|
109
97
|
}
|
|
110
98
|
};
|
|
111
99
|
};
|
|
112
100
|
const makeConditionChipBase = (i, conditions, fields, error)=>{
|
|
113
101
|
const condition = conditions[i];
|
|
114
102
|
if (!condition) return makeEmptyChip(i, error);
|
|
115
|
-
const chipError = condition.error || (error ? true : void 0)
|
|
103
|
+
const chipError = condition.error || (error ? true : void 0);
|
|
116
104
|
const field = fields.find((f)=>f.name === condition.field);
|
|
117
105
|
const baseChip = buildBaseChip(i, condition, field);
|
|
118
106
|
if (condition.operator && isNoValueOperator(condition.operator)) return {
|
package/dist/components/FilterInput/hooks/useFilterInputExpression/useFilterInputExpression.js
CHANGED
|
@@ -155,11 +155,6 @@ const useFilterInputExpression = ({ fields, value, onChange, error, externalErro
|
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
157
|
const condition = buildCondition(field, operator, val, error, dateOrigin);
|
|
158
|
-
if (editingChipId) {
|
|
159
|
-
const idx = chipIdToConditionIndex(editingChipId);
|
|
160
|
-
const prevCondition = null !== idx ? prev.conditions[idx] : void 0;
|
|
161
|
-
if (prevCondition?.pair && prevCondition.field === condition.field) condition.pair = prevCondition.pair;
|
|
162
|
-
}
|
|
163
158
|
const newConditions = applyCondition(prev.conditions, condition, editingChipId, atIndex);
|
|
164
159
|
const newConnectors = addConnectorIfNeeded(prev.connectors, newConditions.length, editingChipId, atIndex, prev.conditions.length);
|
|
165
160
|
applyState({
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FilterInputChipData } from '../types';
|
|
2
2
|
/** Map a chip ID (e.g. "chip-2") back to condition index */
|
|
3
3
|
export declare const chipIdToConditionIndex: (chipId: string) => number | null;
|
|
4
|
-
/** A filter value is empty when null/undefined, '', or an empty array. */
|
|
5
|
-
export declare const isEmptyFilterValue: (value: Condition["value"] | undefined) => boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Error segment for an incomplete triplet, or `undefined` when complete:
|
|
8
|
-
* missing operator → whole triplet (`true`); value-bearing operator with an
|
|
9
|
-
* empty value → the value segment; no-value operator ("is set") → complete.
|
|
10
|
-
*/
|
|
11
|
-
export declare const incompleteTripletError: (operator: FilterOperator | null | undefined, value: Condition["value"] | undefined) => ChipErrorSegment | undefined;
|
|
12
4
|
/**
|
|
13
5
|
* Convert a condition-level insert index to a position in the chips array.
|
|
14
6
|
* When `afterConnector` is true, split AFTER the connector preceding the target chip.
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { SEGMENT_VARIANT } from "../FilterInputField/FilterInputChip/segmentVariant.js";
|
|
2
1
|
import { CHIP_ID_PATTERN } from "./constants.js";
|
|
3
|
-
import { isNoValueOperator } from "./operators.js";
|
|
4
2
|
const chipIdToConditionIndex = (chipId)=>{
|
|
5
3
|
const match = chipId.match(CHIP_ID_PATTERN);
|
|
6
4
|
return match ? Number(match[1]) : null;
|
|
7
5
|
};
|
|
8
|
-
const isEmptyFilterValue = (value)=>null == value || '' === value || Array.isArray(value) && 0 === value.length;
|
|
9
|
-
const incompleteTripletError = (operator, value)=>operator ? isNoValueOperator(operator) ? void 0 : isEmptyFilterValue(value) ? SEGMENT_VARIANT.value : void 0 : true;
|
|
10
6
|
const findChipSplitIndex = (chips, conditionInsertIndex, afterConnector = false)=>{
|
|
11
7
|
let conditionCount = 0;
|
|
12
8
|
for(let i = 0; i < chips.length; i++)if ('chip' === chips[i].variant) {
|
|
@@ -19,4 +15,4 @@ const findChipSplitIndex = (chips, conditionInsertIndex, afterConnector = false)
|
|
|
19
15
|
}
|
|
20
16
|
return chips.length;
|
|
21
17
|
};
|
|
22
|
-
export { chipIdToConditionIndex, findChipSplitIndex
|
|
18
|
+
export { chipIdToConditionIndex, findChipSplitIndex };
|
|
@@ -3,7 +3,7 @@ export { DATE_PRESETS, formatDateForChip, getDateDisplayLabel, isDatePreset, } f
|
|
|
3
3
|
export { applyAcceptChar } from './applyAcceptChar';
|
|
4
4
|
export { applyFieldValueTransforms } from './applyFieldValueTransforms';
|
|
5
5
|
export { applyKnownFieldHelpers, getKnownFieldSerializer } from './applyKnownFieldHelpers';
|
|
6
|
-
export { chipIdToConditionIndex, findChipSplitIndex
|
|
6
|
+
export { chipIdToConditionIndex, findChipSplitIndex } from './conditions';
|
|
7
7
|
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';
|
|
8
8
|
export { COUNTRY_OPTIONS } from './country';
|
|
9
9
|
export { type AnchorBounds, buildAnchoredRect, isMenuRelated, toAnchorBounds } from './dom';
|
|
@@ -2,7 +2,7 @@ import { DATE_PRESETS, formatDateForChip, getDateDisplayLabel, isDatePreset } fr
|
|
|
2
2
|
import { applyAcceptChar } from "./applyAcceptChar.js";
|
|
3
3
|
import { applyFieldValueTransforms } from "./applyFieldValueTransforms.js";
|
|
4
4
|
import { applyKnownFieldHelpers, getKnownFieldSerializer } from "./applyKnownFieldHelpers.js";
|
|
5
|
-
import { chipIdToConditionIndex, findChipSplitIndex
|
|
5
|
+
import { chipIdToConditionIndex, findChipSplitIndex } from "./conditions.js";
|
|
6
6
|
import { 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";
|
|
7
7
|
import { COUNTRY_OPTIONS } from "./country/index.js";
|
|
8
8
|
import { buildAnchoredRect, isMenuRelated, toAnchorBounds } from "./dom.js";
|
|
@@ -15,4 +15,4 @@ import { SEGMENT_TO_MENU } from "./segmentMenu.js";
|
|
|
15
15
|
import { serializeExpression } from "./serializeExpression.js";
|
|
16
16
|
import { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator } from "./statusCode/index.js";
|
|
17
17
|
import { canBorrowCrossFieldLabel, findMatchingFieldValue, getInvalidValueIndices, isValidFieldValue, validateValueForField } from "./validation.js";
|
|
18
|
-
export { CONNECTOR_ID_PATTERN, COUNTRY_OPTIONS, DATE_PRESETS, MENU_BASE_GUTTER, MENU_CHIP_GUTTER_OFFSET, NO_VALUE_OPERATORS, NO_VALUE_PLACEHOLDER, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, SEGMENT_TO_MENU, VARIANT_LABELS, applyAcceptChar, applyFieldValueTransforms, applyKnownFieldHelpers, buildAnchoredRect, canBorrowCrossFieldLabel, chipIdToConditionIndex, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, filterAndSort, findChipSplitIndex, findMatchingFieldValue, findOptionByValue, findValueLabelInFields, formatDateForChip, getCurrentValueTokenText, getDateDisplayLabel, getFieldOperators, getFieldValues, getInvalidValueIndices, getKnownFieldSerializer, getOperatorFromLabel, getOperatorLabel, getValueFilterText, hasFieldValues, hasStaticAllowlist,
|
|
18
|
+
export { CONNECTOR_ID_PATTERN, COUNTRY_OPTIONS, DATE_PRESETS, MENU_BASE_GUTTER, MENU_CHIP_GUTTER_OFFSET, NO_VALUE_OPERATORS, NO_VALUE_PLACEHOLDER, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, SEGMENT_TO_MENU, VARIANT_LABELS, applyAcceptChar, applyFieldValueTransforms, applyKnownFieldHelpers, buildAnchoredRect, canBorrowCrossFieldLabel, chipIdToConditionIndex, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, filterAndSort, findChipSplitIndex, findMatchingFieldValue, findOptionByValue, findValueLabelInFields, formatDateForChip, getCurrentValueTokenText, getDateDisplayLabel, getFieldOperators, getFieldValues, getInvalidValueIndices, getKnownFieldSerializer, getOperatorFromLabel, getOperatorLabel, getValueFilterText, hasFieldValues, hasStaticAllowlist, isBetweenOperator, isBuildingComplete, isDatePreset, isFilterParseError, isMenuRelated, isMultiSelectOperator, isNoValueOperator, isOperatorAllowedForField, isValidFieldValue, isValueShapeCompatible, nextBuildingMenu, parseExpression, serializeExpression, toAnchorBounds, validateValueForField };
|
|
@@ -59,14 +59,6 @@ export interface FieldValueOption {
|
|
|
59
59
|
color: BadgeColor;
|
|
60
60
|
text: string;
|
|
61
61
|
};
|
|
62
|
-
/**
|
|
63
|
-
* Optional secondary text rendered as a muted line beneath the bold `label`
|
|
64
|
-
* in the value dropdown (e.g. a backend path that explains or disambiguates
|
|
65
|
-
* the option). Display-only — never committed as a filter value. Because the
|
|
66
|
-
* bold `label` need not be unique, this line is what distinguishes rows that
|
|
67
|
-
* share a label (two `request-id` rows with different paths).
|
|
68
|
-
*/
|
|
69
|
-
description?: string;
|
|
70
62
|
}
|
|
71
63
|
/**
|
|
72
64
|
* Field Metadata Interface
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type FC, type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { Slider as ArkSlider } from '@ark-ui/react/slider';
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
/** Ark/Zag machine-config props forwarded to the headless `Slider.Root`. */
|
|
5
|
+
type SliderRootConfig = Pick<ArkSlider.RootProps, 'value' | 'defaultValue' | 'min' | 'max' | 'step' | 'disabled' | 'readOnly' | 'getAriaValueText' | 'name' | 'form' | 'minStepsBetweenThumbs' | 'thumbCollisionBehavior'>;
|
|
6
|
+
export interface SliderProps extends SliderRootConfig, TestableProps {
|
|
7
|
+
/** Error state → maps to Ark `invalid` (repaints the handle; the message is the Field's job). */
|
|
8
|
+
error?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
/** Fires live during drag with the current value array (`[n]` single, `[low, high]` range). */
|
|
12
|
+
onValueChange?: (value: number[]) => void;
|
|
13
|
+
/** Fires once on drag release with the committed value array. */
|
|
14
|
+
onValueChangeEnd?: (value: number[]) => void;
|
|
15
|
+
/** Ref to the Ark Slider root element. */
|
|
16
|
+
ref?: Ref<HTMLDivElement>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Slider — pick an approximate, bounded value (or range) by dragging a handle along
|
|
20
|
+
* a track. Built on `@ark-ui/react/slider`.
|
|
21
|
+
*
|
|
22
|
+
* Compose the parts: `SliderControl` (renders the track + range) holds one
|
|
23
|
+
* `SliderThumb` per thumb (the real `role="slider"` node — consumer `data-*` /
|
|
24
|
+
* analytics / `ref` land there) and an optional `SliderMarks`. `SliderInput` and
|
|
25
|
+
* `SliderValue` are optional readouts. Single vs range is driven by the length of
|
|
26
|
+
* `value` / `defaultValue` — render one `SliderThumb` per entry. Thumbs never cross
|
|
27
|
+
* (`thumbCollisionBehavior` defaults to `'none'`); set `minStepsBetweenThumbs` for a gap.
|
|
28
|
+
*
|
|
29
|
+
* It reads `Field` context like `Input`/`Textarea`, so wrapping it in `<Field>` wires
|
|
30
|
+
* label / invalid / disabled. When an exact figure matters, pair with `NumberInput`;
|
|
31
|
+
* for 2–7 fixed options use `SegmentedControl`. See `docs/slider-design-spec.md`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const Slider: FC<SliderProps>;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|