@shipfox/react-ui 0.21.0 → 0.23.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/dashboard/components/charts/bar-chart.d.ts +3 -2
- package/dist/components/dashboard/components/charts/bar-chart.js +13 -7
- package/dist/components/dashboard/components/charts/line-chart.d.ts +3 -2
- package/dist/components/dashboard/components/charts/line-chart.js +13 -7
- package/dist/components/dashboard/context/dashboard-context.d.ts +12 -8
- package/dist/components/dashboard/context/dashboard-context.js +42 -7
- package/dist/components/dashboard/context/index.d.ts +2 -2
- package/dist/components/dashboard/context/index.js +1 -1
- package/dist/components/dashboard/context/types.d.ts +9 -7
- package/dist/components/dashboard/index.d.ts +2 -4
- package/dist/components/dashboard/index.js +1 -2
- package/dist/components/dashboard/pages/analytics-page.js +41 -11
- package/dist/components/dashboard/pages/jobs-page.js +2 -4
- package/dist/components/dashboard/toolbar/filter-button.d.ts +6 -10
- package/dist/components/dashboard/toolbar/filter-button.js +109 -76
- package/dist/components/dashboard/toolbar/page-toolbar.d.ts +7 -19
- package/dist/components/dashboard/toolbar/page-toolbar.js +11 -99
- package/dist/components/dashboard/toolbar/toolbar-actions.js +3 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/interval-selector/hooks/index.d.ts +4 -0
- package/dist/components/interval-selector/hooks/index.js +5 -0
- package/dist/components/interval-selector/hooks/use-interval-selector-input.d.ts +30 -0
- package/dist/components/interval-selector/hooks/use-interval-selector-input.js +125 -0
- package/dist/components/interval-selector/hooks/use-interval-selector-navigation.d.ts +21 -0
- package/dist/components/interval-selector/hooks/use-interval-selector-navigation.js +58 -0
- package/dist/components/interval-selector/hooks/use-interval-selector.d.ts +25 -0
- package/dist/components/interval-selector/hooks/use-interval-selector.js +75 -0
- package/dist/components/interval-selector/index.d.ts +3 -0
- package/dist/components/interval-selector/index.js +4 -0
- package/dist/components/interval-selector/interval-selector-calendar.d.ts +7 -0
- package/dist/components/interval-selector/interval-selector-calendar.js +47 -0
- package/dist/components/interval-selector/interval-selector-input.d.ts +8 -0
- package/dist/components/interval-selector/interval-selector-input.js +34 -0
- package/dist/components/interval-selector/interval-selector-suggestions.d.ts +11 -0
- package/dist/components/interval-selector/interval-selector-suggestions.js +107 -0
- package/dist/components/interval-selector/interval-selector.d.ts +12 -0
- package/dist/components/interval-selector/interval-selector.js +56 -0
- package/dist/components/interval-selector/interval-selector.stories.js +232 -0
- package/dist/components/interval-selector/types.d.ts +19 -0
- package/dist/components/interval-selector/types.js +3 -0
- package/dist/components/interval-selector/utils/constants.d.ts +24 -0
- package/dist/components/interval-selector/utils/constants.js +129 -0
- package/dist/components/interval-selector/utils/format.d.ts +16 -0
- package/dist/components/interval-selector/utils/format.js +23 -0
- package/dist/components/interval-selector/utils/index.d.ts +3 -0
- package/dist/components/interval-selector/utils/index.js +4 -0
- package/dist/components/popover/popover.d.ts +3 -1
- package/dist/components/popover/popover.js +2 -1
- package/dist/styles.css +1 -1
- package/dist/utils/date.js +130 -22
- package/dist/utils/format/date.d.ts +1 -0
- package/dist/utils/format/date.js +11 -4
- package/package.json +2 -1
- package/dist/components/dashboard/filters/expression-filter-bar.d.ts +0 -42
- package/dist/components/dashboard/filters/expression-filter-bar.js +0 -80
- package/dist/components/dashboard/filters/index.d.ts +0 -6
- package/dist/components/dashboard/filters/index.js +0 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
export function useIntervalSelectorNavigation({ relativeSuggestions, intervalSuggestions, highlightedIndex, setHighlightedIndex, popoverOpen, calendarOpen, onOpenCalendar, onSelect }) {
|
|
3
|
+
const allNavigableItems = useMemo(()=>[
|
|
4
|
+
...relativeSuggestions,
|
|
5
|
+
...intervalSuggestions,
|
|
6
|
+
{
|
|
7
|
+
type: 'calendar',
|
|
8
|
+
label: 'Select from calendar'
|
|
9
|
+
}
|
|
10
|
+
], [
|
|
11
|
+
relativeSuggestions,
|
|
12
|
+
intervalSuggestions
|
|
13
|
+
]);
|
|
14
|
+
const canNavigate = popoverOpen && !calendarOpen;
|
|
15
|
+
const currentIndex = highlightedIndex;
|
|
16
|
+
const isNavigating = canNavigate && currentIndex >= 0 && currentIndex < allNavigableItems.length;
|
|
17
|
+
const onKeyDown = useCallback((e)=>{
|
|
18
|
+
if (!canNavigate) return;
|
|
19
|
+
const items = allNavigableItems;
|
|
20
|
+
if (e.key === 'ArrowDown') {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;
|
|
23
|
+
setHighlightedIndex(nextIndex);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (e.key === 'ArrowUp') {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
const nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;
|
|
29
|
+
setHighlightedIndex(nextIndex);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (e.key === 'Enter' && isNavigating) {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
const item = items[currentIndex];
|
|
35
|
+
if (item.type === 'calendar') {
|
|
36
|
+
onOpenCalendar();
|
|
37
|
+
} else {
|
|
38
|
+
onSelect(item);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}, [
|
|
43
|
+
canNavigate,
|
|
44
|
+
isNavigating,
|
|
45
|
+
currentIndex,
|
|
46
|
+
allNavigableItems,
|
|
47
|
+
setHighlightedIndex,
|
|
48
|
+
onOpenCalendar,
|
|
49
|
+
onSelect
|
|
50
|
+
]);
|
|
51
|
+
return {
|
|
52
|
+
allNavigableItems,
|
|
53
|
+
onKeyDown,
|
|
54
|
+
isNavigating
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=use-interval-selector-navigation.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DismissableLayerProps } from '@radix-ui/react-dismissable-layer';
|
|
2
|
+
import type { IntervalSelectorProps } from '../interval-selector';
|
|
3
|
+
import type { IntervalSelection, IntervalSuggestion, RelativeSuggestion } from '../types';
|
|
4
|
+
export interface UseIntervalSelectorProps extends Pick<IntervalSelectorProps, 'onSelectionChange'> {
|
|
5
|
+
relativeSuggestions: RelativeSuggestion[];
|
|
6
|
+
intervalSuggestions: IntervalSuggestion[];
|
|
7
|
+
}
|
|
8
|
+
export declare function useIntervalSelector({ onSelectionChange, relativeSuggestions, intervalSuggestions, }: UseIntervalSelectorProps): {
|
|
9
|
+
onSelect: (selection: IntervalSelection) => void;
|
|
10
|
+
popoverOpen: boolean;
|
|
11
|
+
calendarOpen: boolean;
|
|
12
|
+
highlightedIndex: number;
|
|
13
|
+
inputRef: import("react").RefObject<HTMLInputElement | null>;
|
|
14
|
+
onFocus: () => void;
|
|
15
|
+
onBlur: () => void;
|
|
16
|
+
onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
17
|
+
onOpenCalendar: () => void;
|
|
18
|
+
onChange: () => void;
|
|
19
|
+
onInteractOutside: (e: Parameters<Required<DismissableLayerProps>["onInteractOutside"]>[0]) => void;
|
|
20
|
+
closeAll: () => void;
|
|
21
|
+
isNavigating: boolean;
|
|
22
|
+
isFocused: boolean;
|
|
23
|
+
setIsFocused: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=use-interval-selector.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from 'react';
|
|
2
|
+
import { useIntervalSelectorNavigation } from './use-interval-selector-navigation.js';
|
|
3
|
+
export function useIntervalSelector({ onSelectionChange, relativeSuggestions, intervalSuggestions }) {
|
|
4
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
5
|
+
const [calendarOpen, setCalendarOpen] = useState(false);
|
|
6
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
7
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
8
|
+
const isSelectingRef = useRef(false);
|
|
9
|
+
const inputRef = useRef(null);
|
|
10
|
+
const closeAll = useCallback(()=>{
|
|
11
|
+
setPopoverOpen(false);
|
|
12
|
+
inputRef.current?.blur();
|
|
13
|
+
setCalendarOpen(false);
|
|
14
|
+
setHighlightedIndex(-1);
|
|
15
|
+
setIsFocused(false);
|
|
16
|
+
}, []);
|
|
17
|
+
const onSelect = useCallback((selection)=>{
|
|
18
|
+
isSelectingRef.current = true;
|
|
19
|
+
onSelectionChange(selection);
|
|
20
|
+
closeAll();
|
|
21
|
+
}, [
|
|
22
|
+
closeAll,
|
|
23
|
+
onSelectionChange
|
|
24
|
+
]);
|
|
25
|
+
const onFocus = useCallback(()=>{
|
|
26
|
+
setPopoverOpen(true);
|
|
27
|
+
setHighlightedIndex(-1);
|
|
28
|
+
}, []);
|
|
29
|
+
const onBlur = useCallback(()=>{
|
|
30
|
+
if (!calendarOpen) setPopoverOpen(false);
|
|
31
|
+
}, [
|
|
32
|
+
calendarOpen
|
|
33
|
+
]);
|
|
34
|
+
const onOpenCalendar = useCallback(()=>{
|
|
35
|
+
setCalendarOpen(true);
|
|
36
|
+
}, []);
|
|
37
|
+
const { onKeyDown, isNavigating } = useIntervalSelectorNavigation({
|
|
38
|
+
relativeSuggestions,
|
|
39
|
+
intervalSuggestions,
|
|
40
|
+
highlightedIndex,
|
|
41
|
+
setHighlightedIndex,
|
|
42
|
+
popoverOpen,
|
|
43
|
+
calendarOpen,
|
|
44
|
+
onOpenCalendar,
|
|
45
|
+
onSelect
|
|
46
|
+
});
|
|
47
|
+
const onInteractOutside = useCallback((e)=>{
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
const target = e.target;
|
|
50
|
+
const isClickOnPopover = inputRef.current && (inputRef.current.contains(target) || target.closest('[data-radix-popover-trigger]'));
|
|
51
|
+
if (isClickOnPopover) return;
|
|
52
|
+
closeAll();
|
|
53
|
+
}, [
|
|
54
|
+
closeAll
|
|
55
|
+
]);
|
|
56
|
+
return {
|
|
57
|
+
onSelect,
|
|
58
|
+
popoverOpen,
|
|
59
|
+
calendarOpen,
|
|
60
|
+
highlightedIndex,
|
|
61
|
+
inputRef,
|
|
62
|
+
onFocus,
|
|
63
|
+
onBlur,
|
|
64
|
+
onKeyDown,
|
|
65
|
+
onOpenCalendar,
|
|
66
|
+
onChange: ()=>setHighlightedIndex(-1),
|
|
67
|
+
onInteractOutside,
|
|
68
|
+
closeAll,
|
|
69
|
+
isNavigating,
|
|
70
|
+
isFocused,
|
|
71
|
+
setIsFocused
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=use-interval-selector.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IntervalSelection } from './types';
|
|
2
|
+
interface IntervalSelectorCalendarProps {
|
|
3
|
+
onSelect: (selection: IntervalSelection) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare function IntervalSelectorCalendar({ onSelect }: IntervalSelectorCalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=interval-selector-calendar.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Calendar } from '../../components/calendar/index.js';
|
|
3
|
+
import { endOfDay, format, startOfDay } from 'date-fns';
|
|
4
|
+
import { useCallback, useState } from 'react';
|
|
5
|
+
export function IntervalSelectorCalendar({ onSelect }) {
|
|
6
|
+
const [selectedRange, setSelectedRange] = useState(undefined);
|
|
7
|
+
const handleSelect = useCallback((_, selectedDay)=>{
|
|
8
|
+
if (!selectedDay) return setSelectedRange(undefined);
|
|
9
|
+
if (!selectedRange?.from) return setSelectedRange({
|
|
10
|
+
from: selectedDay,
|
|
11
|
+
to: undefined
|
|
12
|
+
});
|
|
13
|
+
const start = selectedDay < selectedRange.from ? startOfDay(selectedDay) : startOfDay(selectedRange.from);
|
|
14
|
+
const end = selectedDay < selectedRange.from ? endOfDay(selectedRange.from) : endOfDay(selectedDay);
|
|
15
|
+
onSelect({
|
|
16
|
+
type: 'interval',
|
|
17
|
+
interval: {
|
|
18
|
+
start,
|
|
19
|
+
end
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return setSelectedRange(undefined);
|
|
23
|
+
}, [
|
|
24
|
+
onSelect,
|
|
25
|
+
selectedRange
|
|
26
|
+
]);
|
|
27
|
+
return /*#__PURE__*/ _jsx(Calendar, {
|
|
28
|
+
mode: "range",
|
|
29
|
+
selected: selectedRange,
|
|
30
|
+
onSelect: handleSelect,
|
|
31
|
+
numberOfMonths: 1,
|
|
32
|
+
formatters: {
|
|
33
|
+
formatWeekdayName: (date)=>format(date, 'EEEEE')
|
|
34
|
+
},
|
|
35
|
+
disabled: {
|
|
36
|
+
after: new Date()
|
|
37
|
+
},
|
|
38
|
+
classNames: {
|
|
39
|
+
root: 'relative w-full flex justify-center items-center',
|
|
40
|
+
months: 'w-full',
|
|
41
|
+
month_grid: 'flex flex-col justify-center items-center',
|
|
42
|
+
nav: 'flex items-center gap-4 absolute top-16 left-0 w-full z-10'
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=interval-selector-calendar.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type UseNewIntervalSelectorInputProps } from './hooks/use-interval-selector-input';
|
|
2
|
+
type IntervalSelectorInputProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
inputClassName?: string;
|
|
5
|
+
} & UseNewIntervalSelectorInputProps;
|
|
6
|
+
export declare function IntervalSelectorInput({ className, inputClassName, ...props }: IntervalSelectorInputProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=interval-selector-input.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Input } from '../../components/input/index.js';
|
|
3
|
+
import { Kbd } from '../../components/kbd/index.js';
|
|
4
|
+
import { PopoverTrigger } from '../../components/popover/index.js';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import { useIntervalSelectorInput } from './hooks/use-interval-selector-input.js';
|
|
7
|
+
export function IntervalSelectorInput({ className, inputClassName, ...props }) {
|
|
8
|
+
const { displayValue, shortcutValue, isFocused, isInvalid, shouldShake, onChange, onKeyDown, onFocus, onBlur, onMouseDown, onMouseUp, inputRef } = useIntervalSelectorInput(props);
|
|
9
|
+
return /*#__PURE__*/ _jsx(PopoverTrigger, {
|
|
10
|
+
asChild: true,
|
|
11
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
12
|
+
className: cn('relative', className, shouldShake && 'animate-shake'),
|
|
13
|
+
children: /*#__PURE__*/ _jsx(Input, {
|
|
14
|
+
ref: inputRef,
|
|
15
|
+
value: displayValue,
|
|
16
|
+
onChange: isFocused ? onChange : undefined,
|
|
17
|
+
onFocus: onFocus,
|
|
18
|
+
onBlur: onBlur,
|
|
19
|
+
onMouseDown: onMouseDown,
|
|
20
|
+
onMouseUp: onMouseUp,
|
|
21
|
+
onKeyDown: onKeyDown,
|
|
22
|
+
readOnly: !isFocused,
|
|
23
|
+
"aria-invalid": isInvalid && isFocused,
|
|
24
|
+
iconLeft: /*#__PURE__*/ _jsx(Kbd, {
|
|
25
|
+
className: "h-16 shrink-0 min-w-36",
|
|
26
|
+
children: shortcutValue
|
|
27
|
+
}),
|
|
28
|
+
className: cn('w-full pl-50', inputClassName)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=interval-selector-input.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IntervalSelection, IntervalSuggestion, RelativeSuggestion } from './types';
|
|
2
|
+
interface IntervalSelectorSuggestionsProps {
|
|
3
|
+
relativeSuggestions: RelativeSuggestion[];
|
|
4
|
+
intervalSuggestions: IntervalSuggestion[];
|
|
5
|
+
onSelect: (selection: IntervalSelection) => void;
|
|
6
|
+
onOpenCalendar: () => void;
|
|
7
|
+
highlightedIndex: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function IntervalSelectorSuggestions({ relativeSuggestions, intervalSuggestions, onSelect, onOpenCalendar, highlightedIndex, }: IntervalSelectorSuggestionsProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=interval-selector-suggestions.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '../../components/button/index.js';
|
|
3
|
+
import { Icon } from '../../components/icon/index.js';
|
|
4
|
+
import { Kbd } from '../../components/kbd/index.js';
|
|
5
|
+
import { Label } from '../../components/label/index.js';
|
|
6
|
+
import { useEffect, useRef } from 'react';
|
|
7
|
+
import { cn } from '../../utils/cn.js';
|
|
8
|
+
import { generateDurationShortcut, humanizeDurationToNow } from '../../utils/date.js';
|
|
9
|
+
export function IntervalSelectorSuggestions({ relativeSuggestions, intervalSuggestions, onSelect, onOpenCalendar, highlightedIndex }) {
|
|
10
|
+
const pastIntervalsStartIndex = 0;
|
|
11
|
+
const calendarIntervalsStartIndex = relativeSuggestions.length;
|
|
12
|
+
const calendarButtonIndex = calendarIntervalsStartIndex + intervalSuggestions.length;
|
|
13
|
+
const itemRefs = useRef([]);
|
|
14
|
+
useEffect(()=>{
|
|
15
|
+
if (highlightedIndex >= 0 && itemRefs.current[highlightedIndex]) {
|
|
16
|
+
itemRefs.current[highlightedIndex]?.scrollIntoView({
|
|
17
|
+
behavior: 'smooth',
|
|
18
|
+
block: 'nearest'
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}, [
|
|
22
|
+
highlightedIndex
|
|
23
|
+
]);
|
|
24
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
25
|
+
className: "flex flex-col gap-8",
|
|
26
|
+
children: [
|
|
27
|
+
/*#__PURE__*/ _jsx("div", {
|
|
28
|
+
className: "flex flex-col gap-4 p-4",
|
|
29
|
+
children: relativeSuggestions.map((option, index)=>{
|
|
30
|
+
const itemIndex = pastIntervalsStartIndex + index;
|
|
31
|
+
const isHighlighted = highlightedIndex === itemIndex;
|
|
32
|
+
const shortcut = generateDurationShortcut(option.duration);
|
|
33
|
+
const label = humanizeDurationToNow(option.duration);
|
|
34
|
+
return /*#__PURE__*/ _jsxs(Button, {
|
|
35
|
+
ref: (el)=>{
|
|
36
|
+
itemRefs.current[itemIndex] = el;
|
|
37
|
+
},
|
|
38
|
+
type: "button",
|
|
39
|
+
variant: "transparent",
|
|
40
|
+
onClick: ()=>onSelect(option),
|
|
41
|
+
className: cn('w-full text-foreground-neutral-subtle justify-start', isHighlighted && 'bg-background-button-transparent-hover'),
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsx(Kbd, {
|
|
44
|
+
className: "h-16 shrink-0 min-w-36",
|
|
45
|
+
children: shortcut
|
|
46
|
+
}),
|
|
47
|
+
/*#__PURE__*/ _jsx("span", {
|
|
48
|
+
children: label
|
|
49
|
+
})
|
|
50
|
+
]
|
|
51
|
+
}, shortcut);
|
|
52
|
+
})
|
|
53
|
+
}),
|
|
54
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
55
|
+
className: "border-t border-border-neutral-base-component flex flex-col gap-4 p-4",
|
|
56
|
+
children: [
|
|
57
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
58
|
+
className: "px-8 py-4 text-xs leading-20 text-foreground-neutral-subtle select-none",
|
|
59
|
+
children: "Calendar Time"
|
|
60
|
+
}),
|
|
61
|
+
/*#__PURE__*/ _jsx("div", {
|
|
62
|
+
className: "grid grid-cols-1 md:grid-cols-2 gap-4 [&>*:only-child]:md:col-span-2",
|
|
63
|
+
children: intervalSuggestions.map((option, index)=>{
|
|
64
|
+
const itemIndex = calendarIntervalsStartIndex + index;
|
|
65
|
+
const isHighlighted = highlightedIndex === itemIndex;
|
|
66
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
67
|
+
ref: (el)=>{
|
|
68
|
+
itemRefs.current[itemIndex] = el;
|
|
69
|
+
},
|
|
70
|
+
type: "button",
|
|
71
|
+
variant: "transparent",
|
|
72
|
+
onClick: ()=>onSelect(option),
|
|
73
|
+
className: cn('w-full text-foreground-neutral-subtle justify-start', isHighlighted && 'bg-background-button-transparent-hover'),
|
|
74
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
75
|
+
children: option.label
|
|
76
|
+
})
|
|
77
|
+
}, option.label);
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
}),
|
|
82
|
+
/*#__PURE__*/ _jsx("div", {
|
|
83
|
+
className: "border-t border-border-neutral-base-component p-4",
|
|
84
|
+
children: /*#__PURE__*/ _jsxs(Button, {
|
|
85
|
+
ref: (el)=>{
|
|
86
|
+
itemRefs.current[calendarButtonIndex] = el;
|
|
87
|
+
},
|
|
88
|
+
type: "button",
|
|
89
|
+
variant: "transparent",
|
|
90
|
+
onClick: onOpenCalendar,
|
|
91
|
+
className: cn('w-full text-foreground-neutral-subtle justify-start', highlightedIndex === calendarButtonIndex && 'bg-background-button-transparent-hover'),
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
94
|
+
name: "calendar2Line",
|
|
95
|
+
className: "size-16 shrink-0"
|
|
96
|
+
}),
|
|
97
|
+
/*#__PURE__*/ _jsx("span", {
|
|
98
|
+
children: "Select from calendar"
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=interval-selector-suggestions.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IntervalSelection, IntervalSuggestion, RelativeSuggestion } from './types';
|
|
2
|
+
export interface IntervalSelectorProps {
|
|
3
|
+
selection: IntervalSelection;
|
|
4
|
+
onSelectionChange: (selection: IntervalSelection) => void;
|
|
5
|
+
container?: HTMLElement | null;
|
|
6
|
+
className?: string;
|
|
7
|
+
inputClassName?: string;
|
|
8
|
+
relativeSuggestions?: RelativeSuggestion[];
|
|
9
|
+
intervalSuggestions?: IntervalSuggestion[];
|
|
10
|
+
}
|
|
11
|
+
export declare function IntervalSelector({ selection, onSelectionChange, container, className, inputClassName, relativeSuggestions, intervalSuggestions, }: IntervalSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=interval-selector.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Popover, PopoverContent } from '../../components/popover/index.js';
|
|
3
|
+
import { useIntervalSelector } from './hooks/use-interval-selector.js';
|
|
4
|
+
import { IntervalSelectorCalendar } from './interval-selector-calendar.js';
|
|
5
|
+
import { IntervalSelectorInput } from './interval-selector-input.js';
|
|
6
|
+
import { IntervalSelectorSuggestions } from './interval-selector-suggestions.js';
|
|
7
|
+
import { defaultIntervalSuggestions, defaultRelativeSuggestions } from './utils/index.js';
|
|
8
|
+
export function IntervalSelector({ selection, onSelectionChange, container, className, inputClassName, relativeSuggestions = defaultRelativeSuggestions, intervalSuggestions = defaultIntervalSuggestions }) {
|
|
9
|
+
const { onSelect, popoverOpen, calendarOpen, highlightedIndex, inputRef, isNavigating, isFocused, setIsFocused, onBlur, onFocus, onKeyDown, onChange, onOpenCalendar, closeAll, onInteractOutside } = useIntervalSelector({
|
|
10
|
+
onSelectionChange,
|
|
11
|
+
relativeSuggestions,
|
|
12
|
+
intervalSuggestions
|
|
13
|
+
});
|
|
14
|
+
return /*#__PURE__*/ _jsxs(Popover, {
|
|
15
|
+
open: popoverOpen,
|
|
16
|
+
children: [
|
|
17
|
+
/*#__PURE__*/ _jsx(IntervalSelectorInput, {
|
|
18
|
+
onSelect: onSelect,
|
|
19
|
+
selection: selection,
|
|
20
|
+
isNavigating: isNavigating,
|
|
21
|
+
className: className,
|
|
22
|
+
inputClassName: inputClassName,
|
|
23
|
+
onChange: onChange,
|
|
24
|
+
onKeyDown: onKeyDown,
|
|
25
|
+
onFocus: onFocus,
|
|
26
|
+
onBlur: onBlur,
|
|
27
|
+
inputRef: inputRef,
|
|
28
|
+
isFocused: isFocused,
|
|
29
|
+
setIsFocused: setIsFocused
|
|
30
|
+
}),
|
|
31
|
+
/*#__PURE__*/ _jsx(PopoverContent, {
|
|
32
|
+
align: "start",
|
|
33
|
+
sideOffset: 8,
|
|
34
|
+
className: "w-(--radix-popover-trigger-width) p-0",
|
|
35
|
+
onOpenAutoFocus: (e)=>e.preventDefault(),
|
|
36
|
+
onInteractOutside: onInteractOutside,
|
|
37
|
+
onEscapeKeyDown: (e)=>{
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
closeAll();
|
|
40
|
+
},
|
|
41
|
+
container: container,
|
|
42
|
+
children: calendarOpen ? /*#__PURE__*/ _jsx(IntervalSelectorCalendar, {
|
|
43
|
+
onSelect: onSelect
|
|
44
|
+
}) : popoverOpen ? /*#__PURE__*/ _jsx(IntervalSelectorSuggestions, {
|
|
45
|
+
relativeSuggestions: relativeSuggestions,
|
|
46
|
+
intervalSuggestions: intervalSuggestions,
|
|
47
|
+
onSelect: onSelect,
|
|
48
|
+
onOpenCalendar: onOpenCalendar,
|
|
49
|
+
highlightedIndex: highlightedIndex
|
|
50
|
+
}) : null
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=interval-selector.js.map
|