@dxos/react-ui-searchlist 0.8.4-main.a4bbb77 → 0.8.4-main.ae835ea

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.
Files changed (59) hide show
  1. package/dist/lib/browser/index.mjs +193 -216
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +193 -216
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/Combobox/Combobox.d.ts +44 -0
  8. package/dist/types/src/components/Combobox/Combobox.d.ts.map +1 -0
  9. package/dist/types/src/{composites/PopoverCombobox.stories.d.ts → components/Combobox/Combobox.stories.d.ts} +10 -1
  10. package/dist/types/src/components/Combobox/Combobox.stories.d.ts.map +1 -0
  11. package/dist/types/src/components/Combobox/index.d.ts +2 -0
  12. package/dist/types/src/components/Combobox/index.d.ts.map +1 -0
  13. package/dist/types/src/components/{Listbox.d.ts → Listbox/Listbox.d.ts} +6 -6
  14. package/dist/types/src/components/Listbox/Listbox.d.ts.map +1 -0
  15. package/dist/types/src/components/Listbox/Listbox.stories.d.ts +21 -0
  16. package/dist/types/src/components/Listbox/Listbox.stories.d.ts.map +1 -0
  17. package/dist/types/src/components/Listbox/index.d.ts +2 -0
  18. package/dist/types/src/components/Listbox/index.d.ts.map +1 -0
  19. package/dist/types/src/components/{SearchList.d.ts → SearchList/SearchList.d.ts} +5 -28
  20. package/dist/types/src/components/SearchList/SearchList.d.ts.map +1 -0
  21. package/dist/types/src/components/{SearchList.stories.d.ts → SearchList/SearchList.stories.d.ts} +9 -0
  22. package/dist/types/src/components/SearchList/SearchList.stories.d.ts.map +1 -0
  23. package/dist/types/src/components/SearchList/index.d.ts +2 -0
  24. package/dist/types/src/components/SearchList/index.d.ts.map +1 -0
  25. package/dist/types/src/components/index.d.ts +2 -1
  26. package/dist/types/src/components/index.d.ts.map +1 -1
  27. package/dist/types/src/index.d.ts +0 -1
  28. package/dist/types/src/index.d.ts.map +1 -1
  29. package/dist/types/src/translations.d.ts +3 -1
  30. package/dist/types/src/translations.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +9 -9
  33. package/src/components/Combobox/Combobox.stories.tsx +57 -0
  34. package/src/components/Combobox/Combobox.tsx +335 -0
  35. package/src/components/Combobox/index.ts +5 -0
  36. package/src/components/Listbox/Listbox.stories.tsx +53 -0
  37. package/src/components/{Listbox.tsx → Listbox/Listbox.tsx} +33 -9
  38. package/src/components/Listbox/index.ts +5 -0
  39. package/src/components/{SearchList.stories.tsx → SearchList/SearchList.stories.tsx} +17 -8
  40. package/src/components/SearchList/SearchList.tsx +163 -0
  41. package/src/components/SearchList/index.ts +5 -0
  42. package/src/components/index.ts +2 -1
  43. package/src/index.ts +0 -1
  44. package/src/translations.ts +3 -1
  45. package/dist/types/src/components/Listbox.d.ts.map +0 -1
  46. package/dist/types/src/components/Listbox.stories.d.ts +0 -16
  47. package/dist/types/src/components/Listbox.stories.d.ts.map +0 -1
  48. package/dist/types/src/components/SearchList.d.ts.map +0 -1
  49. package/dist/types/src/components/SearchList.stories.d.ts.map +0 -1
  50. package/dist/types/src/composites/PopoverCombobox.d.ts +0 -32
  51. package/dist/types/src/composites/PopoverCombobox.d.ts.map +0 -1
  52. package/dist/types/src/composites/PopoverCombobox.stories.d.ts.map +0 -1
  53. package/dist/types/src/composites/index.d.ts +0 -2
  54. package/dist/types/src/composites/index.d.ts.map +0 -1
  55. package/src/components/Listbox.stories.tsx +0 -73
  56. package/src/components/SearchList.tsx +0 -251
  57. package/src/composites/PopoverCombobox.stories.tsx +0 -47
  58. package/src/composites/PopoverCombobox.tsx +0 -209
  59. package/src/composites/index.ts +0 -5
