@shipfox/react-ui 0.18.0 → 0.20.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/calendar/calendar.js +12 -12
- package/dist/components/combobox/combobox.d.ts +21 -0
- package/dist/components/combobox/combobox.js +84 -0
- package/dist/components/combobox/combobox.stories.js +191 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +3 -0
- package/dist/components/command/command.d.ts +2 -1
- package/dist/components/command/command.js +9 -5
- package/dist/components/dashboard/components/kpi-card.js +4 -1
- package/dist/components/date-picker/date-picker.d.ts +1 -0
- package/dist/components/date-picker/date-picker.js +20 -4
- package/dist/components/date-picker/date-picker.stories.js +16 -0
- package/dist/components/date-time-range-picker/date-time-range-picker.d.ts +1 -0
- package/dist/components/date-time-range-picker/date-time-range-picker.js +51 -23
- package/dist/components/dropdown-input/dropdown-input.d.ts +25 -0
- package/dist/components/dropdown-input/dropdown-input.js +188 -0
- package/dist/components/dropdown-input/dropdown-input.stories.js +240 -0
- package/dist/components/dropdown-input/index.d.ts +2 -0
- package/dist/components/dropdown-input/index.js +3 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/components/input/input.d.ts +6 -3
- package/dist/components/input/input.js +27 -11
- package/dist/components/input/input.stories.js +66 -0
- package/dist/components/scroll-area/index.d.ts +2 -0
- package/dist/components/scroll-area/index.js +3 -0
- package/dist/components/scroll-area/scroll-area.d.ts +6 -0
- package/dist/components/scroll-area/scroll-area.js +34 -0
- package/dist/styles.css +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Input } from '../../components/input';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
export type DropdownInputItem<T = unknown> = {
|
|
5
|
+
id: string | number;
|
|
6
|
+
label: string;
|
|
7
|
+
value: T;
|
|
8
|
+
};
|
|
9
|
+
type InputBaseProps = Omit<ComponentProps<typeof Input>, 'value' | 'onChange' | 'onSelect'>;
|
|
10
|
+
export type DropdownInputProps<T = unknown> = InputBaseProps & {
|
|
11
|
+
value: string;
|
|
12
|
+
onValueChange: (value: string) => void;
|
|
13
|
+
onSelect?: (item: DropdownInputItem<T>) => void;
|
|
14
|
+
items: DropdownInputItem<T>[];
|
|
15
|
+
emptyPlaceholder?: string | ReactNode;
|
|
16
|
+
open: boolean;
|
|
17
|
+
onOpenChange: (open: boolean) => void;
|
|
18
|
+
focusedIndex: number;
|
|
19
|
+
onFocusedIndexChange: (index: number) => void;
|
|
20
|
+
selectedItem?: DropdownInputItem<T> | null;
|
|
21
|
+
dropdownClassName?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function DropdownInput<T = unknown>({ value, onValueChange, onSelect, items, emptyPlaceholder, open, onOpenChange, focusedIndex, onFocusedIndexChange, selectedItem, dropdownClassName, className, ...inputProps }: DropdownInputProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=dropdown-input.d.ts.map
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '../../components/button/index.js';
|
|
3
|
+
import { Input } from '../../components/input/index.js';
|
|
4
|
+
import { Popover, PopoverContent, PopoverTrigger } from '../../components/popover/index.js';
|
|
5
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
export function DropdownInput({ value, onValueChange, onSelect, items = [], emptyPlaceholder, open, onOpenChange, focusedIndex, onFocusedIndexChange, selectedItem, dropdownClassName, className, ...inputProps }) {
|
|
8
|
+
const inputRef = useRef(null);
|
|
9
|
+
const blurTimeoutRef = useRef(null);
|
|
10
|
+
const popoverContentRef = useRef(null);
|
|
11
|
+
const itemRefs = useRef([]);
|
|
12
|
+
const isDisabled = Boolean(inputProps.disabled);
|
|
13
|
+
const hasResults = items.length > 0;
|
|
14
|
+
const shouldShowDropdown = open && !isDisabled;
|
|
15
|
+
const handleOpenChange = useCallback((nextOpen)=>{
|
|
16
|
+
if (isDisabled) {
|
|
17
|
+
if (!nextOpen) onOpenChange(false);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
onOpenChange(nextOpen);
|
|
21
|
+
}, [
|
|
22
|
+
isDisabled,
|
|
23
|
+
onOpenChange
|
|
24
|
+
]);
|
|
25
|
+
const handleSelect = useCallback((item)=>{
|
|
26
|
+
onValueChange(item.label);
|
|
27
|
+
onSelect?.(item);
|
|
28
|
+
onOpenChange(false);
|
|
29
|
+
inputRef.current?.blur();
|
|
30
|
+
}, [
|
|
31
|
+
onValueChange,
|
|
32
|
+
onOpenChange,
|
|
33
|
+
onSelect
|
|
34
|
+
]);
|
|
35
|
+
const handleInputChange = useCallback((e)=>{
|
|
36
|
+
onValueChange(e.target.value);
|
|
37
|
+
onFocusedIndexChange(-1);
|
|
38
|
+
if (!open && !isDisabled) {
|
|
39
|
+
onOpenChange(true);
|
|
40
|
+
}
|
|
41
|
+
}, [
|
|
42
|
+
onValueChange,
|
|
43
|
+
onFocusedIndexChange,
|
|
44
|
+
open,
|
|
45
|
+
isDisabled,
|
|
46
|
+
onOpenChange
|
|
47
|
+
]);
|
|
48
|
+
const handleInputKeyDown = useCallback((e)=>{
|
|
49
|
+
if (!shouldShowDropdown || items.length === 0) return;
|
|
50
|
+
if (e.key === 'ArrowDown') {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
onFocusedIndexChange(focusedIndex < items.length - 1 ? focusedIndex + 1 : 0);
|
|
53
|
+
} else if (e.key === 'ArrowUp') {
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
onFocusedIndexChange(focusedIndex > 0 ? focusedIndex - 1 : items.length - 1);
|
|
56
|
+
} else if (e.key === 'Enter' && focusedIndex >= 0) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
const item = items[focusedIndex];
|
|
59
|
+
if (item) {
|
|
60
|
+
handleSelect(item);
|
|
61
|
+
}
|
|
62
|
+
} else if (e.key === 'Escape') {
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
onOpenChange(false);
|
|
65
|
+
}
|
|
66
|
+
}, [
|
|
67
|
+
shouldShowDropdown,
|
|
68
|
+
items,
|
|
69
|
+
focusedIndex,
|
|
70
|
+
onFocusedIndexChange,
|
|
71
|
+
handleSelect,
|
|
72
|
+
onOpenChange
|
|
73
|
+
]);
|
|
74
|
+
const handleInputBlur = useCallback(()=>{
|
|
75
|
+
if (blurTimeoutRef.current) {
|
|
76
|
+
clearTimeout(blurTimeoutRef.current);
|
|
77
|
+
}
|
|
78
|
+
blurTimeoutRef.current = setTimeout(()=>{
|
|
79
|
+
const activeElement = document.activeElement;
|
|
80
|
+
const popoverContent = activeElement?.closest('[data-radix-popper-content-wrapper]');
|
|
81
|
+
if (!popoverContent) {
|
|
82
|
+
onOpenChange(false);
|
|
83
|
+
}
|
|
84
|
+
}, 200);
|
|
85
|
+
}, [
|
|
86
|
+
onOpenChange
|
|
87
|
+
]);
|
|
88
|
+
useEffect(()=>{
|
|
89
|
+
return ()=>{
|
|
90
|
+
if (blurTimeoutRef.current) {
|
|
91
|
+
clearTimeout(blurTimeoutRef.current);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}, []);
|
|
95
|
+
useEffect(()=>{
|
|
96
|
+
if (focusedIndex >= 0 && itemRefs.current[focusedIndex]) {
|
|
97
|
+
itemRefs.current[focusedIndex]?.scrollIntoView({
|
|
98
|
+
block: 'nearest'
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}, [
|
|
102
|
+
focusedIndex
|
|
103
|
+
]);
|
|
104
|
+
const handlePointerDownOutside = useCallback((e)=>{
|
|
105
|
+
const target = e.target;
|
|
106
|
+
if (target && popoverContentRef.current?.contains(target)) {
|
|
107
|
+
e.preventDefault();
|
|
108
|
+
}
|
|
109
|
+
}, []);
|
|
110
|
+
return /*#__PURE__*/ _jsxs(Popover, {
|
|
111
|
+
open: shouldShowDropdown,
|
|
112
|
+
onOpenChange: handleOpenChange,
|
|
113
|
+
children: [
|
|
114
|
+
/*#__PURE__*/ _jsx(PopoverTrigger, {
|
|
115
|
+
asChild: true,
|
|
116
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
117
|
+
className: "w-full",
|
|
118
|
+
children: /*#__PURE__*/ _jsx(Input, {
|
|
119
|
+
ref: inputRef,
|
|
120
|
+
value: value,
|
|
121
|
+
onChange: handleInputChange,
|
|
122
|
+
onKeyDown: handleInputKeyDown,
|
|
123
|
+
onBlur: handleInputBlur,
|
|
124
|
+
onFocus: ()=>{
|
|
125
|
+
if (blurTimeoutRef.current) {
|
|
126
|
+
clearTimeout(blurTimeoutRef.current);
|
|
127
|
+
blurTimeoutRef.current = null;
|
|
128
|
+
}
|
|
129
|
+
if (!open && !isDisabled && value.length > 0 && hasResults) {
|
|
130
|
+
onOpenChange(true);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
className: className,
|
|
134
|
+
...inputProps
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
}),
|
|
138
|
+
/*#__PURE__*/ _jsx(PopoverContent, {
|
|
139
|
+
align: "start",
|
|
140
|
+
sideOffset: 8,
|
|
141
|
+
className: cn('w-(--radix-popover-trigger-width) rounded-8 bg-background-components-base p-4 shadow-tooltip', dropdownClassName),
|
|
142
|
+
onOpenAutoFocus: (e)=>e.preventDefault(),
|
|
143
|
+
onPointerDownOutside: handlePointerDownOutside,
|
|
144
|
+
onInteractOutside: handlePointerDownOutside,
|
|
145
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
146
|
+
ref: popoverContentRef,
|
|
147
|
+
className: "max-h-200 overflow-y-auto overscroll-contain scrollbar",
|
|
148
|
+
onWheel: (e)=>e.stopPropagation(),
|
|
149
|
+
onTouchStart: (e)=>e.stopPropagation(),
|
|
150
|
+
onTouchMove: (e)=>e.stopPropagation(),
|
|
151
|
+
children: hasResults ? /*#__PURE__*/ _jsxs("div", {
|
|
152
|
+
className: "flex flex-col gap-4 p-4",
|
|
153
|
+
children: [
|
|
154
|
+
/*#__PURE__*/ _jsx("div", {
|
|
155
|
+
className: "p-4 text-xs leading-20 text-foreground-neutral-muted",
|
|
156
|
+
children: "Select a repository"
|
|
157
|
+
}),
|
|
158
|
+
items.map((item, index)=>{
|
|
159
|
+
const isSelected = selectedItem?.id === item.id;
|
|
160
|
+
const isFocused = focusedIndex === index;
|
|
161
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
162
|
+
type: "button",
|
|
163
|
+
variant: "transparent",
|
|
164
|
+
ref: (el)=>{
|
|
165
|
+
itemRefs.current[index] = el;
|
|
166
|
+
},
|
|
167
|
+
onClick: ()=>handleSelect(item),
|
|
168
|
+
onMouseDown: (e)=>e.preventDefault(),
|
|
169
|
+
onMouseEnter: ()=>onFocusedIndexChange(index),
|
|
170
|
+
className: cn('!px-8 w-full text-left text-foreground-neutral-subtle', (isSelected || isFocused) && 'bg-background-components-hover text-foreground-neutral-base'),
|
|
171
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
172
|
+
className: "flex-1 truncate",
|
|
173
|
+
children: item.label
|
|
174
|
+
})
|
|
175
|
+
}, item.id);
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
179
|
+
className: "p-4 text-xs leading-20 text-foreground-neutral-muted",
|
|
180
|
+
children: emptyPlaceholder ? emptyPlaceholder : null
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=dropdown-input.js.map
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, ButtonLink } from '../../components/button/index.js';
|
|
3
|
+
import { DropdownInput } from '../../components/dropdown-input/index.js';
|
|
4
|
+
import { Icon } from '../../components/icon/index.js';
|
|
5
|
+
import { Label } from '../../components/label/index.js';
|
|
6
|
+
import { useMemo, useRef, useState } from 'react';
|
|
7
|
+
const sampleItems = [
|
|
8
|
+
{
|
|
9
|
+
id: 'apache',
|
|
10
|
+
label: 'apache',
|
|
11
|
+
value: 'apache'
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 'apache-superset',
|
|
15
|
+
label: 'apache-superset',
|
|
16
|
+
value: 'apache-superset'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'apaleo',
|
|
20
|
+
label: 'apaleo',
|
|
21
|
+
value: 'apaleo'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'apollo',
|
|
25
|
+
label: 'apollo',
|
|
26
|
+
value: 'apollo'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'apple',
|
|
30
|
+
label: 'apple',
|
|
31
|
+
value: 'apple'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'apache-kafka',
|
|
35
|
+
label: 'apache-kafka',
|
|
36
|
+
value: 'apache-kafka'
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
const meta = {
|
|
40
|
+
title: 'Components/DropdownInput',
|
|
41
|
+
component: DropdownInput,
|
|
42
|
+
tags: [
|
|
43
|
+
'autodocs'
|
|
44
|
+
],
|
|
45
|
+
parameters: {
|
|
46
|
+
layout: 'centered'
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
export default meta;
|
|
50
|
+
function CustomEmptyStateContent({ value, onValueChange, onOpenChange, contactSupportHref, inputRef }) {
|
|
51
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
52
|
+
className: "flex flex-col items-start justify-center",
|
|
53
|
+
children: [
|
|
54
|
+
/*#__PURE__*/ _jsxs(Button, {
|
|
55
|
+
type: "button",
|
|
56
|
+
variant: "transparent",
|
|
57
|
+
className: "!px-4 w-full justify-start",
|
|
58
|
+
onClick: ()=>{
|
|
59
|
+
onValueChange(value);
|
|
60
|
+
onOpenChange(false);
|
|
61
|
+
inputRef.current?.blur();
|
|
62
|
+
},
|
|
63
|
+
children: [
|
|
64
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
65
|
+
name: "addLine",
|
|
66
|
+
className: "size-16 text-foreground-neutral-subtle"
|
|
67
|
+
}),
|
|
68
|
+
/*#__PURE__*/ _jsx("span", {
|
|
69
|
+
className: "truncate",
|
|
70
|
+
children: value
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}),
|
|
74
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
75
|
+
className: "px-8 whitespace-pre-wrap",
|
|
76
|
+
children: [
|
|
77
|
+
"Repository list is limited to 100. Enter the full repository path or",
|
|
78
|
+
' ',
|
|
79
|
+
/*#__PURE__*/ _jsx(ButtonLink, {
|
|
80
|
+
variant: "base",
|
|
81
|
+
underline: true,
|
|
82
|
+
href: contactSupportHref,
|
|
83
|
+
target: "_blank",
|
|
84
|
+
rel: "noopener noreferrer",
|
|
85
|
+
className: "!font-regular",
|
|
86
|
+
children: "contact support"
|
|
87
|
+
}),
|
|
88
|
+
"."
|
|
89
|
+
]
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export const Default = {
|
|
95
|
+
args: {},
|
|
96
|
+
render: ()=>{
|
|
97
|
+
const [value, setValue] = useState('');
|
|
98
|
+
const [open, setOpen] = useState(false);
|
|
99
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
100
|
+
const [selectedItem, setSelectedItem] = useState(null);
|
|
101
|
+
const inputRef = useRef(null);
|
|
102
|
+
const items = useMemo(()=>{
|
|
103
|
+
if (value.length < 1) return sampleItems;
|
|
104
|
+
const lowerQuery = value.toLowerCase();
|
|
105
|
+
return sampleItems.filter((item)=>item.label.toLowerCase().includes(lowerQuery));
|
|
106
|
+
}, [
|
|
107
|
+
value
|
|
108
|
+
]);
|
|
109
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
110
|
+
className: "w-[80vw] md:w-500",
|
|
111
|
+
children: [
|
|
112
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
113
|
+
htmlFor: "dropdown-input",
|
|
114
|
+
children: "Search repositories"
|
|
115
|
+
}),
|
|
116
|
+
/*#__PURE__*/ _jsx(DropdownInput, {
|
|
117
|
+
id: "dropdown-input",
|
|
118
|
+
value: value,
|
|
119
|
+
onValueChange: (newValue)=>{
|
|
120
|
+
setValue(newValue);
|
|
121
|
+
if (selectedItem && selectedItem.label !== newValue) {
|
|
122
|
+
setSelectedItem(null);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
onSelect: (item)=>{
|
|
126
|
+
setSelectedItem(item);
|
|
127
|
+
},
|
|
128
|
+
selectedItem: selectedItem,
|
|
129
|
+
items: items,
|
|
130
|
+
open: open,
|
|
131
|
+
onOpenChange: setOpen,
|
|
132
|
+
focusedIndex: focusedIndex,
|
|
133
|
+
onFocusedIndexChange: setFocusedIndex,
|
|
134
|
+
placeholder: "Type to search...",
|
|
135
|
+
emptyPlaceholder: /*#__PURE__*/ _jsx(CustomEmptyStateContent, {
|
|
136
|
+
value: value,
|
|
137
|
+
onValueChange: setValue,
|
|
138
|
+
onOpenChange: setOpen,
|
|
139
|
+
contactSupportHref: "https://support.example.com",
|
|
140
|
+
inputRef: inputRef
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
export const EmptyState = {
|
|
148
|
+
args: {},
|
|
149
|
+
render: ()=>{
|
|
150
|
+
const [value, setValue] = useState('abcxyz');
|
|
151
|
+
const [open, setOpen] = useState(true);
|
|
152
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
153
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
154
|
+
className: "w-[80vw] md:w-500",
|
|
155
|
+
children: [
|
|
156
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
157
|
+
htmlFor: "dropdown-empty",
|
|
158
|
+
children: "No results"
|
|
159
|
+
}),
|
|
160
|
+
/*#__PURE__*/ _jsx(DropdownInput, {
|
|
161
|
+
id: "dropdown-empty",
|
|
162
|
+
value: value,
|
|
163
|
+
onValueChange: setValue,
|
|
164
|
+
items: [],
|
|
165
|
+
open: open,
|
|
166
|
+
onOpenChange: setOpen,
|
|
167
|
+
focusedIndex: focusedIndex,
|
|
168
|
+
onFocusedIndexChange: setFocusedIndex,
|
|
169
|
+
placeholder: "Type to search...",
|
|
170
|
+
emptyPlaceholder: "No results found"
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
export const LoadingState = {
|
|
177
|
+
args: {},
|
|
178
|
+
render: ()=>{
|
|
179
|
+
const [value, setValue] = useState('apache');
|
|
180
|
+
const [open, setOpen] = useState(true);
|
|
181
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
182
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
183
|
+
className: "w-[80vw] md:w-500",
|
|
184
|
+
children: [
|
|
185
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
186
|
+
htmlFor: "dropdown-loading",
|
|
187
|
+
children: "Loading"
|
|
188
|
+
}),
|
|
189
|
+
/*#__PURE__*/ _jsx(DropdownInput, {
|
|
190
|
+
id: "dropdown-loading",
|
|
191
|
+
value: value,
|
|
192
|
+
onValueChange: setValue,
|
|
193
|
+
items: [],
|
|
194
|
+
iconRight: /*#__PURE__*/ _jsx(Icon, {
|
|
195
|
+
name: "spinner",
|
|
196
|
+
className: "size-16 text-foreground-neutral-base"
|
|
197
|
+
}),
|
|
198
|
+
open: open,
|
|
199
|
+
onOpenChange: setOpen,
|
|
200
|
+
focusedIndex: focusedIndex,
|
|
201
|
+
onFocusedIndexChange: setFocusedIndex,
|
|
202
|
+
placeholder: "Type to search...",
|
|
203
|
+
emptyPlaceholder: "Fetching..."
|
|
204
|
+
})
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
export const DisabledState = {
|
|
210
|
+
args: {},
|
|
211
|
+
render: ()=>{
|
|
212
|
+
const [value, setValue] = useState('apache');
|
|
213
|
+
const [open, setOpen] = useState(false);
|
|
214
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
215
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
216
|
+
className: "w-[80vw] md:w-500",
|
|
217
|
+
children: [
|
|
218
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
219
|
+
htmlFor: "dropdown-disabled",
|
|
220
|
+
children: "Disabled"
|
|
221
|
+
}),
|
|
222
|
+
/*#__PURE__*/ _jsx(DropdownInput, {
|
|
223
|
+
id: "dropdown-disabled",
|
|
224
|
+
value: value,
|
|
225
|
+
onValueChange: setValue,
|
|
226
|
+
items: sampleItems,
|
|
227
|
+
disabled: true,
|
|
228
|
+
open: open,
|
|
229
|
+
onOpenChange: setOpen,
|
|
230
|
+
focusedIndex: focusedIndex,
|
|
231
|
+
onFocusedIndexChange: setFocusedIndex,
|
|
232
|
+
placeholder: "Disabled input",
|
|
233
|
+
emptyPlaceholder: "No results found"
|
|
234
|
+
})
|
|
235
|
+
]
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=dropdown-input.stories.js.map
|
|
@@ -7,6 +7,7 @@ export * from './calendar';
|
|
|
7
7
|
export * from './card';
|
|
8
8
|
export * from './checkbox';
|
|
9
9
|
export * from './code-block';
|
|
10
|
+
export * from './combobox';
|
|
10
11
|
export * from './command';
|
|
11
12
|
export * from './confetti';
|
|
12
13
|
export * from './count-up';
|
|
@@ -14,6 +15,7 @@ export * from './dashboard';
|
|
|
14
15
|
export * from './date-picker';
|
|
15
16
|
export * from './date-time-range-picker';
|
|
16
17
|
export * from './dot-grid';
|
|
18
|
+
export * from './dropdown-input';
|
|
17
19
|
export * from './dropdown-menu';
|
|
18
20
|
export * from './dynamic-item';
|
|
19
21
|
export * from './empty-state';
|
|
@@ -27,6 +29,7 @@ export * from './label';
|
|
|
27
29
|
export * from './modal';
|
|
28
30
|
export * from './moving-border';
|
|
29
31
|
export * from './popover';
|
|
32
|
+
export * from './scroll-area';
|
|
30
33
|
export * from './search';
|
|
31
34
|
export * from './select';
|
|
32
35
|
export * from './sheet';
|
package/dist/components/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from './calendar/index.js';
|
|
|
7
7
|
export * from './card/index.js';
|
|
8
8
|
export * from './checkbox/index.js';
|
|
9
9
|
export * from './code-block/index.js';
|
|
10
|
+
export * from './combobox/index.js';
|
|
10
11
|
export * from './command/index.js';
|
|
11
12
|
export * from './confetti/index.js';
|
|
12
13
|
export * from './count-up/index.js';
|
|
@@ -14,6 +15,7 @@ export * from './dashboard/index.js';
|
|
|
14
15
|
export * from './date-picker/index.js';
|
|
15
16
|
export * from './date-time-range-picker/index.js';
|
|
16
17
|
export * from './dot-grid/index.js';
|
|
18
|
+
export * from './dropdown-input/index.js';
|
|
17
19
|
export * from './dropdown-menu/index.js';
|
|
18
20
|
export * from './dynamic-item/index.js';
|
|
19
21
|
export * from './empty-state/index.js';
|
|
@@ -27,6 +29,7 @@ export * from './label/index.js';
|
|
|
27
29
|
export * from './modal/index.js';
|
|
28
30
|
export * from './moving-border/index.js';
|
|
29
31
|
export * from './popover/index.js';
|
|
32
|
+
export * from './scroll-area/index.js';
|
|
30
33
|
export * from './search/index.js';
|
|
31
34
|
export * from './select/index.js';
|
|
32
35
|
export * from './sheet/index.js';
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
-
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
3
3
|
export declare const inputVariants: (props?: ({
|
|
4
4
|
variant?: "base" | "component" | null | undefined;
|
|
5
5
|
size?: "base" | "small" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
-
type InputProps = Omit<ComponentProps<'input'>, 'size'> & VariantProps<typeof inputVariants
|
|
8
|
-
|
|
7
|
+
type InputProps = Omit<ComponentProps<'input'>, 'size'> & VariantProps<typeof inputVariants> & {
|
|
8
|
+
iconLeft?: ReactNode;
|
|
9
|
+
iconRight?: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
export declare const Input: import("react").ForwardRefExoticComponent<Omit<InputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
9
12
|
export {};
|
|
10
13
|
//# sourceMappingURL=input.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cva } from 'class-variance-authority';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
3
4
|
import { cn } from '../../utils/cn.js';
|
|
4
5
|
export const inputVariants = cva('', {
|
|
5
6
|
variants: {
|
|
@@ -17,16 +18,31 @@ export const inputVariants = cva('', {
|
|
|
17
18
|
size: 'base'
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
|
-
export
|
|
21
|
-
return /*#__PURE__*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
export const Input = /*#__PURE__*/ forwardRef(({ className, type, variant, size, iconLeft, iconRight, ...props }, ref)=>{
|
|
22
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
23
|
+
className: "relative flex items-center w-full",
|
|
24
|
+
children: [
|
|
25
|
+
iconLeft && /*#__PURE__*/ _jsx("div", {
|
|
26
|
+
className: "absolute left-8 top-1/2 -translate-y-1/2 flex items-center justify-center shrink-0 pointer-events-none z-10",
|
|
27
|
+
children: iconLeft
|
|
28
|
+
}),
|
|
29
|
+
/*#__PURE__*/ _jsx("input", {
|
|
30
|
+
ref: ref,
|
|
31
|
+
type: type,
|
|
32
|
+
"data-slot": "input",
|
|
33
|
+
className: cn('placeholder:text-foreground-neutral-muted w-full min-w-0 rounded-6 text-sm leading-20 text-foreground-neutral-base shadow-button-neutral transition-[color,box-shadow] outline-none', 'hover:bg-background-field-hover', 'selection:bg-background-accent-neutral-soft selection:text-foreground-neutral-on-inverted', 'file:text-foreground-neutral-base file:inline-flex file:font-medium', 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-background-neutral-disabled disabled:shadow-none disabled:text-foreground-neutral-disabled', 'focus-visible:shadow-border-interactive-with-active', 'aria-invalid:shadow-border-error', iconLeft ? 'pl-32' : 'pl-8', iconRight ? 'pr-32' : 'pr-8', inputVariants({
|
|
34
|
+
variant,
|
|
35
|
+
size
|
|
36
|
+
}), className),
|
|
37
|
+
...props
|
|
38
|
+
}),
|
|
39
|
+
iconRight && /*#__PURE__*/ _jsx("div", {
|
|
40
|
+
className: "absolute right-8 top-1/2 -translate-y-1/2 flex items-center justify-center shrink-0 pointer-events-none z-10",
|
|
41
|
+
children: iconRight
|
|
42
|
+
})
|
|
43
|
+
]
|
|
29
44
|
});
|
|
30
|
-
}
|
|
45
|
+
});
|
|
46
|
+
Input.displayName = 'Input';
|
|
31
47
|
|
|
32
48
|
//# sourceMappingURL=input.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon } from '../../components/icon/index.js';
|
|
2
3
|
import { Code, Header } from '../../components/typography/index.js';
|
|
3
4
|
import { Input } from './input.js';
|
|
4
5
|
const typeOptions = [
|
|
@@ -195,5 +196,70 @@ export const Types = {
|
|
|
195
196
|
}, t))
|
|
196
197
|
})
|
|
197
198
|
};
|
|
199
|
+
export const WithIcons = {
|
|
200
|
+
render: (args)=>/*#__PURE__*/ _jsxs("div", {
|
|
201
|
+
className: "flex flex-col gap-24 w-full max-w-400",
|
|
202
|
+
children: [
|
|
203
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
204
|
+
className: "flex flex-col gap-8",
|
|
205
|
+
children: [
|
|
206
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
207
|
+
variant: "label",
|
|
208
|
+
className: "text-foreground-neutral-subtle",
|
|
209
|
+
children: "Left Icon"
|
|
210
|
+
}),
|
|
211
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
212
|
+
...args,
|
|
213
|
+
placeholder: "Search...",
|
|
214
|
+
iconLeft: /*#__PURE__*/ _jsx(Icon, {
|
|
215
|
+
name: "searchLine",
|
|
216
|
+
className: "size-16 text-foreground-neutral-muted"
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
]
|
|
220
|
+
}),
|
|
221
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
222
|
+
className: "flex flex-col gap-8",
|
|
223
|
+
children: [
|
|
224
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
225
|
+
variant: "label",
|
|
226
|
+
className: "text-foreground-neutral-subtle",
|
|
227
|
+
children: "Right Icon"
|
|
228
|
+
}),
|
|
229
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
230
|
+
...args,
|
|
231
|
+
placeholder: "Enter email",
|
|
232
|
+
iconRight: /*#__PURE__*/ _jsx(Icon, {
|
|
233
|
+
name: "mailLine",
|
|
234
|
+
className: "size-16 text-foreground-neutral-muted"
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
]
|
|
238
|
+
}),
|
|
239
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
240
|
+
className: "flex flex-col gap-8",
|
|
241
|
+
children: [
|
|
242
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
243
|
+
variant: "label",
|
|
244
|
+
className: "text-foreground-neutral-subtle",
|
|
245
|
+
children: "Both Icons"
|
|
246
|
+
}),
|
|
247
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
248
|
+
...args,
|
|
249
|
+
placeholder: "Search users...",
|
|
250
|
+
iconLeft: /*#__PURE__*/ _jsx(Icon, {
|
|
251
|
+
name: "searchLine",
|
|
252
|
+
className: "size-16 text-foreground-neutral-muted"
|
|
253
|
+
}),
|
|
254
|
+
iconRight: /*#__PURE__*/ _jsx(Icon, {
|
|
255
|
+
name: "userLine",
|
|
256
|
+
className: "size-16 text-foreground-neutral-muted"
|
|
257
|
+
})
|
|
258
|
+
})
|
|
259
|
+
]
|
|
260
|
+
})
|
|
261
|
+
]
|
|
262
|
+
})
|
|
263
|
+
};
|
|
198
264
|
|
|
199
265
|
//# sourceMappingURL=input.stories.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
declare function ScrollArea({ className, children, ...props }: ComponentProps<typeof ScrollAreaPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
declare function ScrollBar({ className, orientation, ...props }: ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export { ScrollArea, ScrollBar };
|
|
6
|
+
//# sourceMappingURL=scroll-area.d.ts.map
|