@dxos/react-ui 0.3.7-main.c3c2c7d → 0.3.7-main.d721c9c
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/lib/browser/index.mjs +338 -442
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/Input/Input.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/package.json +6 -7
- package/src/components/Input/Input.tsx +0 -1
- package/src/components/Select/Select.tsx +1 -3
- package/src/components/index.ts +0 -1
- package/dist/types/src/components/ComboBox/ComboBox.d.ts +0 -49
- package/dist/types/src/components/ComboBox/ComboBox.d.ts.map +0 -1
- package/dist/types/src/components/ComboBox/ComboBox.stories.d.ts +0 -25
- package/dist/types/src/components/ComboBox/ComboBox.stories.d.ts.map +0 -1
- package/dist/types/src/components/ComboBox/index.d.ts +0 -2
- package/dist/types/src/components/ComboBox/index.d.ts.map +0 -1
- package/src/components/ComboBox/ComboBox.stories.tsx +0 -82
- package/src/components/ComboBox/ComboBox.tsx +0 -218
- package/src/components/ComboBox/index.ts +0 -5
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import '@dxosTheme';
|
|
6
|
-
|
|
7
|
-
import { faker } from '@faker-js/faker';
|
|
8
|
-
import React, { type FC, useEffect, useState } from 'react';
|
|
9
|
-
|
|
10
|
-
import { ComboBox, type ComboBoxItem } from './ComboBox';
|
|
11
|
-
|
|
12
|
-
type TestItem = { id: string; text: string };
|
|
13
|
-
|
|
14
|
-
const data: TestItem[] = faker.helpers
|
|
15
|
-
.uniqueArray(faker.definitions.animal.fish, 100)
|
|
16
|
-
.sort()
|
|
17
|
-
.map((text) => ({
|
|
18
|
-
id: faker.string.uuid(),
|
|
19
|
-
text,
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
const ComboBoxStory: FC<{ data: TestItem[] }> = ({ data = [] }) => {
|
|
23
|
-
const [filter, setFilter] = useState<string>();
|
|
24
|
-
const [items, setItems] = useState<ComboBoxItem[]>([]);
|
|
25
|
-
const [selected, setSelected] = useState<ComboBoxItem>();
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
setItems(() =>
|
|
28
|
-
filter?.length
|
|
29
|
-
? data
|
|
30
|
-
.filter((item) => item.text?.length && item.text?.toLowerCase().includes(filter.toLowerCase()))
|
|
31
|
-
.map((item) => ({ id: item.id, label: item.text, data: item }))
|
|
32
|
-
: [],
|
|
33
|
-
);
|
|
34
|
-
}, [filter]);
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<div className='flex flex-col w-full bg-neutral-100 dark:bg-neutral-800'>
|
|
38
|
-
<ComboBox.Root items={items} onChange={setSelected} onInputChange={setFilter}>
|
|
39
|
-
<ComboBox.Input placeholder={'Select...'} />
|
|
40
|
-
<ComboBox.Content>
|
|
41
|
-
{items?.map((item) => (
|
|
42
|
-
<ComboBox.Item key={item.id} item={item}>
|
|
43
|
-
{item.label}
|
|
44
|
-
</ComboBox.Item>
|
|
45
|
-
))}
|
|
46
|
-
</ComboBox.Content>
|
|
47
|
-
</ComboBox.Root>
|
|
48
|
-
|
|
49
|
-
<div className='mt-16 p-2 font-mono text-xs truncate'>
|
|
50
|
-
<div>{selected?.label}</div>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export default {
|
|
57
|
-
component: ComboBoxStory,
|
|
58
|
-
decorators: [
|
|
59
|
-
(Story: any) => (
|
|
60
|
-
<div className='flex flex-col items-center h-screen w-full overflow-hidden'>
|
|
61
|
-
<div className='flex w-60 m-8 bg-white'>
|
|
62
|
-
<Story />
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
),
|
|
66
|
-
],
|
|
67
|
-
parameters: {
|
|
68
|
-
layout: 'fullscreen',
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// TODO(burdon): Test controlled and uncontrolled.
|
|
73
|
-
|
|
74
|
-
export const Default = {
|
|
75
|
-
args: {
|
|
76
|
-
data,
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const Empty = {
|
|
81
|
-
args: {},
|
|
82
|
-
};
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { CaretDown, CaretUp } from '@phosphor-icons/react';
|
|
6
|
-
import { createContextScope, type Scope } from '@radix-ui/react-context';
|
|
7
|
-
import { createPopperScope } from '@radix-ui/react-popper';
|
|
8
|
-
import * as PopperPrimitive from '@radix-ui/react-popper';
|
|
9
|
-
import { useCombobox, type UseComboboxReturnValue } from 'downshift';
|
|
10
|
-
import React, { forwardRef, type PropsWithChildren } from 'react';
|
|
11
|
-
|
|
12
|
-
import { useThemeContext } from '../../hooks';
|
|
13
|
-
import { type ThemedClassName } from '../../util';
|
|
14
|
-
import { Button } from '../Buttons';
|
|
15
|
-
import { Input } from '../Input';
|
|
16
|
-
|
|
17
|
-
const COMBOBOX_NAME = 'ComboBox';
|
|
18
|
-
|
|
19
|
-
type ScopedProps<P> = P & { __scopeComboBox?: Scope };
|
|
20
|
-
|
|
21
|
-
type ComboBoxItem = {
|
|
22
|
-
id: string;
|
|
23
|
-
label: string;
|
|
24
|
-
data?: any;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type ComboBoxContextValue = {
|
|
28
|
-
items: ComboBoxItem[];
|
|
29
|
-
} & UseComboboxReturnValue<ComboBoxItem>;
|
|
30
|
-
|
|
31
|
-
const usePopperScope = createPopperScope();
|
|
32
|
-
const [createComboBoxContext] = createContextScope(COMBOBOX_NAME, [createPopperScope]);
|
|
33
|
-
const [ComboBoxProvider, useComboBoxContext] = createComboBoxContext<ComboBoxContextValue>(COMBOBOX_NAME);
|
|
34
|
-
|
|
35
|
-
type ComboBoxRootProps = ThemedClassName<
|
|
36
|
-
ScopedProps<
|
|
37
|
-
PropsWithChildren<{
|
|
38
|
-
items?: ComboBoxItem[];
|
|
39
|
-
value?: ComboBoxItem;
|
|
40
|
-
onChange?: (selected: ComboBoxItem | undefined) => void;
|
|
41
|
-
onInputChange?: (text?: string) => void;
|
|
42
|
-
}>
|
|
43
|
-
>
|
|
44
|
-
>;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Type-ahead combobox.
|
|
48
|
-
*/
|
|
49
|
-
const ComboBoxRoot = ({
|
|
50
|
-
__scopeComboBox,
|
|
51
|
-
children,
|
|
52
|
-
classNames,
|
|
53
|
-
items = [],
|
|
54
|
-
value,
|
|
55
|
-
onChange,
|
|
56
|
-
onInputChange,
|
|
57
|
-
}: ComboBoxRootProps) => {
|
|
58
|
-
const { tx } = useThemeContext();
|
|
59
|
-
const popperScope = usePopperScope(__scopeComboBox);
|
|
60
|
-
|
|
61
|
-
// TODO(burdon): Remove and implement natively?
|
|
62
|
-
// https://www.downshift-js.com/use-combobox
|
|
63
|
-
const comboProps = useCombobox<ComboBoxItem>({
|
|
64
|
-
items,
|
|
65
|
-
itemToString: (selectedItem) => selectedItem?.label ?? '',
|
|
66
|
-
onInputValueChange: ({ inputValue }) => onInputChange?.(inputValue),
|
|
67
|
-
selectedItem: value ?? null,
|
|
68
|
-
onSelectedItemChange: ({ selectedItem }) => onChange?.(selectedItem === null ? undefined : selectedItem),
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<ComboBoxProvider scope={__scopeComboBox} items={items} {...comboProps}>
|
|
73
|
-
<PopperPrimitive.Root {...popperScope}>
|
|
74
|
-
<div className={tx('combobox.root', 'combobox__root', {}, classNames)}>{children}</div>
|
|
75
|
-
</PopperPrimitive.Root>
|
|
76
|
-
</ComboBoxProvider>
|
|
77
|
-
);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
// Input
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
const INPUT_NAME = 'ComboBoxInput';
|
|
85
|
-
|
|
86
|
-
type ComboBoxInputProps = ThemedClassName<
|
|
87
|
-
ScopedProps<
|
|
88
|
-
PropsWithChildren<{
|
|
89
|
-
placeholder?: string;
|
|
90
|
-
}>
|
|
91
|
-
>
|
|
92
|
-
>;
|
|
93
|
-
|
|
94
|
-
const ComboBoxInput = forwardRef<HTMLDivElement, ComboBoxInputProps>(
|
|
95
|
-
({ __scopeComboBox, classNames, placeholder }: ComboBoxInputProps, forwardedRef) => {
|
|
96
|
-
const { tx } = useThemeContext();
|
|
97
|
-
const popperScope = usePopperScope(__scopeComboBox);
|
|
98
|
-
const { getInputProps, getToggleButtonProps, isOpen } = useComboBoxContext(INPUT_NAME, __scopeComboBox);
|
|
99
|
-
|
|
100
|
-
// TODO(burdon): Break out input and button.
|
|
101
|
-
return (
|
|
102
|
-
<PopperPrimitive.Anchor asChild {...popperScope} ref={forwardedRef}>
|
|
103
|
-
{/* TODO(burdon): Move class to theme. */}
|
|
104
|
-
<div role='none' className='flex items-center gap-1'>
|
|
105
|
-
<Input.Root>
|
|
106
|
-
<Input.TextInput
|
|
107
|
-
{...getInputProps()}
|
|
108
|
-
placeholder={placeholder}
|
|
109
|
-
variant='subdued'
|
|
110
|
-
classNames={tx('combobox.input', 'combobox__input', {}, classNames)}
|
|
111
|
-
/>
|
|
112
|
-
</Input.Root>
|
|
113
|
-
<Button
|
|
114
|
-
{...getToggleButtonProps()}
|
|
115
|
-
aria-label='toggle menu'
|
|
116
|
-
variant='ghost'
|
|
117
|
-
classNames={tx('combobox.button', 'combobox__button')}
|
|
118
|
-
>
|
|
119
|
-
{(isOpen && <CaretUp />) || <CaretDown />}
|
|
120
|
-
</Button>
|
|
121
|
-
</div>
|
|
122
|
-
</PopperPrimitive.Anchor>
|
|
123
|
-
);
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
//
|
|
128
|
-
// Content
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
const CONTENT_NAME = 'ComboBoxContent';
|
|
132
|
-
|
|
133
|
-
type ComboBoxContentProps = ThemedClassName<ScopedProps<PropsWithChildren<{}>>>;
|
|
134
|
-
|
|
135
|
-
const ComboBoxContent = forwardRef<HTMLDivElement, ComboBoxContentProps>(
|
|
136
|
-
({ __scopeComboBox, classNames, children }: ComboBoxContentProps, forwardedRef) => {
|
|
137
|
-
const { tx } = useThemeContext();
|
|
138
|
-
const popperScope = usePopperScope(__scopeComboBox);
|
|
139
|
-
const { getMenuProps, isOpen } = useComboBoxContext(CONTENT_NAME, __scopeComboBox);
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<PopperPrimitive.Content
|
|
143
|
-
data-state={isOpen}
|
|
144
|
-
role='dialog'
|
|
145
|
-
{...popperScope}
|
|
146
|
-
ref={forwardedRef}
|
|
147
|
-
style={
|
|
148
|
-
{
|
|
149
|
-
// Re-namespace exposed content custom properties.
|
|
150
|
-
...{
|
|
151
|
-
'--radix-combobox-content-transform-origin': 'var(--radix-popper-transform-origin)',
|
|
152
|
-
'--radix-combobox-content-available-width': 'var(--radix-popper-available-width)',
|
|
153
|
-
'--radix-combobox-content-available-height': 'var(--radix-popper-available-height)',
|
|
154
|
-
'--radix-combobox-trigger-width': 'var(--radix-popper-anchor-width)',
|
|
155
|
-
'--radix-combobox-trigger-height': 'var(--radix-popper-anchor-height)',
|
|
156
|
-
},
|
|
157
|
-
} as any // TODO(burdon): Why any?
|
|
158
|
-
}
|
|
159
|
-
>
|
|
160
|
-
<ul {...getMenuProps()} className={tx('combobox.content', 'combobox__content', {}, classNames)}>
|
|
161
|
-
{isOpen && children}
|
|
162
|
-
</ul>
|
|
163
|
-
</PopperPrimitive.Content>
|
|
164
|
-
);
|
|
165
|
-
},
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
// Item
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
const ITEM_NAME = 'ComboBoxItem';
|
|
173
|
-
|
|
174
|
-
type ComboBoxItemProps = ThemedClassName<
|
|
175
|
-
ScopedProps<
|
|
176
|
-
PropsWithChildren<{
|
|
177
|
-
item: ComboBoxItem;
|
|
178
|
-
}>
|
|
179
|
-
>
|
|
180
|
-
>;
|
|
181
|
-
|
|
182
|
-
const ComboBoxItem = forwardRef<HTMLLIElement, ComboBoxItemProps>(
|
|
183
|
-
({ __scopeComboBox, classNames, children, item }, forwardedRef) => {
|
|
184
|
-
const { tx } = useThemeContext();
|
|
185
|
-
const { getItemProps, items, selectedItem, highlightedIndex } = useComboBoxContext(ITEM_NAME, __scopeComboBox);
|
|
186
|
-
|
|
187
|
-
return (
|
|
188
|
-
<li
|
|
189
|
-
ref={forwardedRef}
|
|
190
|
-
data-selected={selectedItem?.id === item.id ? 'true' : undefined}
|
|
191
|
-
data-highlighted={
|
|
192
|
-
highlightedIndex !== undefined && items[highlightedIndex]?.id === item.id ? 'true' : undefined
|
|
193
|
-
}
|
|
194
|
-
className={tx('combobox.item', 'item', {}, classNames)}
|
|
195
|
-
{...getItemProps({ item })}
|
|
196
|
-
>
|
|
197
|
-
{children}
|
|
198
|
-
</li>
|
|
199
|
-
);
|
|
200
|
-
},
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// prettier-ignore
|
|
204
|
-
export const ComboBox = {
|
|
205
|
-
Root: ComboBoxRoot,
|
|
206
|
-
Input: ComboBoxInput,
|
|
207
|
-
Content: ComboBoxContent,
|
|
208
|
-
Item: ComboBoxItem
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
// prettier-ignore
|
|
212
|
-
export type {
|
|
213
|
-
ComboBoxItem,
|
|
214
|
-
ComboBoxRootProps,
|
|
215
|
-
ComboBoxInputProps,
|
|
216
|
-
ComboBoxContentProps,
|
|
217
|
-
ComboBoxItemProps
|
|
218
|
-
};
|