@@ -0,0 +1,163 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { CommandEmpty, CommandInput, CommandItem, CommandList, CommandRoot } from 'cmdk';
6
+ import React, { type ComponentPropsWithRef, forwardRef } from 'react';
7
+
8
+ import {
9
+ type TextInputProps,
10
+ type ThemedClassName,
11
+ useDensityContext,
12
+ useElevationContext,
13
+ useThemeContext,
14
+ useTranslation,
15
+ } from '@dxos/react-ui';
16
+ import { mx } from '@dxos/react-ui-theme';
17
+
18
+ import { translationKey } from '../../translations';
19
+
20
+ const commandItem = 'flex items-center overflow-hidden';
21
+ const searchListItem =
22
+ 'plb-1 pli-2 rounded-sm select-none cursor-pointer data-[selected]:bg-hoverOverlay hover:bg-hoverOverlay';
23
+
24
+ const SEARCHLIST_NAME = 'SearchList';
25
+ const SEARCHLIST_ITEM_NAME = 'SearchListItem';
26
+
27
+ //
28
+ // Root
29
+ //
30
+
31
+ type SearchListVariant = 'list' | 'menu' | 'listbox';
32
+
33
+ type SearchListRootProps = ThemedClassName<ComponentPropsWithRef<typeof CommandRoot>> & {
34
+ variant?: SearchListVariant;
35
+ };
36
+
37
+ const SearchListRoot = forwardRef<HTMLDivElement, SearchListRootProps>(
38
+ ({ children, classNames, ...props }, forwardedRef) => {
39
+ return (
40
+ <CommandRoot {...props} className={mx(classNames)} ref={forwardedRef}>
41
+ {children}
42
+ </CommandRoot>
43
+ );
44
+ },
45
+ );
46
+
47
+ SearchListRoot.displayName = SEARCHLIST_NAME;
48
+
49
+ //
50
+ // Input
51
+ //
52
+
53
+ type CommandInputPrimitiveProps = ComponentPropsWithRef<typeof CommandInput>;
54
+
55
+ // TODO: Harmonize with other inputs’ `onChange` prop.
56
+ type SearchListInputProps = Omit<TextInputProps, 'value' | 'defaultValue' | 'onChange'> &
57
+ Pick<CommandInputPrimitiveProps, 'value' | 'defaultValue' | 'onValueChange'>;
58
+
59
+ const SearchListInput = forwardRef<HTMLInputElement, SearchListInputProps>(
60
+ ({ classNames, density: propsDensity, elevation: propsElevation, variant, ...props }, forwardedRef) => {
61
+ const { t } = useTranslation(translationKey);
62
+ const placeholder = props.placeholder ?? t('search.placeholder');
63
+
64
+ // TODO(thure): Keep this in-sync with `TextInput`, or submit a PR for `cmdk` to support `asChild` so we don’t have to.
65
+ const { hasIosKeyboard } = useThemeContext();
66
+ const { tx } = useThemeContext();
67
+ const density = useDensityContext(propsDensity);
68
+ const elevation = useElevationContext(propsElevation);
69
+
70
+ return (
71
+ <CommandInput
72
+ {...props}
73
+ placeholder={placeholder}
74
+ className={tx(
75
+ 'input.input',
76
+ 'input',
77
+ {
78
+ variant,
79
+ disabled: props.disabled,
80
+ density,
81
+ elevation,
82
+ },
83
+ 'mbe-cardSpacingBlock',
84
+ classNames,
85
+ )}
86
+ {...(props.autoFocus && !hasIosKeyboard && { autoFocus: true })}
87
+ ref={forwardedRef}
88
+ />
89
+ );
90
+ },
91
+ );
92
+
93
+ //
94
+ // Content
95
+ //
96
+
97
+ type SearchListContentProps = ThemedClassName<ComponentPropsWithRef<typeof CommandList>>;
98
+
99
+ const SearchListContent = forwardRef<HTMLDivElement, SearchListContentProps>(
100
+ ({ children, classNames, ...props }, forwardedRef) => {
101
+ return (
102
+ <CommandList {...props} className={mx(classNames)} ref={forwardedRef}>
103
+ {children}
104
+ </CommandList>
105
+ );
106
+ },
107
+ );
108
+
109
+ //
110
+ // Empty
111
+ //
112
+
113
+ type SearchListEmptyProps = ThemedClassName<ComponentPropsWithRef<typeof CommandEmpty>>;
114
+
115
+ const SearchListEmpty = forwardRef<HTMLDivElement, SearchListEmptyProps>(
116
+ ({ children, classNames, ...props }, forwardedRef) => {
117
+ return (
118
+ <CommandEmpty {...props} className={mx(classNames)} ref={forwardedRef}>
119
+ {children}
120
+ </CommandEmpty>
121
+ );
122
+ },
123
+ );
124
+
125
+ //
126
+ // Item
127
+ //
128
+
129
+ type SearchListItemProps = ThemedClassName<ComponentPropsWithRef<typeof CommandItem>>;
130
+
131
+ const SearchListItem = forwardRef<HTMLDivElement, SearchListItemProps>(
132
+ ({ children, classNames, ...props }, forwardedRef) => {
133
+ return (
134
+ <CommandItem {...props} className={mx(searchListItem, classNames)} ref={forwardedRef}>
135
+ {children}
136
+ </CommandItem>
137
+ );
138
+ },
139
+ );
140
+
141
+ SearchListItem.displayName = SEARCHLIST_ITEM_NAME;
142
+
143
+ //
144
+ // SearchList
145
+ //
146
+
147
+ export const SearchList = {
148
+ Root: SearchListRoot,
149
+ Input: SearchListInput,
150
+ Content: SearchListContent,
151
+ Empty: SearchListEmpty,
152
+ Item: SearchListItem,
153
+ };
154
+
155
+ export type {
156
+ SearchListRootProps,
157
+ SearchListInputProps,
158
+ SearchListContentProps,
159
+ SearchListEmptyProps,
160
+ SearchListItemProps,
161
+ };
162
+
163
+ export { commandItem, searchListItem };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export * from './SearchList';
@@ -2,5 +2,6 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './SearchList';
5
+ export * from './Combobox';
6
6
  export * from './Listbox';
