@wallarm-org/design-system 0.29.1-rc-feature-AS-882.2 → 0.29.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/Calendar/CalendarContent.js +1 -1
- package/dist/components/Calendar/CalendarGrid.js +6 -6
- package/dist/components/Calendar/CalendarGrids.js +1 -1
- package/dist/components/Calendar/CalendarHeader.js +3 -3
- package/dist/components/Calendar/CalendarInputHeader.js +3 -6
- package/dist/components/Calendar/CalendarKeyboardHints.js +21 -16
- package/dist/components/DateInput/internal/DateInputInternal.js +2 -1
- package/dist/components/DateRangeInput/DateRangeSegmentGroup.js +2 -1
- package/dist/components/FilterInput/FilterInputContext/types.d.ts +0 -4
- package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.d.ts +0 -2
- package/dist/components/FilterInput/FilterInputContext/useFilterInputContextValue.js +1 -5
- package/dist/components/FilterInput/FilterInputField/FilterInputChip/Segment.js +2 -8
- package/dist/components/FilterInput/FilterInputField/FilterInputConnectorChip/FilterInputConnectorChip.js +0 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputDateValueMenu/FilterInputDateValueMenu.js +0 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FieldMenuSections.d.ts +0 -3
- package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FieldMenuSections.js +3 -7
- package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FilterInputFieldMenu.js +4 -9
- package/dist/components/FilterInput/FilterInputMenu/FilterInputOperatorMenu.js +1 -3
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.js +1 -3
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuItem.d.ts +0 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/ValueMenuItem.js +1 -2
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuState.d.ts +0 -1
- package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuState.js +1 -2
- package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.d.ts +0 -1
- package/dist/components/FilterInput/FilterInputMenu/hooks/useKeyboardNav.js +7 -9
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts +0 -2
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js +3 -15
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFocusManagement.d.ts +2 -7
- package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFocusManagement.js +4 -15
- package/dist/components/FilterInput/lib/dom.d.ts +1 -9
- package/dist/components/FilterInput/lib/dom.js +1 -1
- package/dist/components/InputGroup/InputGroup.js +1 -1
- package/dist/components/TemporalCore/TemporalClear.js +8 -7
- package/dist/components/TemporalCore/TemporalSegment.js +18 -12
- package/dist/metadata/components.json +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ const CalendarContent = /*#__PURE__*/ forwardRef(({ children, className }, ref)=
|
|
|
6
6
|
children: /*#__PURE__*/ jsx(DatePicker.Positioner, {
|
|
7
7
|
children: /*#__PURE__*/ jsx(DatePicker.Content, {
|
|
8
8
|
ref: ref,
|
|
9
|
-
className: cn('flex bg-bg-surface-
|
|
9
|
+
className: cn('flex bg-bg-surface-2 rounded-12 shadow-md', 'border border-border-primary-light', 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95', 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95', className),
|
|
10
10
|
children: children
|
|
11
11
|
})
|
|
12
12
|
})
|
|
@@ -16,7 +16,7 @@ const CalendarGrid = ({ showArrows = true, showJumpToToday = false, monthOffset
|
|
|
16
16
|
const targetMonth = visibleRange.start.month;
|
|
17
17
|
return /*#__PURE__*/ jsxs(DatePicker.View, {
|
|
18
18
|
view: "day",
|
|
19
|
-
className: "flex flex-col
|
|
19
|
+
className: "flex flex-col",
|
|
20
20
|
children: [
|
|
21
21
|
/*#__PURE__*/ jsx(CalendarHeader, {
|
|
22
22
|
showArrows: showArrows,
|
|
@@ -59,7 +59,7 @@ const CalendarGrid = ({ showArrows = true, showJumpToToday = false, monthOffset
|
|
|
59
59
|
children: /*#__PURE__*/ jsx("div", {
|
|
60
60
|
className: cn('flex items-center justify-center relative', 'w-40 h-40 p-2'),
|
|
61
61
|
children: /*#__PURE__*/ jsx("span", {
|
|
62
|
-
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'text-text-secondary', (cellState.inRange || cellState.inHoveredRange) && 'bg-states-primary-pressed', cellState.selected && 'bg-bg-fill-brand text-text-primary-alt'),
|
|
62
|
+
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'text-text-secondary', (cellState.inRange || cellState.inHoveredRange) && 'bg-states-primary-pressed', cellState.selected && 'bg-bg-fill-brand text-text-primary-alt font-medium'),
|
|
63
63
|
children: day.day
|
|
64
64
|
})
|
|
65
65
|
})
|
|
@@ -77,11 +77,11 @@ const CalendarGrid = ({ showArrows = true, showJumpToToday = false, monthOffset
|
|
|
77
77
|
className: cn('flex items-center justify-center relative', 'w-40 h-40 p-2'),
|
|
78
78
|
children: [
|
|
79
79
|
/*#__PURE__*/ jsx("span", {
|
|
80
|
-
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'text-text-primary', (cellState.inRange || cellState.inHoveredRange) && 'bg-states-primary-pressed', cellState.selected && 'bg-bg-fill-brand text-text-primary-alt'),
|
|
80
|
+
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'text-text-primary', (cellState.inRange || cellState.inHoveredRange) && 'bg-states-primary-pressed', cellState.selected && 'bg-bg-fill-brand text-text-primary-alt font-medium'),
|
|
81
81
|
children: day.day
|
|
82
82
|
}),
|
|
83
83
|
isToday && /*#__PURE__*/ jsx("span", {
|
|
84
|
-
className: cn('absolute bottom-
|
|
84
|
+
className: cn('absolute bottom-7 left-1/2 -translate-x-1/2 w-4 h-4 rounded-full', 'bg-bg-fill-brand', cellState.selected && 'bg-text-primary-alt')
|
|
85
85
|
})
|
|
86
86
|
]
|
|
87
87
|
})
|
|
@@ -94,11 +94,11 @@ const CalendarGrid = ({ showArrows = true, showJumpToToday = false, monthOffset
|
|
|
94
94
|
className: cn('flex items-center justify-center relative', 'w-40 h-40 p-2', 'cursor-pointer select-none', 'outline-none'),
|
|
95
95
|
children: [
|
|
96
96
|
/*#__PURE__*/ jsx("span", {
|
|
97
|
-
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'transition-colors', '[[data-selected]_&]:bg-bg-fill-brand [[data-selected]_&]:text-text-primary-alt', '[[data-in-range]_&]:bg-states-primary-pressed', '[[data-outside-range]_&]:text-text-secondary', '[[data-disabled]_&]:cursor-not-allowed [[data-disabled]_&]:line-through [[data-disabled]_&]:text-text-secondary', 'not-[[data-selected]_&]:not-[[data-disabled]_&]:hover:bg-states-primary-hover', 'not-[[data-selected]_&]:not-[[data-disabled]_&]:active:bg-states-primary-pressed', '[:focus-visible_&]:ring-3 [:focus-visible_&]:ring-focus-primary', '[[data-selected]:focus-visible_&]:ring-focus-brand'),
|
|
97
|
+
className: cn('flex items-center justify-center', 'w-36 h-36 rounded-8', 'font-mono text-sm leading-sm', 'transition-colors', '[[data-selected]_&]:bg-bg-fill-brand [[data-selected]_&]:text-text-primary-alt [[data-selected]_&]:font-medium', '[[data-in-range]_&]:bg-states-primary-pressed', '[[data-outside-range]_&]:text-text-secondary', '[[data-disabled]_&]:cursor-not-allowed [[data-disabled]_&]:line-through [[data-disabled]_&]:text-text-secondary', 'not-[[data-selected]_&]:not-[[data-disabled]_&]:hover:bg-states-primary-hover', 'not-[[data-selected]_&]:not-[[data-disabled]_&]:active:bg-states-primary-pressed', '[:focus-visible_&]:ring-3 [:focus-visible_&]:ring-focus-primary', '[[data-selected]:focus-visible_&]:ring-focus-brand'),
|
|
98
98
|
children: day.day
|
|
99
99
|
}),
|
|
100
100
|
isToday && /*#__PURE__*/ jsx("span", {
|
|
101
|
-
className: cn('absolute bottom-
|
|
101
|
+
className: cn('absolute bottom-7 left-1/2 -translate-x-1/2 w-4 h-4 rounded-full', 'bg-bg-fill-brand', '[[data-selected]_&]:bg-text-primary-alt')
|
|
102
102
|
})
|
|
103
103
|
]
|
|
104
104
|
})
|
|
@@ -7,7 +7,7 @@ const CalendarGrids = /*#__PURE__*/ forwardRef(({ className }, ref)=>{
|
|
|
7
7
|
const { isRange } = useCalendarContext();
|
|
8
8
|
return /*#__PURE__*/ jsxs("div", {
|
|
9
9
|
ref: ref,
|
|
10
|
-
className: cn('flex px-12 pb-
|
|
10
|
+
className: cn('flex px-12 pb-8 first:pt-12', isRange && 'gap-12', className),
|
|
11
11
|
children: [
|
|
12
12
|
/*#__PURE__*/ jsx(CalendarGrid, {
|
|
13
13
|
showArrows: !isRange,
|
|
@@ -63,7 +63,7 @@ const CalendarHeader = ({ showArrows = true, showJumpToToday = false, visibleRan
|
|
|
63
63
|
api.setFocusedValue(todayDate);
|
|
64
64
|
},
|
|
65
65
|
children: /*#__PURE__*/ jsx(JumpToTodayIcon, {
|
|
66
|
-
size: "
|
|
66
|
+
size: "md"
|
|
67
67
|
})
|
|
68
68
|
})
|
|
69
69
|
}),
|
|
@@ -94,7 +94,7 @@ const CalendarHeader = ({ showArrows = true, showJumpToToday = false, visibleRan
|
|
|
94
94
|
size: "small",
|
|
95
95
|
"aria-label": "Previous month",
|
|
96
96
|
children: /*#__PURE__*/ jsx(ArrowLeft, {
|
|
97
|
-
size: "
|
|
97
|
+
size: "md"
|
|
98
98
|
})
|
|
99
99
|
})
|
|
100
100
|
})
|
|
@@ -116,7 +116,7 @@ const CalendarHeader = ({ showArrows = true, showJumpToToday = false, visibleRan
|
|
|
116
116
|
size: "small",
|
|
117
117
|
"aria-label": "Next month",
|
|
118
118
|
children: /*#__PURE__*/ jsx(ArrowRight, {
|
|
119
|
-
size: "
|
|
119
|
+
size: "md"
|
|
120
120
|
})
|
|
121
121
|
})
|
|
122
122
|
})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback } from "react";
|
|
3
3
|
import { DatePicker } from "@ark-ui/react";
|
|
4
|
-
import { ArrowRight } from "../../icons/index.js";
|
|
5
4
|
import { cn } from "../../utils/cn.js";
|
|
6
5
|
import { DateInput } from "../DateInput/index.js";
|
|
7
6
|
import { useCalendarContext } from "./CalendarContext.js";
|
|
@@ -82,12 +81,10 @@ const RangeDateInputInner = ({ api, readonly })=>{
|
|
|
82
81
|
readOnly: readonly,
|
|
83
82
|
granularity: "day"
|
|
84
83
|
}),
|
|
85
|
-
/*#__PURE__*/ jsx("
|
|
86
|
-
className: "flex items-center justify-center shrink-0 basis-20",
|
|
84
|
+
/*#__PURE__*/ jsx("span", {
|
|
85
|
+
className: "flex items-center justify-center shrink-0 basis-20 font-sans text-sm leading-sm text-text-secondary",
|
|
87
86
|
"aria-hidden": "true",
|
|
88
|
-
children:
|
|
89
|
-
size: "md"
|
|
90
|
-
})
|
|
87
|
+
children: "→"
|
|
91
88
|
}),
|
|
92
89
|
/*#__PURE__*/ jsx(DateInput, {
|
|
93
90
|
value: endValue,
|
|
@@ -9,21 +9,26 @@ const CalendarKeyboardHints = /*#__PURE__*/ forwardRef(({ className }, ref)=>/*#
|
|
|
9
9
|
/*#__PURE__*/ jsxs("div", {
|
|
10
10
|
className: "flex items-center gap-4",
|
|
11
11
|
children: [
|
|
12
|
-
/*#__PURE__*/
|
|
13
|
-
|
|
14
|
-
children:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
/*#__PURE__*/ jsxs("div", {
|
|
13
|
+
className: "flex items-center gap-2",
|
|
14
|
+
children: [
|
|
15
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
16
|
+
size: "small",
|
|
17
|
+
children: "←"
|
|
18
|
+
}),
|
|
19
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
20
|
+
size: "small",
|
|
21
|
+
children: "↑"
|
|
22
|
+
}),
|
|
23
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
24
|
+
size: "small",
|
|
25
|
+
children: "↓"
|
|
26
|
+
}),
|
|
27
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
28
|
+
size: "small",
|
|
29
|
+
children: "→"
|
|
30
|
+
})
|
|
31
|
+
]
|
|
27
32
|
}),
|
|
28
33
|
/*#__PURE__*/ jsx("span", {
|
|
29
34
|
className: "font-sans font-medium text-xs text-text-secondary",
|
|
@@ -49,7 +54,7 @@ const CalendarKeyboardHints = /*#__PURE__*/ forwardRef(({ className }, ref)=>/*#
|
|
|
49
54
|
children: [
|
|
50
55
|
/*#__PURE__*/ jsx(Kbd, {
|
|
51
56
|
size: "small",
|
|
52
|
-
children: "
|
|
57
|
+
children: "ESC"
|
|
53
58
|
}),
|
|
54
59
|
/*#__PURE__*/ jsx("span", {
|
|
55
60
|
className: "font-sans font-medium text-xs text-text-secondary",
|
|
@@ -71,9 +71,10 @@ const DateInputInternal = ({ state, icon: IconComponent, error, disabled, readOn
|
|
|
71
71
|
...props,
|
|
72
72
|
ref: ref,
|
|
73
73
|
"data-slot": "input",
|
|
74
|
-
className: cn('h-full', showPlaceholder && 'opacity-0'),
|
|
74
|
+
className: cn('h-full', showPlaceholder && 'opacity-0', readOnly && 'cursor-not-allowed'),
|
|
75
75
|
"aria-invalid": error || void 0,
|
|
76
76
|
"aria-disabled": disabled || void 0,
|
|
77
|
+
"data-readonly": readOnly || void 0,
|
|
77
78
|
state: state,
|
|
78
79
|
disabled: disabled,
|
|
79
80
|
readOnly: readOnly,
|
|
@@ -73,9 +73,10 @@ const DateRangeSegmentGroup = ({ type, onHasPartialValueChange, ref, ...props })
|
|
|
73
73
|
...fieldProps,
|
|
74
74
|
ref: composeRefs(internalRef, ref),
|
|
75
75
|
"data-slot": "input",
|
|
76
|
-
className: cn('h-full'),
|
|
76
|
+
className: cn('h-full', readOnly && 'cursor-not-allowed'),
|
|
77
77
|
"aria-disabled": disabled || void 0,
|
|
78
78
|
"aria-invalid": error || void 0,
|
|
79
|
+
"data-readonly": readOnly || void 0,
|
|
79
80
|
"data-field-type": type,
|
|
80
81
|
state: fieldState,
|
|
81
82
|
disabled: disabled,
|
|
@@ -39,8 +39,4 @@ export interface FilterInputContextValue {
|
|
|
39
39
|
closeAutocompleteMenu: () => void;
|
|
40
40
|
/** Register/unregister a chip DOM element for selection tracking */
|
|
41
41
|
registerChipRef: (id: string, el: HTMLElement | null) => void;
|
|
42
|
-
/** Direct ref to the attribute segment <input> — attached by Segment when editing. */
|
|
43
|
-
segmentAttributeInputRef: RefObject<HTMLInputElement | null>;
|
|
44
|
-
/** Direct ref to the value segment <input> — attached by Segment when editing. */
|
|
45
|
-
segmentValueInputRef: RefObject<HTMLInputElement | null>;
|
|
46
42
|
}
|
|
@@ -25,8 +25,6 @@ interface AutocompleteForContext {
|
|
|
25
25
|
handleCustomAttributeCommit: (customText: string) => void;
|
|
26
26
|
menuRef: RefObject<HTMLDivElement | null>;
|
|
27
27
|
closeAutocompleteMenu: () => void;
|
|
28
|
-
segmentAttributeInputRef: RefObject<HTMLInputElement | null>;
|
|
29
|
-
segmentValueInputRef: RefObject<HTMLInputElement | null>;
|
|
30
28
|
}
|
|
31
29
|
interface UseFilterInputContextValueOptions {
|
|
32
30
|
chips: FilterInputChipData[];
|
|
@@ -28,9 +28,7 @@ const useFilterInputContextValue = ({ chips, autocomplete, buildingChipRef, inpu
|
|
|
28
28
|
onCustomAttributeCommit: autocomplete.handleCustomAttributeCommit,
|
|
29
29
|
menuRef: autocomplete.menuRef,
|
|
30
30
|
closeAutocompleteMenu: autocomplete.closeAutocompleteMenu,
|
|
31
|
-
registerChipRef
|
|
32
|
-
segmentAttributeInputRef: autocomplete.segmentAttributeInputRef,
|
|
33
|
-
segmentValueInputRef: autocomplete.segmentValueInputRef
|
|
31
|
+
registerChipRef
|
|
34
32
|
}), [
|
|
35
33
|
chips,
|
|
36
34
|
autocomplete.buildingChipData,
|
|
@@ -55,8 +53,6 @@ const useFilterInputContextValue = ({ chips, autocomplete, buildingChipRef, inpu
|
|
|
55
53
|
autocomplete.handleCustomAttributeCommit,
|
|
56
54
|
autocomplete.menuRef,
|
|
57
55
|
autocomplete.closeAutocompleteMenu,
|
|
58
|
-
autocomplete.segmentAttributeInputRef,
|
|
59
|
-
autocomplete.segmentValueInputRef,
|
|
60
56
|
registerChipRef,
|
|
61
57
|
buildingChipRef,
|
|
62
58
|
inputRef,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
3
|
import { cn } from "../../../../utils/cn.js";
|
|
4
|
-
import { FilterInputContext } from "../../FilterInputContext/FilterInputContext.js";
|
|
5
4
|
import { segmentContainer, segmentTextVariants } from "./classes.js";
|
|
6
5
|
import { CHAR_WIDTH_PX } from "./constants.js";
|
|
7
6
|
import { MultiValueSegment } from "./MultiValueSegment.js";
|
|
@@ -10,8 +9,6 @@ const Segment = ({ variant, children, className, error, editing, editText, onEdi
|
|
|
10
9
|
const textRef = useRef(null);
|
|
11
10
|
const inputRef = useRef(null);
|
|
12
11
|
const sizerRef = useRef(null);
|
|
13
|
-
const filterInputContext = useContext(FilterInputContext);
|
|
14
|
-
const segmentInputRef = 'attribute' === variant ? filterInputContext?.segmentAttributeInputRef : 'value' === variant ? filterInputContext?.segmentValueInputRef : null;
|
|
15
12
|
const lastTextWidthRef = useRef(0);
|
|
16
13
|
useEffect(()=>{
|
|
17
14
|
if (editing) return;
|
|
@@ -62,10 +59,7 @@ const Segment = ({ variant, children, className, error, editing, editText, onEdi
|
|
|
62
59
|
children: editing ? /*#__PURE__*/ jsxs(Fragment, {
|
|
63
60
|
children: [
|
|
64
61
|
/*#__PURE__*/ jsx("input", {
|
|
65
|
-
ref:
|
|
66
|
-
inputRef.current = node;
|
|
67
|
-
if (segmentInputRef) segmentInputRef.current = node;
|
|
68
|
-
},
|
|
62
|
+
ref: inputRef,
|
|
69
63
|
size: 1,
|
|
70
64
|
value: editText ?? '',
|
|
71
65
|
onChange: (e)=>onEditChange?.(e.target.value),
|
|
@@ -56,7 +56,6 @@ const FilterInputConnectorChip = ({ chipId, variant, onChange, className })=>{
|
|
|
56
56
|
}),
|
|
57
57
|
/*#__PURE__*/ jsxs(DropdownMenuContent, {
|
|
58
58
|
className: "w-auto min-w-64",
|
|
59
|
-
"data-filter-input-menu": "true",
|
|
60
59
|
children: [
|
|
61
60
|
/*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
62
61
|
value: "and",
|
|
@@ -51,7 +51,6 @@ const FilterInputDateValueMenu = ({ open, onSelect, onRangeSelect, onOpenChange,
|
|
|
51
51
|
children: /*#__PURE__*/ jsx(DropdownMenuContent, {
|
|
52
52
|
ref: menuRef,
|
|
53
53
|
className: cn('w-fit', className),
|
|
54
|
-
"data-filter-input-menu": "true",
|
|
55
54
|
onKeyDown: (e)=>{
|
|
56
55
|
if ('Escape' === e.key) {
|
|
57
56
|
e.preventDefault();
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FieldMenuSections.d.ts
CHANGED
|
@@ -4,19 +4,16 @@ interface RecentSectionProps {
|
|
|
4
4
|
conditions: Condition[];
|
|
5
5
|
fields: FieldMetadata[];
|
|
6
6
|
onSelect: (field: FieldMetadata) => void;
|
|
7
|
-
registerItem: (id: string) => (el: HTMLElement | null) => void;
|
|
8
7
|
}
|
|
9
8
|
export declare const RecentSection: FC<RecentSectionProps>;
|
|
10
9
|
interface SuggestionsSectionProps {
|
|
11
10
|
fields: FieldMetadata[];
|
|
12
11
|
onSelect: (field: FieldMetadata) => void;
|
|
13
|
-
registerItem: (id: string) => (el: HTMLElement | null) => void;
|
|
14
12
|
}
|
|
15
13
|
export declare const SuggestionsSection: FC<SuggestionsSectionProps>;
|
|
16
14
|
interface OperatorsSectionProps {
|
|
17
15
|
onSelectAnd?: () => void;
|
|
18
16
|
onSelectOr?: () => void;
|
|
19
|
-
registerItem: (id: string) => (el: HTMLElement | null) => void;
|
|
20
17
|
}
|
|
21
18
|
export declare const OperatorsSection: FC<OperatorsSectionProps>;
|
|
22
19
|
export {};
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FieldMenuSections.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { CirclePlus } from "../../../../icons/CirclePlus.js";
|
|
3
3
|
import { CircleSlash } from "../../../../icons/CircleSlash.js";
|
|
4
4
|
import { DropdownMenuGroup, DropdownMenuItem, DropdownMenuItemIcon, DropdownMenuItemText, DropdownMenuLabel, DropdownMenuSeparator } from "../../../DropdownMenu/index.js";
|
|
5
|
-
const RecentSection = ({ conditions, fields, onSelect
|
|
5
|
+
const RecentSection = ({ conditions, fields, onSelect })=>/*#__PURE__*/ jsxs(Fragment, {
|
|
6
6
|
children: [
|
|
7
7
|
/*#__PURE__*/ jsx(DropdownMenuLabel, {
|
|
8
8
|
children: "Recent"
|
|
@@ -15,7 +15,6 @@ const RecentSection = ({ conditions, fields, onSelect, registerItem })=>/*#__PUR
|
|
|
15
15
|
const value = String(condition.value);
|
|
16
16
|
return /*#__PURE__*/ jsx(DropdownMenuItem, {
|
|
17
17
|
value: `recent-${index}`,
|
|
18
|
-
ref: registerItem(`recent-${index}`),
|
|
19
18
|
onSelect: ()=>{
|
|
20
19
|
if (fieldMeta) onSelect(fieldMeta);
|
|
21
20
|
},
|
|
@@ -43,7 +42,7 @@ const RecentSection = ({ conditions, fields, onSelect, registerItem })=>/*#__PUR
|
|
|
43
42
|
]
|
|
44
43
|
});
|
|
45
44
|
RecentSection.displayName = 'RecentSection';
|
|
46
|
-
const SuggestionsSection = ({ fields, onSelect
|
|
45
|
+
const SuggestionsSection = ({ fields, onSelect })=>/*#__PURE__*/ jsxs(Fragment, {
|
|
47
46
|
children: [
|
|
48
47
|
/*#__PURE__*/ jsx(DropdownMenuLabel, {
|
|
49
48
|
children: "Suggestions"
|
|
@@ -51,7 +50,6 @@ const SuggestionsSection = ({ fields, onSelect, registerItem })=>/*#__PURE__*/ j
|
|
|
51
50
|
/*#__PURE__*/ jsx(DropdownMenuGroup, {
|
|
52
51
|
children: fields.map((field, index)=>/*#__PURE__*/ jsx(DropdownMenuItem, {
|
|
53
52
|
value: `suggested-${index}`,
|
|
54
|
-
ref: registerItem(`suggested-${index}`),
|
|
55
53
|
onSelect: ()=>onSelect(field),
|
|
56
54
|
children: /*#__PURE__*/ jsxs("span", {
|
|
57
55
|
className: "flex gap-2 items-center text-sm",
|
|
@@ -76,12 +74,11 @@ const SuggestionsSection = ({ fields, onSelect, registerItem })=>/*#__PURE__*/ j
|
|
|
76
74
|
]
|
|
77
75
|
});
|
|
78
76
|
SuggestionsSection.displayName = 'SuggestionsSection';
|
|
79
|
-
const OperatorsSection = ({ onSelectAnd, onSelectOr
|
|
77
|
+
const OperatorsSection = ({ onSelectAnd, onSelectOr })=>/*#__PURE__*/ jsxs(Fragment, {
|
|
80
78
|
children: [
|
|
81
79
|
/*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
|
|
82
80
|
onSelectAnd && /*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
83
81
|
value: "and",
|
|
84
|
-
ref: registerItem('and'),
|
|
85
82
|
onSelect: ()=>onSelectAnd(),
|
|
86
83
|
children: [
|
|
87
84
|
/*#__PURE__*/ jsx(DropdownMenuItemIcon, {
|
|
@@ -94,7 +91,6 @@ const OperatorsSection = ({ onSelectAnd, onSelectOr, registerItem })=>/*#__PURE_
|
|
|
94
91
|
}),
|
|
95
92
|
onSelectOr && /*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
96
93
|
value: "or",
|
|
97
|
-
ref: registerItem('or'),
|
|
98
94
|
onSelect: ()=>onSelectOr(),
|
|
99
95
|
children: [
|
|
100
96
|
/*#__PURE__*/ jsx(DropdownMenuItemIcon, {
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputFieldMenu/FilterInputFieldMenu.js
CHANGED
|
@@ -87,7 +87,7 @@ const FilterInputFieldMenu = ({ fields, filterText = '', onSelect, open = false,
|
|
|
87
87
|
} else if ('and' === data.type) onSelectAnd?.();
|
|
88
88
|
else if ('or' === data.type) onSelectOr?.();
|
|
89
89
|
};
|
|
90
|
-
const { highlightedValue, onHighlightChange
|
|
90
|
+
const { highlightedValue, onHighlightChange } = useKeyboardNav({
|
|
91
91
|
items: flatItems,
|
|
92
92
|
open,
|
|
93
93
|
onSelect: handleItemSelect,
|
|
@@ -109,23 +109,19 @@ const FilterInputFieldMenu = ({ fields, filterText = '', onSelect, open = false,
|
|
|
109
109
|
ref: menuRef,
|
|
110
110
|
className: cn('w-[300px] max-h-[430px]', className),
|
|
111
111
|
"data-slot": "filter-input-field-menu",
|
|
112
|
-
"data-filter-input-menu": "true",
|
|
113
112
|
children: [
|
|
114
113
|
!filterText && showRecent && /*#__PURE__*/ jsx(RecentSection, {
|
|
115
114
|
conditions: limitedRecentConditions,
|
|
116
115
|
fields: fields,
|
|
117
|
-
onSelect: onSelect
|
|
118
|
-
registerItem: registerItem
|
|
116
|
+
onSelect: onSelect
|
|
119
117
|
}),
|
|
120
118
|
!filterText && showSuggestions && !showRecent && /*#__PURE__*/ jsx(SuggestionsSection, {
|
|
121
119
|
fields: suggestedFields,
|
|
122
|
-
onSelect: onSelect
|
|
123
|
-
registerItem: registerItem
|
|
120
|
+
onSelect: onSelect
|
|
124
121
|
}),
|
|
125
122
|
filteredFields.length > 0 ? /*#__PURE__*/ jsx(DropdownMenuGroup, {
|
|
126
123
|
children: filteredFields.map((field)=>/*#__PURE__*/ jsx(DropdownMenuItem, {
|
|
127
124
|
value: `field-${field.name}`,
|
|
128
|
-
ref: registerItem(`field-${field.name}`),
|
|
129
125
|
onSelect: ()=>onSelect(field),
|
|
130
126
|
children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
|
|
131
127
|
children: field.label
|
|
@@ -134,8 +130,7 @@ const FilterInputFieldMenu = ({ fields, filterText = '', onSelect, open = false,
|
|
|
134
130
|
}) : /*#__PURE__*/ jsx(MenuEmptyState, {}),
|
|
135
131
|
!filterText && (onSelectAnd || onSelectOr) && /*#__PURE__*/ jsx(OperatorsSection, {
|
|
136
132
|
onSelectAnd: onSelectAnd,
|
|
137
|
-
onSelectOr: onSelectOr
|
|
138
|
-
registerItem: registerItem
|
|
133
|
+
onSelectOr: onSelectOr
|
|
139
134
|
}),
|
|
140
135
|
/*#__PURE__*/ jsxs(DropdownMenuFooter, {
|
|
141
136
|
children: [
|
|
@@ -36,7 +36,7 @@ const FilterInputOperatorMenu = ({ fieldType, operators, onSelect, open = false,
|
|
|
36
36
|
filteredGroups,
|
|
37
37
|
fieldType
|
|
38
38
|
]);
|
|
39
|
-
const { highlightedValue, onHighlightChange
|
|
39
|
+
const { highlightedValue, onHighlightChange } = useKeyboardNav({
|
|
40
40
|
items: flatItems,
|
|
41
41
|
open,
|
|
42
42
|
onSelect: (item)=>onSelect(item.value),
|
|
@@ -56,14 +56,12 @@ const FilterInputOperatorMenu = ({ fieldType, operators, onSelect, open = false,
|
|
|
56
56
|
children: /*#__PURE__*/ jsxs(DropdownMenuContent, {
|
|
57
57
|
ref: menuRef,
|
|
58
58
|
className: cn('w-256 max-h-[430px]', className),
|
|
59
|
-
"data-filter-input-menu": "true",
|
|
60
59
|
children: [
|
|
61
60
|
filteredGroups.length > 0 ? filteredGroups.map((group, groupIdx)=>/*#__PURE__*/ jsxs(Fragment, {
|
|
62
61
|
children: [
|
|
63
62
|
/*#__PURE__*/ jsx(DropdownMenuGroup, {
|
|
64
63
|
children: group.map((operator)=>/*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
65
64
|
value: operator,
|
|
66
|
-
ref: registerItem(operator),
|
|
67
65
|
onSelect: ()=>onSelect(operator),
|
|
68
66
|
children: [
|
|
69
67
|
/*#__PURE__*/ jsx(DropdownMenuItemText, {
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/FilterInputValueMenu.js
CHANGED
|
@@ -16,7 +16,7 @@ const FilterInputValueMenu = ({ values, onSelect, onCommit, open = false, onOpen
|
|
|
16
16
|
values,
|
|
17
17
|
filterText
|
|
18
18
|
]);
|
|
19
|
-
const { selectedValues, checkedValues, highlightedValue, onHighlightChange, pendingIds,
|
|
19
|
+
const { selectedValues, checkedValues, highlightedValue, onHighlightChange, pendingIds, handleItemSelect } = useValueMenuState({
|
|
20
20
|
values: filteredValues,
|
|
21
21
|
open,
|
|
22
22
|
multiSelect,
|
|
@@ -54,7 +54,6 @@ const FilterInputValueMenu = ({ values, onSelect, onCommit, open = false, onOpen
|
|
|
54
54
|
ref: menuRef,
|
|
55
55
|
className: cn(widthClass, 'max-h-[430px]', className),
|
|
56
56
|
style: widthStyle,
|
|
57
|
-
"data-filter-input-menu": "true",
|
|
58
57
|
children: [
|
|
59
58
|
displayValues.length > 0 ? /*#__PURE__*/ jsx(DropdownMenuGroup, {
|
|
60
59
|
children: displayValues.map((option)=>/*#__PURE__*/ jsx(ValueMenuItem, {
|
|
@@ -62,7 +61,6 @@ const FilterInputValueMenu = ({ values, onSelect, onCommit, open = false, onOpen
|
|
|
62
61
|
isChecked: selectedValues.includes(option.value),
|
|
63
62
|
isPending: pendingIds.has(String(option.value)),
|
|
64
63
|
multiSelect: multiSelect,
|
|
65
|
-
registerItem: registerItem,
|
|
66
64
|
onSelect: ()=>handleItemSelect({
|
|
67
65
|
id: String(option.value),
|
|
68
66
|
label: option.label,
|
|
@@ -4,9 +4,8 @@ import { Badge } from "../../../Badge/index.js";
|
|
|
4
4
|
import { Checkmark } from "../../../Checkmark/index.js";
|
|
5
5
|
import { DropdownMenuItem } from "../../../DropdownMenu/index.js";
|
|
6
6
|
import { Text } from "../../../Text/index.js";
|
|
7
|
-
const ValueMenuItem = ({ option, isChecked, isPending, multiSelect, onSelect
|
|
7
|
+
const ValueMenuItem = ({ option, isChecked, isPending, multiSelect, onSelect })=>/*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
8
8
|
value: String(option.value),
|
|
9
|
-
ref: registerItem?.(String(option.value)),
|
|
10
9
|
onSelect: onSelect,
|
|
11
10
|
className: isPending ? 'bg-states-primary-hover' : void 0,
|
|
12
11
|
children: [
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuState.d.ts
CHANGED
|
@@ -31,7 +31,6 @@ export declare const useValueMenuState: ({ values, open, multiSelect, initialVal
|
|
|
31
31
|
highlightedValue: string | null;
|
|
32
32
|
}) => void;
|
|
33
33
|
pendingIds: Set<string>;
|
|
34
|
-
registerItem: (id: string) => (el: HTMLElement | null) => void;
|
|
35
34
|
commitChecked: () => boolean;
|
|
36
35
|
handleItemSelect: (item: FilterInputDropdownItem) => void;
|
|
37
36
|
};
|
package/dist/components/FilterInput/FilterInputMenu/FilterInputValueMenu/useValueMenuState.js
CHANGED
|
@@ -68,7 +68,7 @@ const useValueMenuState = ({ values, open, multiSelect, initialValues, highlight
|
|
|
68
68
|
if (multiSelect) commitChecked();
|
|
69
69
|
onOpenChange?.(false);
|
|
70
70
|
};
|
|
71
|
-
const { highlightedValue, onHighlightChange, pendingIds
|
|
71
|
+
const { highlightedValue, onHighlightChange, pendingIds } = useKeyboardNav({
|
|
72
72
|
items: flatItems,
|
|
73
73
|
open,
|
|
74
74
|
onSelect: handleItemSelect,
|
|
@@ -94,7 +94,6 @@ const useValueMenuState = ({ values, open, multiSelect, initialValues, highlight
|
|
|
94
94
|
highlightedValue,
|
|
95
95
|
onHighlightChange,
|
|
96
96
|
pendingIds,
|
|
97
|
-
registerItem,
|
|
98
97
|
commitChecked,
|
|
99
98
|
handleItemSelect
|
|
100
99
|
};
|
|
@@ -2,11 +2,6 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
2
2
|
const useKeyboardNav = ({ items, open, onSelect, onClose, onArrowRight, onPendingCommit, arrowRightSelectsActive = false, inputRef, menuRef })=>{
|
|
3
3
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
4
4
|
const [pendingIds, setPendingIds] = useState(new Set());
|
|
5
|
-
const itemRegistryRef = useRef(new Map());
|
|
6
|
-
const registerItem = useCallback((id)=>(el)=>{
|
|
7
|
-
if (el) itemRegistryRef.current.set(id, el);
|
|
8
|
-
else itemRegistryRef.current.delete(id);
|
|
9
|
-
}, []);
|
|
10
5
|
const activeIndexRef = useRef(-1);
|
|
11
6
|
const pendingIdsRef = useRef(pendingIds);
|
|
12
7
|
pendingIdsRef.current = pendingIds;
|
|
@@ -67,7 +62,9 @@ const useKeyboardNav = ({ items, open, onSelect, onClose, onArrowRight, onPendin
|
|
|
67
62
|
setActiveIndex(next);
|
|
68
63
|
const itemId = list[next]?.id;
|
|
69
64
|
if (itemId) requestAnimationFrame(()=>{
|
|
70
|
-
|
|
65
|
+
const container = stateRef.current.menuRef?.current;
|
|
66
|
+
const el = container?.querySelector(`[role="menuitem"][data-value="${CSS.escape(itemId)}"]`);
|
|
67
|
+
el?.scrollIntoView({
|
|
71
68
|
block: 'nearest'
|
|
72
69
|
});
|
|
73
70
|
});
|
|
@@ -220,7 +217,9 @@ const useKeyboardNav = ({ items, open, onSelect, onClose, onArrowRight, onPendin
|
|
|
220
217
|
setActiveIndex(idx);
|
|
221
218
|
activeIndexRef.current = idx;
|
|
222
219
|
}
|
|
223
|
-
|
|
220
|
+
const container = stateRef.current.menuRef?.current;
|
|
221
|
+
const el = container?.querySelector(`[role="menuitem"][data-value="${CSS.escape(details.highlightedValue)}"]`);
|
|
222
|
+
el?.scrollIntoView({
|
|
224
223
|
block: 'nearest'
|
|
225
224
|
});
|
|
226
225
|
}, []);
|
|
@@ -230,8 +229,7 @@ const useKeyboardNav = ({ items, open, onSelect, onClose, onArrowRight, onPendin
|
|
|
230
229
|
setActiveIndex,
|
|
231
230
|
highlightedValue,
|
|
232
231
|
onHighlightChange,
|
|
233
|
-
pendingIds
|
|
234
|
-
registerItem
|
|
232
|
+
pendingIds
|
|
235
233
|
};
|
|
236
234
|
};
|
|
237
235
|
export { useKeyboardNav };
|
package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.d.ts
CHANGED
|
@@ -71,7 +71,5 @@ export declare const useFilterInputAutocomplete: ({ fields, conditions, chips, u
|
|
|
71
71
|
closeAutocompleteMenu: () => void;
|
|
72
72
|
blurCommitRef: RefObject<(() => boolean) | null>;
|
|
73
73
|
setInputText: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
74
|
-
segmentAttributeInputRef: RefObject<HTMLInputElement | null>;
|
|
75
|
-
segmentValueInputRef: RefObject<HTMLInputElement | null>;
|
|
76
74
|
};
|
|
77
75
|
export {};
|
package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFilterInputAutocomplete.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useRef, useState } from "react";
|
|
2
2
|
import { flushSync } from "react-dom";
|
|
3
3
|
import { useDateRange } from "../../FilterInputMenu/FilterInputDateValueMenu/hooks.js";
|
|
4
|
-
import { applyAcceptChar, chipIdToConditionIndex
|
|
4
|
+
import { applyAcceptChar, chipIdToConditionIndex } from "../../lib/index.js";
|
|
5
5
|
import { deriveAutocompleteValues } from "./deriveAutocompleteValues.js";
|
|
6
6
|
import { useChipEditing } from "./useChipEditing.js";
|
|
7
7
|
import { useFocusManagement } from "./useFocusManagement.js";
|
|
@@ -25,8 +25,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
25
25
|
const conditionsLengthRef = useRef(conditions.length);
|
|
26
26
|
conditionsLengthRef.current = conditions.length;
|
|
27
27
|
const blurCommitRef = useRef(null);
|
|
28
|
-
const segmentAttributeInputRef = useRef(null);
|
|
29
|
-
const segmentValueInputRef = useRef(null);
|
|
30
28
|
const { menuPositioning, setMenuOffset, resetMenuOffset } = useMenuPositioning({
|
|
31
29
|
containerRef,
|
|
32
30
|
buildingChipRef,
|
|
@@ -63,14 +61,11 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
63
61
|
flushSync(doReset);
|
|
64
62
|
setMenuState('field');
|
|
65
63
|
} else doReset();
|
|
66
|
-
|
|
67
|
-
const stayedInside = active === document.body || containerRef.current?.contains(active) || isMenuRelated(active);
|
|
68
|
-
if (stayedInside) inputRef.current?.focus();
|
|
64
|
+
inputRef.current?.focus();
|
|
69
65
|
}, [
|
|
70
66
|
editing,
|
|
71
67
|
dateRange,
|
|
72
68
|
inputRef,
|
|
73
|
-
containerRef,
|
|
74
69
|
resetMenuOffset
|
|
75
70
|
]);
|
|
76
71
|
const selectedFieldRef = useRef(selectedField);
|
|
@@ -123,9 +118,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
123
118
|
const text = inputTextRef.current.trim();
|
|
124
119
|
if (!field) return false;
|
|
125
120
|
if (editing.editingChipId) return false;
|
|
126
|
-
selectedFieldRef.current = null;
|
|
127
|
-
selectedOperatorRef.current = null;
|
|
128
|
-
inputTextRef.current = '';
|
|
129
121
|
if (operator && text) {
|
|
130
122
|
handleCustomValueCommit(text);
|
|
131
123
|
return true;
|
|
@@ -148,8 +140,6 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
148
140
|
containerRef,
|
|
149
141
|
inputRef,
|
|
150
142
|
editingSegment: editing.editingSegment,
|
|
151
|
-
segmentAttributeInputRef,
|
|
152
|
-
segmentValueInputRef,
|
|
153
143
|
blurCommitRef,
|
|
154
144
|
commitBuildingOnBlur,
|
|
155
145
|
setIsFocused,
|
|
@@ -249,9 +239,7 @@ const useFilterInputAutocomplete = ({ fields, conditions, chips, upsertCondition
|
|
|
249
239
|
menuRef,
|
|
250
240
|
closeAutocompleteMenu,
|
|
251
241
|
blurCommitRef,
|
|
252
|
-
setInputText
|
|
253
|
-
segmentAttributeInputRef,
|
|
254
|
-
segmentValueInputRef
|
|
242
|
+
setInputText
|
|
255
243
|
};
|
|
256
244
|
};
|
|
257
245
|
export { useFilterInputAutocomplete };
|
package/dist/components/FilterInput/hooks/useFilterInputAutocomplete/useFocusManagement.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { FocusEvent, RefObject } from 'react';
|
|
2
|
-
import type { ChipSegment } from '../../FilterInputField/FilterInputChip';
|
|
3
2
|
import type { MenuState } from '../../types';
|
|
4
3
|
interface UseFocusManagementDeps {
|
|
5
4
|
menuState: MenuState;
|
|
@@ -8,11 +7,7 @@ interface UseFocusManagementDeps {
|
|
|
8
7
|
inputText: string;
|
|
9
8
|
containerRef: RefObject<HTMLElement | null>;
|
|
10
9
|
inputRef: RefObject<HTMLInputElement | null>;
|
|
11
|
-
editingSegment:
|
|
12
|
-
/** Direct ref to the attribute segment <input> when editing — avoids querySelector. */
|
|
13
|
-
segmentAttributeInputRef: RefObject<HTMLInputElement | null>;
|
|
14
|
-
/** Direct ref to the value segment <input> when editing — avoids querySelector. */
|
|
15
|
-
segmentValueInputRef: RefObject<HTMLInputElement | null>;
|
|
10
|
+
editingSegment: string | null;
|
|
16
11
|
/** Ref set by FilterInputValueMenu — calls commitChecked() for multi-select before blur reset. Returns true if committed. */
|
|
17
12
|
blurCommitRef: RefObject<(() => boolean) | null>;
|
|
18
13
|
/** Tries to commit a building chip's freeform value on blur. Returns true if committed. */
|
|
@@ -22,7 +17,7 @@ interface UseFocusManagementDeps {
|
|
|
22
17
|
resetMenuOffset: () => void;
|
|
23
18
|
resetState: (continueBuilding?: boolean) => void;
|
|
24
19
|
}
|
|
25
|
-
export declare const useFocusManagement: ({ menuState, isFocused, conditionsLength, inputText, containerRef, inputRef, editingSegment,
|
|
20
|
+
export declare const useFocusManagement: ({ menuState, isFocused, conditionsLength, inputText, containerRef, inputRef, editingSegment, blurCommitRef, commitBuildingOnBlur, setIsFocused, setMenuState, resetMenuOffset, resetState, }: UseFocusManagementDeps) => {
|
|
26
21
|
handleFocus: (e: FocusEvent) => void;
|
|
27
22
|
handleBlur: (e: FocusEvent) => void;
|
|
28
23
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import { isMenuRelated } from "../../lib/index.js";
|
|
3
|
-
const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText, containerRef, inputRef, editingSegment,
|
|
3
|
+
const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText, containerRef, inputRef, editingSegment, blurCommitRef, commitBuildingOnBlur, setIsFocused, setMenuState, resetMenuOffset, resetState })=>{
|
|
4
4
|
const handleFocus = useCallback((e)=>{
|
|
5
5
|
if (e.target?.closest?.('[data-slot="filter-input-connector-chip"]')) return;
|
|
6
6
|
setIsFocused(true);
|
|
@@ -14,15 +14,12 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
|
|
|
14
14
|
setIsFocused(false);
|
|
15
15
|
const committed = blurCommitRef.current?.() || commitBuildingOnBlur();
|
|
16
16
|
if (!committed) resetState();
|
|
17
|
-
related?.focus();
|
|
18
|
-
if (document.activeElement === inputRef.current) inputRef.current?.blur();
|
|
19
17
|
}, [
|
|
20
18
|
containerRef,
|
|
21
19
|
blurCommitRef,
|
|
22
20
|
commitBuildingOnBlur,
|
|
23
21
|
resetState,
|
|
24
|
-
setIsFocused
|
|
25
|
-
inputRef
|
|
22
|
+
setIsFocused
|
|
26
23
|
]);
|
|
27
24
|
const prevFocusedRef = useRef(false);
|
|
28
25
|
useEffect(()=>{
|
|
@@ -40,17 +37,12 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
|
|
|
40
37
|
]);
|
|
41
38
|
useEffect(()=>{
|
|
42
39
|
if ('closed' === menuState) return;
|
|
43
|
-
if (!isFocused) return;
|
|
44
40
|
let outerRaf = 0;
|
|
45
41
|
let innerRaf = 0;
|
|
46
42
|
outerRaf = requestAnimationFrame(()=>{
|
|
47
43
|
innerRaf = requestAnimationFrame(()=>{
|
|
48
|
-
const container = containerRef.current;
|
|
49
|
-
if (!container) return;
|
|
50
|
-
const active = document.activeElement;
|
|
51
|
-
if (active && !container.contains(active) && !isMenuRelated(active)) return;
|
|
52
44
|
if (editingSegment) {
|
|
53
|
-
const segmentInput =
|
|
45
|
+
const segmentInput = containerRef.current?.querySelector(`[data-slot="segment-${editingSegment}"] input`);
|
|
54
46
|
if (segmentInput && document.activeElement !== segmentInput) {
|
|
55
47
|
segmentInput.focus();
|
|
56
48
|
segmentInput.select();
|
|
@@ -64,12 +56,9 @@ const useFocusManagement = ({ menuState, isFocused, conditionsLength, inputText,
|
|
|
64
56
|
};
|
|
65
57
|
}, [
|
|
66
58
|
menuState,
|
|
67
|
-
isFocused,
|
|
68
59
|
inputRef,
|
|
69
60
|
editingSegment,
|
|
70
|
-
containerRef
|
|
71
|
-
segmentAttributeInputRef,
|
|
72
|
-
segmentValueInputRef
|
|
61
|
+
containerRef
|
|
73
62
|
]);
|
|
74
63
|
return {
|
|
75
64
|
handleFocus,
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if an element belongs to a FilterInput-owned menu/portal overlay.
|
|
3
|
-
*
|
|
4
|
-
* Menus are marked with `data-filter-input-menu` on their `DropdownMenuContent`
|
|
5
|
-
* root. Generic Ark UI selectors (`[role="menu"]`, `[data-part="content"]`,
|
|
6
|
-
* `[data-scope="date-picker"]`) intentionally DO NOT match — otherwise blur
|
|
7
|
-
* handlers mistake unrelated page popups (tenant switcher, other dropdowns)
|
|
8
|
-
* for FilterInput's own menu and refuse to close. See AS-882.
|
|
9
|
-
*/
|
|
1
|
+
/** Check if an element belongs to a menu/portal overlay (dropdown, date-picker, etc.) */
|
|
10
2
|
export declare const isMenuRelated: (el: HTMLElement | null) => boolean;
|
|
11
3
|
/**
|
|
12
4
|
* Build a DOMRect-compatible object anchored vertically to the container
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const isMenuRelated = (el)=>!!el?.closest('[data-
|
|
1
|
+
const isMenuRelated = (el)=>!!(el?.closest('[role="menu"]') || el?.closest('[data-scope="menu"]') || el?.closest('[data-scope="date-picker"]') || el?.closest('[data-part="content"]'));
|
|
2
2
|
const buildContainerAnchoredRect = (containerRect, anchorLeft, anchorRight = containerRect.right)=>({
|
|
3
3
|
x: anchorLeft,
|
|
4
4
|
y: containerRect.top,
|
|
@@ -2,7 +2,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { cva } from "class-variance-authority";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
5
|
-
const inputGroupVariants = cva(cn('group/input-group', 'w-full flex items-center border rounded-8 bg-component-input-bg relative', 'has-[>textarea]:h-auto', '**:data-[slot=input]:flex-1', '**:data-[slot=input]:rounded-none', '**:data-[slot=input]:border-0', '**:data-[slot=input]:bg-transparent', '**:data-[slot=input]:shadow-none', '**:data-[slot=input]:focus-visible:ring-0', '**:data-[slot=input]:focus-within:ring-0', 'border border-border-primary outline-none shadow-xs transition-[color,border,box-shadow]', 'has-[[data-slot=input]:not(:disabled):not([aria-disabled=true]):not(:focus-visible)]:hover:border-component-border-input-hover', 'focus-visible:ring-focus-primary', 'has-[[data-slot=input]:focus-visible]:ring-3', 'has-[[data-slot=input]:focus-visible]:ring-focus-primary', 'has-[[data-slot=input]:focus-visible]:border-border-strong-primary', 'focus-within:ring-focus-primary', 'has-[[data-slot=input]:focus-within]:ring-3', 'has-[[data-slot=input]:focus-within]:ring-focus-primary', 'has-[[data-slot=input]:focus-within]:border-border-strong-primary', 'has-[[data-slot][aria-invalid=true]]:border-border-strong-danger', 'has-[[data-slot][aria-invalid=true]]:ring-focus-destructive', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true])]:hover:border-border-strong-danger', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true])]:hover:ring-3', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true])]:hover:ring-focus-destructive-hover', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true])]:*:data-[slot=input]:hover:ring-0', 'has-[[data-slot=input]:disabled]:opacity-50', 'has-[[data-slot=input][aria-disabled=true]]:opacity-50', 'has-[[data-slot=input]:disabled]:cursor-not-allowed', 'has-[[data-slot=input][aria-disabled=true]]:cursor-not-allowed'), {
|
|
5
|
+
const inputGroupVariants = cva(cn('group/input-group', 'w-full flex items-center border rounded-8 bg-component-input-bg relative', 'has-[>textarea]:h-auto', '**:data-[slot=input]:flex-1', '**:data-[slot=input]:rounded-none', '**:data-[slot=input]:border-0', '**:data-[slot=input]:bg-transparent', '**:data-[slot=input]:shadow-none', '**:data-[slot=input]:focus-visible:ring-0', '**:data-[slot=input]:focus-within:ring-0', 'border border-border-primary outline-none shadow-xs transition-[color,border,box-shadow]', 'has-[[data-slot=input]:not(:disabled):not([aria-disabled=true]):not([data-readonly=true]):not(:focus-visible)]:hover:border-component-border-input-hover', 'focus-visible:ring-focus-primary', 'has-[[data-slot=input]:not([data-readonly=true]):focus-visible]:ring-3', 'has-[[data-slot=input]:not([data-readonly=true]):focus-visible]:ring-focus-primary', 'has-[[data-slot=input]:not([data-readonly=true]):focus-visible]:border-border-strong-primary', 'focus-within:ring-focus-primary', 'has-[[data-slot=input]:not([data-readonly=true]):focus-within]:ring-3', 'has-[[data-slot=input]:not([data-readonly=true]):focus-within]:ring-focus-primary', 'has-[[data-slot=input]:not([data-readonly=true]):focus-within]:border-border-strong-primary', 'has-[[data-slot][aria-invalid=true]]:border-border-strong-danger', 'has-[[data-slot][aria-invalid=true]]:ring-focus-destructive', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true]):not([data-readonly=true])]:hover:border-border-strong-danger', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true]):not([data-readonly=true])]:hover:ring-3', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true]):not([data-readonly=true])]:hover:ring-focus-destructive-hover', 'has-[[data-slot][aria-invalid=true]:not(:disabled):not([aria-disabled=true]):not([data-readonly=true])]:*:data-[slot=input]:hover:ring-0', 'has-[[data-slot=input]:disabled]:opacity-50', 'has-[[data-slot=input][aria-disabled=true]]:opacity-50', 'has-[[data-slot=input]:disabled]:cursor-not-allowed', 'has-[[data-slot=input][aria-disabled=true]]:cursor-not-allowed'), {
|
|
6
6
|
variants: {
|
|
7
7
|
size: {
|
|
8
8
|
default: 'h-36',
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { X } from "../../icons/index.js";
|
|
3
|
-
import {
|
|
4
|
-
const TemporalClear = ({ onClick, disabled = false })=>/*#__PURE__*/ jsx(
|
|
5
|
-
|
|
6
|
-
color: "neutral",
|
|
7
|
-
size: "small",
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
const TemporalClear = ({ onClick, disabled = false })=>/*#__PURE__*/ jsx("button", {
|
|
5
|
+
type: "button",
|
|
8
6
|
onClick: onClick,
|
|
9
7
|
disabled: disabled,
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
"aria-label": "Clear",
|
|
9
|
+
className: cn('inline-flex items-center justify-center', 'icon-md text-icon-primary', 'bg-transparent p-0 border-0', 'cursor-pointer', 'disabled:opacity-50 disabled:cursor-not-allowed', 'outline-none focus-visible:ring-3 focus-visible:ring-focus-primary rounded-4'),
|
|
10
|
+
children: /*#__PURE__*/ jsx(X, {
|
|
11
|
+
size: "md"
|
|
12
|
+
})
|
|
12
13
|
});
|
|
13
14
|
export { TemporalClear };
|
|
@@ -20,7 +20,7 @@ const segmentVariants = cva(cn('relative outline-none text-left', 'font-sans tex
|
|
|
20
20
|
false: 'hover:bg-states-primary-default-alt cursor-text'
|
|
21
21
|
},
|
|
22
22
|
type: {
|
|
23
|
-
literal:
|
|
23
|
+
literal: 'text-text-primary select-none hover:bg-transparent focus:bg-transparent rounded-2',
|
|
24
24
|
editable: 'px-1 focus:bg-bg-fill-brand focus:text-text-primary-alt'
|
|
25
25
|
}
|
|
26
26
|
},
|
|
@@ -35,22 +35,28 @@ const TemporalSegment = ({ segment, state, disabled = false, readOnly = false, d
|
|
|
35
35
|
const { segmentProps } = useDateSegment(segment, state, ref);
|
|
36
36
|
const isLiteral = 'literal' === segment.type;
|
|
37
37
|
const isEditable = segment.isEditable && !readOnly;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
const displayText = displayOverride ?? (isLiteral ? segment.text : resolveSegmentText(segment));
|
|
39
|
+
if (isLiteral || !isEditable) {
|
|
40
|
+
const isReadOnlySegment = !isLiteral && !isEditable && !disabled;
|
|
41
|
+
return /*#__PURE__*/ jsx("span", {
|
|
42
|
+
className: cn(segmentVariants({
|
|
43
|
+
type: 'literal',
|
|
44
|
+
isPlaceholder: !isLiteral && segment.isPlaceholder,
|
|
45
|
+
disabled
|
|
46
|
+
}), isReadOnlySegment && 'cursor-not-allowed'),
|
|
47
|
+
"data-segment": isLiteral ? void 0 : segment.type,
|
|
48
|
+
"data-placeholder": !isLiteral && segment.isPlaceholder ? true : void 0,
|
|
49
|
+
"aria-hidden": "true",
|
|
50
|
+
children: displayText
|
|
51
|
+
});
|
|
52
|
+
}
|
|
47
53
|
return /*#__PURE__*/ jsx("span", {
|
|
48
54
|
...segmentProps,
|
|
49
55
|
ref: ref,
|
|
50
56
|
className: cn(segmentVariants({
|
|
51
|
-
type:
|
|
57
|
+
type: 'editable',
|
|
52
58
|
isPlaceholder: segment.isPlaceholder,
|
|
53
|
-
disabled
|
|
59
|
+
disabled
|
|
54
60
|
})),
|
|
55
61
|
"data-segment": segment.type,
|
|
56
62
|
"data-placeholder": segment.isPlaceholder || void 0,
|
package/package.json
CHANGED