7
+ export * from './SearchList';
package/src/index.ts CHANGED
@@ -3,5 +3,4 @@
3
3
  //
4
4
 
5
5
  export * from './components';
6
- export * from './composites';
7
6
  export * from './translations';
@@ -9,7 +9,9 @@ export const translationKey = 'react-ui-searchlist';
9
9
  export const translations = [
10
10
  {
11
11
  'en-US': {
12
- [translationKey]: {},
12
+ [translationKey]: {
13
+ 'search.placeholder': 'Search...',
14
+ },
13
15
  },
14
16
  },
15
17
  ] as const satisfies Resource[];
@@ -1 +0,0 @@
1
- {"version":3,"file":"Listbox.d.ts","sourceRoot":"","sources":["../../../../src/components/Listbox.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,KAAK,EAAsB,MAAM,yBAAyB,CAAC;AAEzE,OAAO,KAAK,EAAE,EAAE,KAAK,qBAAqB,EAA8C,MAAM,OAAO,CAAC;AAEtG,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAU5E,KAAK,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,cAAc,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAG5D,KAAK,gBAAgB,GAAG,eAAe,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,KAAK,kBAAkB,GAAG,eAAe,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG;IACvE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,QAAA,MAA6B,kBAAkB,+CAAwC,CAAC;AAKxF,KAAK,mBAAmB,GAAG;IACzB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAOF,QAAA,MAAwB,iBAAiB,8FAA2D,CAAC;AA0GrG,KAAK,2BAA2B,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAoB9F,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;AAEjD,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,16 +0,0 @@
1
- import { type StoryObj } from '@storybook/react-vite';
2
- import React from 'react';
3
- declare const DefaultStory: () => React.JSX.Element;
4
- declare const DefaultValueStory: () => React.JSX.Element;
5
- declare const meta: {
6
- title: string;
7
- component: React.ForwardRefExoticComponent<Omit<import("./Listbox").ListboxRootProps, "ref"> & React.RefAttributes<HTMLUListElement>>;
8
- decorators: import("@storybook/react").Decorator[];
9
- parameters: {
10
- layout: string;
11
- };
12
- };
13
- export default meta;
14
- export declare const Default: StoryObj<typeof DefaultStory>;
15
- export declare const DefaultValue: StoryObj<typeof DefaultValueStory>;
16
- //# sourceMappingURL=Listbox.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Listbox.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Listbox.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAmB,MAAM,OAAO,CAAC;AAMxC,QAAA,MAAM,YAAY,yBAqBjB,CAAC;AAEF,QAAA,MAAM,iBAAiB,yBAmBtB,CAAC;AAEF,QAAA,MAAM,IAAI;;;;;;;CAO2B,CAAC;AAEtC,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,OAAO,YAAY,CAEjD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,OAAO,iBAAiB,CAE3D,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SearchList.d.ts","sourceRoot":"","sources":["../../../../src/components/SearchList.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACzF,OAAO,KAAK,EAAE,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAA2B,MAAM,OAAO,CAAC;AAE3G,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,cAAc,EACnB,KAAK,eAAe,EAKrB,MAAM,gBAAgB,CAAC;AAGxB,KAAK,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,KAAK,mBAAmB,GAAG,eAAe,CAAC,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,GAAG;IACtF,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,UAAU,EAAE,IAAI,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AASF,KAAK,iBAAiB,GAAG,iBAAiB,CACxC,OAAO,CAAC,oBAAoB,GAAG;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CACpG,CAAC;AAcF,KAAK,0BAA0B,GAAG,qBAAqB,CAAC,OAAO,YAAY,CAAC,CAAC;AAG7E,KAAK,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC,GACrF,IAAI,CAAC,0BAA0B,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAAC,CAAC;AAgC/E,KAAK,sBAAsB,GAAG,eAAe,CAAC,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC;AAYzF,KAAK,oBAAoB,GAAG,eAAe,CAAC,qBAAqB,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC;AAYxF,KAAK,mBAAmB,GAAG,eAAe,CAAC,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC;AAEtF,QAAA,MAAM,WAAW,sCAAsC,CAAC;AACxD,QAAA,MAAM,cAAc,4GACuF,CAAC;AA8D5G,KAAK,oBAAoB,GAAG,WAAW,CAAC;AAuCxC,eAAO,MAAM,UAAU;;;;;;CAMtB,CAAC;AAEF,eAAO,MAAM,QAAQ;;+LA5ElB,iBAAiB;;;;;CAgFnB,CAAC;AAEF,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,GACrB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SearchList.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/SearchList.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAUzC,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC;AAiBF,QAAA,MAAM,IAAI;;eAEsB,GAAG;wBAjBa,UAAU;;CAoBrB,CAAC;AAEtC,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
@@ -1,32 +0,0 @@
1
- import React from 'react';
2
- import { type PopoverArrowProps, type PopoverContentProps, type PopoverVirtualTriggerProps } from '@dxos/react-ui';
3
- import { type ComboboxRootProps, type ComboboxTriggerProps, type SearchListContentProps, type SearchListEmptyProps, type SearchListInputProps, type SearchListItemProps, type SearchListRootProps } from '../components';
4
- type PopoverComboboxRootProps = ComboboxRootProps & {
5
- modal?: boolean;
6
- };
7
- type PopoverComboboxContentProps = SearchListRootProps & PopoverContentProps;
8
- type PopoverComboboxTriggerProps = ComboboxTriggerProps;
9
- type PopoverComboboxVirtualTriggerProps = PopoverVirtualTriggerProps;
10
- type PopoverComboboxInputProps = SearchListInputProps;
11
- type PopoverComboboxListProps = SearchListContentProps;
12
- type PopoverComboboxItemProps = SearchListItemProps;
13
- type PopoverComboboxArrowProps = PopoverArrowProps;
14
- type PopoverComboboxEmptyProps = SearchListEmptyProps;
15
- export declare const PopoverCombobox: {
16
- Root: ({ modal, children, open: propsOpen, onOpenChange: propsOnOpenChange, defaultOpen, ...props }: PopoverComboboxRootProps) => React.JSX.Element;
17
- Content: React.ForwardRefExoticComponent<Omit<PopoverComboboxContentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
18
- Trigger: React.ForwardRefExoticComponent<Omit<import("@dxos/react-ui").ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
19
- VirtualTrigger: {
20
- (props: PopoverVirtualTriggerProps & {
21
- __scopePopover?: import("@radix-ui/react-context").Scope;
22
- }): React.JSX.Element;
23
- displayName: string;
24
- };
25
- Input: React.ForwardRefExoticComponent<Omit<SearchListInputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
26
- List: React.ForwardRefExoticComponent<Omit<SearchListContentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
27
- Item: React.ForwardRefExoticComponent<Omit<SearchListItemProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
28
- Arrow: React.ForwardRefExoticComponent<PopoverArrowProps & React.RefAttributes<SVGSVGElement>>;
29
- Empty: React.ForwardRefExoticComponent<Omit<SearchListEmptyProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
30
- };
31
- export type { PopoverComboboxRootProps, PopoverComboboxContentProps, PopoverComboboxTriggerProps, PopoverComboboxVirtualTriggerProps, PopoverComboboxInputProps, PopoverComboboxListProps, PopoverComboboxItemProps, PopoverComboboxArrowProps, PopoverComboboxEmptyProps, };
32
- //# sourceMappingURL=PopoverCombobox.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PopoverCombobox.d.ts","sourceRoot":"","sources":["../../../../src/composites/PopoverCombobox.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AAEvB,KAAK,wBAAwB,GAAG,iBAAiB,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAwBxE,KAAK,2BAA2B,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAqE7E,KAAK,2BAA2B,GAAG,oBAAoB,CAAC;AAUxD,KAAK,kCAAkC,GAAG,0BAA0B,CAAC;AAIrE,KAAK,yBAAyB,GAAG,oBAAoB,CAAC;AAiBtD,KAAK,wBAAwB,GAAG,sBAAsB,CAAC;AAcvD,KAAK,wBAAwB,GAAG,mBAAmB,CAAC;AAcpD,KAAK,yBAAyB,GAAG,iBAAiB,CAAC;AAInD,KAAK,yBAAyB,GAAG,oBAAoB,CAAC;AAItD,eAAO,MAAM,eAAe;yGAvJzB,wBAAwB;;;;;;;;;;;;;;CAiK1B,CAAC;AAEF,YAAY,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,2BAA2B,EAC3B,kCAAkC,EAClC,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,GAC1B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PopoverCombobox.stories.d.ts","sourceRoot":"","sources":["../../../../src/composites/PopoverCombobox.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,MAAM,OAAO,CAAC;AA4B1B,QAAA,MAAM,IAAI;;eAE2B,GAAG;;;CAGH,CAAC;AAEtC,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
@@ -1,2 +0,0 @@
1
- export * from './PopoverCombobox';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/composites/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC"}
@@ -1,73 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useState } from 'react';
7
-
8
- import { withTheme } from '@dxos/react-ui/testing';
9
-
10
- import { Listbox } from './Listbox';
11
-
12
- const DefaultStory = () => {
13
- const [selectedValue, setSelectedValue] = useState<string>('option-2');
14
-
15
- const options = [
16
- { value: 'option-1', label: 'First Option' },
17
- { value: 'option-2', label: 'Second Option' },
18
- { value: 'option-3', label: 'Third Option' },
19
- ];
20
-
21
- return (
22
- <div className='w-64'>
23
- <Listbox.Root value={selectedValue} onValueChange={setSelectedValue}>
24
- {options.map((option) => (
25
- <Listbox.Option key={option.value} value={option.value}>
26
- <Listbox.OptionLabel>{option.label}</Listbox.OptionLabel>
27
- <Listbox.OptionIndicator />
28
- </Listbox.Option>
29
- ))}
30
- </Listbox.Root>
31
- </div>
32
- );
33
- };
34
-
35
- const DefaultValueStory = () => {
36
- const options = [
37
- { value: 'apple', label: 'Apple' },
38
- { value: 'banana', label: 'Banana' },
39
- { value: 'cherry', label: 'Cherry' },
40
- ];
41
-
42
- return (
43
- <div className='w-64'>
44
- <Listbox.Root defaultValue='banana'>
45
- {options.map((option) => (
46
- <Listbox.Option key={option.value} value={option.value}>
47
- <Listbox.OptionLabel>{option.label}</Listbox.OptionLabel>
48
- <Listbox.OptionIndicator />
49
- </Listbox.Option>
50
- ))}
51
- </Listbox.Root>
52
- </div>
53
- );
54
- };
55
-
56
- const meta = {
57
- title: 'ui/react-ui-searchlist/Listbox',
58
- component: Listbox.Root,
59
- decorators: [withTheme],
60
- parameters: {
61
- layout: 'fullscreen',
62
- },
63
- } satisfies Meta<typeof Listbox.Root>;
64
-
65
- export default meta;
66
-
67
- export const Default: StoryObj<typeof DefaultStory> = {
68
- render: DefaultStory,
69
- };
70
-
71
- export const DefaultValue: StoryObj<typeof DefaultValueStory> = {
72
- render: DefaultValueStory,
73
- };
@@ -1,251 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { createContext } from '@radix-ui/react-context';
6
- import { useControllableState } from '@radix-ui/react-use-controllable-state';
7
- import { CommandEmpty, CommandInput, CommandItem, CommandList, CommandRoot } from 'cmdk';
8
- import React, { type ComponentPropsWithRef, type PropsWithChildren, forwardRef, useCallback } from 'react';
9
-
10
- import {
11
- Button,
12
- type ButtonProps,
13
- Icon,
14
- type TextInputProps,
15
- type ThemedClassName,
16
- useDensityContext,
17
- useElevationContext,
18
- useId,
19
- useThemeContext,
20
- } from '@dxos/react-ui';
21
- import { mx, staticPlaceholderText } from '@dxos/react-ui-theme';
22
-
23
- type SearchListVariant = 'list' | 'menu' | 'listbox';
24
-
25
- type SearchListRootProps = ThemedClassName<ComponentPropsWithRef<typeof CommandRoot>> & {
26
- variant?: SearchListVariant;
27
- };
28
-
29
- type ComboboxContextValue = {
30
- isCombobox: true;
31
- modalId: string;
32
- open: boolean;
33
- onOpenChange: (nextOpen: boolean) => void;
34
- value: string;
35
- onValueChange: (nextValue: string) => void;
36
- placeholder?: string;
37
- };
38
-
39
- const COMBOBOX_NAME = 'Combobox';
40
- const COMBOBOX_TRIGGER_NAME = 'ComboboxTrigger';
41
- const SEARCHLIST_NAME = 'SearchList';
42
- const SEARCHLIST_ITEM_NAME = 'SearchListItem';
43
-
44
- const [ComboboxProvider, useComboboxContext] = createContext<Partial<ComboboxContextValue>>(COMBOBOX_NAME, {});
45
-
46
- type ComboboxRootProps = PropsWithChildren<
47
- Partial<ComboboxContextValue & { defaultOpen: boolean; defaultValue: string; placeholder: string }>
48
- >;
49
-
50
- const SearchListRoot = forwardRef<HTMLDivElement, SearchListRootProps>(
51
- ({ children, classNames, ...props }, forwardedRef) => {
52
- return (
53
- <CommandRoot {...props} className={mx('', classNames)} ref={forwardedRef}>
54
- {children}
55
- </CommandRoot>
56
- );
57
- },
58
- );
59
-
60
- SearchListRoot.displayName = SEARCHLIST_NAME;
61
-
62
- type CommandInputPrimitiveProps = ComponentPropsWithRef<typeof CommandInput>;
63
-
64
- // TODO: Harmonize with other inputs’ `onChange` prop.
65
- type SearchListInputProps = Omit<TextInputProps, 'value' | 'defaultValue' | 'onChange'> &
66
- Pick<CommandInputPrimitiveProps, 'value' | 'defaultValue' | 'onValueChange'>;
67
-
68
- const SearchListInput = forwardRef<HTMLInputElement, SearchListInputProps>(
69
- ({ classNames, density: propsDensity, elevation: propsElevation, variant, ...props }, forwardedRef) => {
70
- // CHORE(thure): Keep this in-sync with `TextInput`, or submit a PR for `cmdk` to support `asChild` so we don’t have to.
71
- const { hasIosKeyboard } = useThemeContext();
72
- const { tx } = useThemeContext();
73
- const density = useDensityContext(propsDensity);
74
- const elevation = useElevationContext(propsElevation);
75
-
76
- return (
77
- <CommandInput
78
- {...props}
79
- className={tx(
80
- 'input.input',
81
- 'input',
82
- {
83
- variant,
84
- disabled: props.disabled,
85
- density,
86
- elevation,
87
- },
88
- 'mbe-cardSpacingBlock',
89
- classNames,
90
- )}
91
- {...(props.autoFocus && !hasIosKeyboard && { autoFocus: true })}
92
- ref={forwardedRef}
93
- />
94
- );
95
- },
96
- );
97
-
98
- type SearchListContentProps = ThemedClassName<ComponentPropsWithRef<typeof CommandList>>;
99
-
100
- const SearchListContent = forwardRef<HTMLDivElement, SearchListContentProps>(
101
- ({ children, classNames, ...props }, forwardedRef) => {
102
- return (
103
- <CommandList {...props} className={mx(classNames)} ref={forwardedRef}>
104
- {children}
105
- </CommandList>
106
- );
107
- },
108
- );
109
-
110
- type SearchListEmptyProps = ThemedClassName<ComponentPropsWithRef<typeof CommandEmpty>>;
111
-
112
- const SearchListEmpty = forwardRef<HTMLDivElement, SearchListEmptyProps>(
113
- ({ children, classNames, ...props }, forwardedRef) => {
114
- return (
115
- <CommandEmpty {...props} className={mx(classNames)} ref={forwardedRef}>
116
- {children}
117
- </CommandEmpty>
118
- );
119
- },
120
- );
121
-
122
- type SearchListItemProps = ThemedClassName<ComponentPropsWithRef<typeof CommandItem>>;
123
-
124
- const commandItem = 'flex items-center overflow-hidden';
125
- const searchListItem =
126
- 'plb-1 pli-2 rounded-sm select-none cursor-pointer data-[selected]:bg-hoverOverlay hover:bg-hoverOverlay';
127
-
128
- const SearchListItem = forwardRef<HTMLDivElement, SearchListItemProps>(
129
- ({ children, classNames, onSelect, ...props }, forwardedRef) => {
130
- const { onValueChange, onOpenChange } = useComboboxContext(SEARCHLIST_ITEM_NAME);
131
- const handleSelect = useCallback(
132
- (nextValue: string) => {
133
- onValueChange?.(nextValue);
134
- onOpenChange?.(false);
135
- onSelect?.(nextValue);
136
- },
137
- [onValueChange, onOpenChange, onSelect],
138
- );
139
- return (
140
- <CommandItem {...props} onSelect={handleSelect} className={mx(searchListItem, classNames)} ref={forwardedRef}>
141
- {children}
142
- </CommandItem>
143
- );
144
- },
145
- );
146
-
147
- SearchListItem.displayName = SEARCHLIST_ITEM_NAME;
148
-
149
- const ComboboxRoot = ({
150
- modalId: propsModalId,
151
- open: propsOpen,
152
- defaultOpen,
153
- onOpenChange: propsOnOpenChange,
154
- value: propsValue,
155
- defaultValue,
156
- onValueChange: propsOnValueChange,
157
- placeholder,
158
- children,
159
- }: ComboboxRootProps) => {
160
- const modalId = useId(COMBOBOX_NAME, propsModalId);
161
- const [open = false, onOpenChange] = useControllableState({
162
- prop: propsOpen,
163
- onChange: propsOnOpenChange,
164
- defaultProp: defaultOpen,
165
- });
166
- const [value = '', onValueChange] = useControllableState({
167
- prop: propsValue,
168
- onChange: propsOnValueChange,
169
- defaultProp: defaultValue,
170
- });
171
- return (
172
- <ComboboxProvider
173
- isCombobox
174
- modalId={modalId}
175
- open={open}
176
- onOpenChange={onOpenChange}
177
- value={value}
178
- onValueChange={onValueChange}
179
- placeholder={placeholder}
180
- >
181
- {children}
182
- </ComboboxProvider>
183
- );
184
- };
185
-
186
- ComboboxRoot.displayName = COMBOBOX_NAME;
187
-
188
- type ComboboxTriggerProps = ButtonProps;
189
-
190
- const ComboboxTrigger = forwardRef<HTMLButtonElement, ComboboxTriggerProps>(
191
- ({ children, onClick, ...props }, forwardedRef) => {
192
- const { modalId, open, onOpenChange, placeholder, value } = useComboboxContext(COMBOBOX_TRIGGER_NAME);
193
- const handleClick = useCallback(
194
- (event: Parameters<Exclude<ButtonProps['onClick'], undefined>>[0]) => {
195
- onClick?.(event);
196
- onOpenChange?.(true);
197
- },
198
- [onClick, onOpenChange],
199
- );
200
- return (
201
- <Button
202
- {...props}
203
- role='combobox'
204
- aria-expanded={open}
205
- aria-controls={modalId}
206
- aria-haspopup='dialog'
207
- onClick={handleClick}
208
- ref={forwardedRef}
209
- >
210
- {children ?? (
211
- <>
212
- <span
213
- className={mx('font-normal text-start flex-1 min-is-0 truncate mie-2', !value && staticPlaceholderText)}
214
- >
215
- {value || placeholder}
216
- </span>
217
- <Icon icon='ph--caret-down--bold' size={3} />
218
- </>
219
- )}
220
- </Button>
221
- );
222
- },
223
- );
224
-
225
- ComboboxTrigger.displayName = COMBOBOX_TRIGGER_NAME;
226
-
227
- export const SearchList = {
228
- Root: SearchListRoot,
229
- Input: SearchListInput,
230
- Content: SearchListContent,
231
- Empty: SearchListEmpty,
232
- Item: SearchListItem,
233
- };
234
-
235
- export const Combobox = {
236
- Root: ComboboxRoot,
237
- Trigger: ComboboxTrigger,
238
- useComboboxContext,
239
- };
240
-
241
- export type {
242
- SearchListRootProps,
243
- SearchListInputProps,
244
- SearchListContentProps,
245
- SearchListEmptyProps,
246
- SearchListItemProps,
247
- ComboboxRootProps,
248
- ComboboxTriggerProps,
249
- };
250
-
251
- export { commandItem, searchListItem };
@@ -1,47 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React from 'react';
7
-
8
- import { faker } from '@dxos/random';
9
- import { withTheme } from '@dxos/react-ui/testing';
10
-
11
- import { PopoverCombobox } from './PopoverCombobox';
12
-
13
- faker.seed(1234);
14
-
15
- const storybookItems = faker.helpers.uniqueArray(faker.commerce.productName, 16);
16
-
17
- const DefaultStory = () => {
18
- return (
19
- <PopoverCombobox.Root placeholder='Nothing selected'>
20
- <PopoverCombobox.Trigger />
21
- <PopoverCombobox.Content filter={(value, search) => (value.includes(search) ? 1 : 0)}>
22
- <PopoverCombobox.Input placeholder='Search...' />
23
- <PopoverCombobox.List>
24
- {storybookItems.map((value) => (
25
- <PopoverCombobox.Item key={value}>{value}</PopoverCombobox.Item>
26
- ))}
27
- </PopoverCombobox.List>
28
- <PopoverCombobox.Arrow />
29
- </PopoverCombobox.Content>
30
- </PopoverCombobox.Root>
31
- );
32
- };
33
-
34
- const meta = {
35
- title: 'ui/react-ui-searchlist/PopoverCombobox',
36
- component: PopoverCombobox.Root as any,
37
- render: DefaultStory,
38
- decorators: [withTheme],
39
- } satisfies Meta<typeof DefaultStory>;
40
-
41
- export default meta;
42
-
43
- type Story = StoryObj<typeof meta>;
44
-
45
- export const Default: Story = {
46
- args: {},
47
- };