@sproutsocial/seeds-react-menu 1.12.2 → 1.13.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/.turbo/turbo-build.log +13 -13
- package/CHANGELOG.md +16 -0
- package/dist/esm/v3/index.js +517 -58
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/index.d.mts +22 -22
- package/dist/index.d.ts +22 -22
- package/dist/v3/index.d.mts +160 -50
- package/dist/v3/index.d.ts +160 -50
- package/dist/v3/index.js +522 -57
- package/dist/v3/index.js.map +1 -1
- package/package.json +1 -1
- package/src/v3/ActionMenu.stories.tsx +260 -0
- package/src/v3/ActionMenu.tsx +345 -0
- package/src/v3/ActionMenuStyles.tsx +153 -0
- package/src/v3/Common/SelectStyles.tsx +4 -3
- package/src/v3/ModalStories.stories.tsx +159 -0
- package/src/v3/MultiCombobox.stories.tsx +17 -0
- package/src/v3/MultiCombobox.tsx +24 -13
- package/src/v3/MultiSearchableSelect.stories.tsx +18 -0
- package/src/v3/MultiSearchableSelect.tsx +214 -55
- package/src/v3/MultiSelect.stories.tsx +17 -0
- package/src/v3/MultiSelect.tsx +3 -2
- package/src/v3/SingleCombobox.stories.tsx +17 -0
- package/src/v3/SingleCombobox.tsx +3 -1
- package/src/v3/SingleSearchableSelect.stories.tsx +18 -0
- package/src/v3/SingleSearchableSelect.tsx +3 -1
- package/src/v3/SingleSelect.stories.tsx +17 -0
- package/src/v3/SingleSelect.tsx +3 -2
- package/src/v3/index.ts +1 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Menu } from "@base-ui/react/menu";
|
|
2
|
+
import styled, { css } from "styled-components";
|
|
3
|
+
import { focusRing } from "@sproutsocial/seeds-react-mixins";
|
|
4
|
+
|
|
5
|
+
export const ActionMenuTrigger = styled(Menu.Trigger)``;
|
|
6
|
+
|
|
7
|
+
export const ActionMenuPositioner = styled(Menu.Positioner)`
|
|
8
|
+
min-width: var(--anchor-width);
|
|
9
|
+
z-index: 7;
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const ActionMenuPopup = styled(Menu.Popup)`
|
|
13
|
+
font-family: ${({ theme }) => theme.fontFamily};
|
|
14
|
+
background: ${({ theme }) => theme.colors.container.background.base};
|
|
15
|
+
border: 1px solid ${({ theme }) => theme.colors.container.border.base};
|
|
16
|
+
border-radius: ${({ theme }) => theme.radii[500]};
|
|
17
|
+
box-shadow: ${({ theme }) => theme.shadows.low};
|
|
18
|
+
outline: none;
|
|
19
|
+
max-height: min(var(--base-ui-available-height, 400px), 400px);
|
|
20
|
+
overflow-y: auto;
|
|
21
|
+
padding: ${({ theme }) => theme.space[200]};
|
|
22
|
+
|
|
23
|
+
&[data-open] {
|
|
24
|
+
animation: action-menu-popup-in 120ms ease-out;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&[data-closed] {
|
|
28
|
+
animation: action-menu-popup-out 100ms ease-in;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes action-menu-popup-in {
|
|
32
|
+
from {
|
|
33
|
+
opacity: 0;
|
|
34
|
+
transform: scale(0.95);
|
|
35
|
+
}
|
|
36
|
+
to {
|
|
37
|
+
opacity: 1;
|
|
38
|
+
transform: scale(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@keyframes action-menu-popup-out {
|
|
43
|
+
from {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
transform: scale(1);
|
|
46
|
+
}
|
|
47
|
+
to {
|
|
48
|
+
opacity: 0;
|
|
49
|
+
transform: scale(0.95);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export const ActionMenuGroup = styled(Menu.Group)`
|
|
55
|
+
display: block;
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export const ActionMenuGroupLabel = styled(Menu.GroupLabel)`
|
|
59
|
+
padding: ${({ theme }) =>
|
|
60
|
+
`${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
|
|
61
|
+
font-size: ${({ theme }) => theme.typography[100].fontSize};
|
|
62
|
+
font-weight: ${({ theme }) => theme.fontWeights.semibold};
|
|
63
|
+
text-transform: uppercase;
|
|
64
|
+
letter-spacing: 0.05em;
|
|
65
|
+
color: ${({ theme }) => theme.colors.text.subtext};
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
export const ActionMenuSeparator = styled(Menu.Separator)`
|
|
69
|
+
height: 1px;
|
|
70
|
+
margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
|
|
71
|
+
background: ${({ theme }) => theme.colors.container.border.base};
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const menuItemStyles = css`
|
|
75
|
+
box-sizing: border-box;
|
|
76
|
+
display: block;
|
|
77
|
+
width: 100%;
|
|
78
|
+
border-radius: ${({ theme }) => theme.radii[500]};
|
|
79
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.base};
|
|
80
|
+
border: 1px solid ${({ theme }) => theme.colors.listItem.background.base};
|
|
81
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
82
|
+
font-family: ${({ theme }) => theme.fontFamily};
|
|
83
|
+
font-weight: ${({ theme }) => theme.fontWeights.normal};
|
|
84
|
+
text-align: left;
|
|
85
|
+
text-decoration: none;
|
|
86
|
+
padding: ${({ theme }) => theme.space[300]};
|
|
87
|
+
outline: 0;
|
|
88
|
+
${({ theme }) => theme.typography[200]};
|
|
89
|
+
transition: all ${({ theme }) => theme.duration.fast};
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
user-select: none;
|
|
92
|
+
|
|
93
|
+
&[data-highlighted] {
|
|
94
|
+
border-color: ${({ theme }) => theme.colors.listItem.border.base};
|
|
95
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.hover};
|
|
96
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
97
|
+
text-decoration: none;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&[data-disabled] {
|
|
101
|
+
cursor: not-allowed;
|
|
102
|
+
opacity: 0.4;
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
export const StyledMenuItem = styled(Menu.Item)`
|
|
107
|
+
${menuItemStyles}
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
export const StyledCheckboxItem = styled(Menu.CheckboxItem)`
|
|
111
|
+
${menuItemStyles}
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
115
|
+
`;
|
|
116
|
+
|
|
117
|
+
export const StyledRadioItem = styled(Menu.RadioItem)`
|
|
118
|
+
${menuItemStyles}
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
export const StyledCheckboxItemIndicator = styled(Menu.CheckboxItemIndicator)`
|
|
125
|
+
display: flex;
|
|
126
|
+
align-items: center;
|
|
127
|
+
width: 16px;
|
|
128
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
export const StyledRadioItemIndicator = styled(Menu.RadioItemIndicator)`
|
|
132
|
+
display: flex;
|
|
133
|
+
align-items: center;
|
|
134
|
+
width: 16px;
|
|
135
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
136
|
+
`;
|
|
137
|
+
|
|
138
|
+
export const StyledSubmenuTrigger = styled(Menu.SubmenuTrigger)`
|
|
139
|
+
${menuItemStyles}
|
|
140
|
+
display: flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
143
|
+
justify-content: space-between;
|
|
144
|
+
|
|
145
|
+
&[data-popup-open] {
|
|
146
|
+
border-color: ${({ theme }) => theme.colors.listItem.border.base};
|
|
147
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.hover};
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
|
|
151
|
+
export const StyledLinkItem = styled(Menu.LinkItem)`
|
|
152
|
+
${menuItemStyles}
|
|
153
|
+
`;
|
|
@@ -2,11 +2,12 @@ import { Select } from "@base-ui/react/select";
|
|
|
2
2
|
import styled from "styled-components";
|
|
3
3
|
import { focusRing } from "@sproutsocial/seeds-react-mixins";
|
|
4
4
|
|
|
5
|
-
export const Field = styled.div
|
|
6
|
-
display:
|
|
5
|
+
export const Field = styled.div<{ $fullWidth?: boolean }>`
|
|
6
|
+
display: ${({ $fullWidth }) =>
|
|
7
|
+
$fullWidth === false ? "inline-flex" : "flex"};
|
|
7
8
|
flex-direction: column;
|
|
8
9
|
gap: ${({ theme }) => theme.space[200]};
|
|
9
|
-
width: 100%;
|
|
10
|
+
${({ $fullWidth }) => $fullWidth !== false && "width: 100%;"}
|
|
10
11
|
`;
|
|
11
12
|
|
|
12
13
|
export const SelectLabel = styled(Select.Label)`
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { action } from "@storybook/addon-actions";
|
|
3
4
|
import { FormField } from "@sproutsocial/seeds-react-form-field";
|
|
4
5
|
import { Button } from "@sproutsocial/seeds-react-button";
|
|
5
6
|
import { Input } from "@sproutsocial/seeds-react-input";
|
|
@@ -16,6 +17,13 @@ import { SingleCombobox } from "./SingleCombobox";
|
|
|
16
17
|
import { MultiCombobox } from "./MultiCombobox";
|
|
17
18
|
import { SingleSearchableSelect } from "./SingleSearchableSelect";
|
|
18
19
|
import { MultiSearchableSelect } from "./MultiSearchableSelect";
|
|
20
|
+
import {
|
|
21
|
+
ActionMenu,
|
|
22
|
+
MenuGroup,
|
|
23
|
+
MenuItem,
|
|
24
|
+
MenuSub,
|
|
25
|
+
MenuSubTrigger,
|
|
26
|
+
} from "./ActionMenu";
|
|
19
27
|
import { books, itemToString } from "./storyData";
|
|
20
28
|
|
|
21
29
|
// ─── Shared content ───────────────────────────────────────────────────────────
|
|
@@ -179,3 +187,154 @@ export const V2Modal: Story = {
|
|
|
179
187
|
</>
|
|
180
188
|
),
|
|
181
189
|
};
|
|
190
|
+
|
|
191
|
+
// ─── Action Menu in Modal ─────────────────────────────────────────────────────
|
|
192
|
+
|
|
193
|
+
export const ActionMenuInV1Modal: Story = {
|
|
194
|
+
name: "Action Menu in V1 Modal",
|
|
195
|
+
render: () => {
|
|
196
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
197
|
+
return (
|
|
198
|
+
<>
|
|
199
|
+
<Button appearance="primary" onClick={() => setIsOpen(true)}>
|
|
200
|
+
Open V1 Modal
|
|
201
|
+
</Button>
|
|
202
|
+
<ModalV1
|
|
203
|
+
appElementSelector="#root"
|
|
204
|
+
isOpen={isOpen}
|
|
205
|
+
onClose={() => setIsOpen(false)}
|
|
206
|
+
closeButtonLabel="Close"
|
|
207
|
+
label="Action Menu in V1 Modal"
|
|
208
|
+
>
|
|
209
|
+
<ModalV1.Header title="" subtitle="" bordered>
|
|
210
|
+
Actions
|
|
211
|
+
</ModalV1.Header>
|
|
212
|
+
<ModalV1.Content>
|
|
213
|
+
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
|
|
214
|
+
<ActionMenu
|
|
215
|
+
trigger={<Button appearance="secondary">Basic Menu</Button>}
|
|
216
|
+
>
|
|
217
|
+
<MenuItem onClick={action("Compose")}>Compose</MenuItem>
|
|
218
|
+
<MenuItem onClick={action("View Messages")}>
|
|
219
|
+
View Messages
|
|
220
|
+
</MenuItem>
|
|
221
|
+
<MenuItem onClick={action("Analyze post")}>
|
|
222
|
+
Analyze post
|
|
223
|
+
</MenuItem>
|
|
224
|
+
</ActionMenu>
|
|
225
|
+
|
|
226
|
+
<ActionMenu
|
|
227
|
+
trigger={
|
|
228
|
+
<Button appearance="secondary">Menu with Groups</Button>
|
|
229
|
+
}
|
|
230
|
+
>
|
|
231
|
+
<MenuGroup label="Actions" showSeparator>
|
|
232
|
+
<MenuItem onClick={action("Edit")}>Edit</MenuItem>
|
|
233
|
+
<MenuItem onClick={action("Duplicate")}>Duplicate</MenuItem>
|
|
234
|
+
</MenuGroup>
|
|
235
|
+
<MenuGroup label="Danger">
|
|
236
|
+
<MenuItem onClick={action("Delete")} disabled>
|
|
237
|
+
Delete
|
|
238
|
+
</MenuItem>
|
|
239
|
+
</MenuGroup>
|
|
240
|
+
</ActionMenu>
|
|
241
|
+
|
|
242
|
+
<ActionMenu
|
|
243
|
+
trigger={
|
|
244
|
+
<Button appearance="secondary">Menu with Submenu</Button>
|
|
245
|
+
}
|
|
246
|
+
>
|
|
247
|
+
<MenuItem onClick={action("Compose")}>Compose</MenuItem>
|
|
248
|
+
<MenuSub trigger={<MenuSubTrigger>Share</MenuSubTrigger>}>
|
|
249
|
+
<MenuItem onClick={action("Share to Twitter")}>
|
|
250
|
+
Twitter
|
|
251
|
+
</MenuItem>
|
|
252
|
+
<MenuItem onClick={action("Share to LinkedIn")}>
|
|
253
|
+
LinkedIn
|
|
254
|
+
</MenuItem>
|
|
255
|
+
<MenuSub
|
|
256
|
+
trigger={<MenuSubTrigger>More platforms</MenuSubTrigger>}
|
|
257
|
+
>
|
|
258
|
+
<MenuItem onClick={action("Share to Facebook")}>
|
|
259
|
+
Facebook
|
|
260
|
+
</MenuItem>
|
|
261
|
+
<MenuItem onClick={action("Share to Instagram")}>
|
|
262
|
+
Instagram
|
|
263
|
+
</MenuItem>
|
|
264
|
+
</MenuSub>
|
|
265
|
+
</MenuSub>
|
|
266
|
+
<MenuItem onClick={action("Delete")} disabled>
|
|
267
|
+
Delete
|
|
268
|
+
</MenuItem>
|
|
269
|
+
</ActionMenu>
|
|
270
|
+
</div>
|
|
271
|
+
</ModalV1.Content>
|
|
272
|
+
<ModalV1.Footer>Footer</ModalV1.Footer>
|
|
273
|
+
</ModalV1>
|
|
274
|
+
</>
|
|
275
|
+
);
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const ActionMenuInModal: Story = {
|
|
280
|
+
name: "Action Menu in V2 Modal",
|
|
281
|
+
render: () => (
|
|
282
|
+
<ModalV2
|
|
283
|
+
title="Actions"
|
|
284
|
+
modalTrigger={<Button appearance="primary">Open Modal</Button>}
|
|
285
|
+
closeButtonAriaLabel="Close"
|
|
286
|
+
>
|
|
287
|
+
<ModalBody>
|
|
288
|
+
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
|
|
289
|
+
<ActionMenu
|
|
290
|
+
trigger={<Button appearance="secondary">Basic Menu</Button>}
|
|
291
|
+
>
|
|
292
|
+
<MenuItem onClick={action("Compose")}>Compose</MenuItem>
|
|
293
|
+
<MenuItem onClick={action("View Messages")}>View Messages</MenuItem>
|
|
294
|
+
<MenuItem onClick={action("Analyze post")}>Analyze post</MenuItem>
|
|
295
|
+
</ActionMenu>
|
|
296
|
+
|
|
297
|
+
<ActionMenu
|
|
298
|
+
trigger={<Button appearance="secondary">Menu with Groups</Button>}
|
|
299
|
+
>
|
|
300
|
+
<MenuGroup label="Actions" showSeparator>
|
|
301
|
+
<MenuItem onClick={action("Edit")}>Edit</MenuItem>
|
|
302
|
+
<MenuItem onClick={action("Duplicate")}>Duplicate</MenuItem>
|
|
303
|
+
</MenuGroup>
|
|
304
|
+
<MenuGroup label="Danger">
|
|
305
|
+
<MenuItem onClick={action("Delete")} disabled>
|
|
306
|
+
Delete
|
|
307
|
+
</MenuItem>
|
|
308
|
+
</MenuGroup>
|
|
309
|
+
</ActionMenu>
|
|
310
|
+
|
|
311
|
+
<ActionMenu
|
|
312
|
+
trigger={<Button appearance="secondary">Menu with Submenu</Button>}
|
|
313
|
+
>
|
|
314
|
+
<MenuItem onClick={action("Compose")}>Compose</MenuItem>
|
|
315
|
+
<MenuSub trigger={<MenuSubTrigger>Share</MenuSubTrigger>}>
|
|
316
|
+
<MenuItem onClick={action("Share to Twitter")}>Twitter</MenuItem>
|
|
317
|
+
<MenuItem onClick={action("Share to LinkedIn")}>
|
|
318
|
+
LinkedIn
|
|
319
|
+
</MenuItem>
|
|
320
|
+
<MenuSub
|
|
321
|
+
trigger={<MenuSubTrigger>More platforms</MenuSubTrigger>}
|
|
322
|
+
>
|
|
323
|
+
<MenuItem onClick={action("Share to Facebook")}>
|
|
324
|
+
Facebook
|
|
325
|
+
</MenuItem>
|
|
326
|
+
<MenuItem onClick={action("Share to Instagram")}>
|
|
327
|
+
Instagram
|
|
328
|
+
</MenuItem>
|
|
329
|
+
</MenuSub>
|
|
330
|
+
</MenuSub>
|
|
331
|
+
<MenuItem onClick={action("Delete")} disabled>
|
|
332
|
+
Delete
|
|
333
|
+
</MenuItem>
|
|
334
|
+
</ActionMenu>
|
|
335
|
+
</div>
|
|
336
|
+
</ModalBody>
|
|
337
|
+
<ModalFooter cancelButton={<Button>Close</Button>} />
|
|
338
|
+
</ModalV2>
|
|
339
|
+
),
|
|
340
|
+
};
|
|
@@ -396,6 +396,23 @@ export const VirtualizedSelectAll: Story = {
|
|
|
396
396
|
),
|
|
397
397
|
};
|
|
398
398
|
|
|
399
|
+
export const Inline: Story = {
|
|
400
|
+
name: "Inline (fullWidth=false)",
|
|
401
|
+
render: () => (
|
|
402
|
+
<FormField label="Pick books">
|
|
403
|
+
{({ id }) => (
|
|
404
|
+
<MultiCombobox
|
|
405
|
+
id={id}
|
|
406
|
+
data={books}
|
|
407
|
+
itemToString={itemToString}
|
|
408
|
+
placeholder="Search books..."
|
|
409
|
+
fullWidth={false}
|
|
410
|
+
/>
|
|
411
|
+
)}
|
|
412
|
+
</FormField>
|
|
413
|
+
),
|
|
414
|
+
};
|
|
415
|
+
|
|
399
416
|
export const CustomSearch: Story = {
|
|
400
417
|
name: "Custom search (title + author)",
|
|
401
418
|
render: () => (
|
package/src/v3/MultiCombobox.tsx
CHANGED
|
@@ -74,6 +74,7 @@ interface MultiComboboxBaseProps {
|
|
|
74
74
|
inputValue?: string;
|
|
75
75
|
onInputValueChange?: (value: string) => void;
|
|
76
76
|
"aria-describedby"?: string;
|
|
77
|
+
fullWidth?: boolean;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
interface MultiComboboxDataProps<T extends DataWithId>
|
|
@@ -141,6 +142,7 @@ export function MultiCombobox<T extends DataWithId>(
|
|
|
141
142
|
filter,
|
|
142
143
|
inputValue,
|
|
143
144
|
onInputValueChange,
|
|
145
|
+
fullWidth = true,
|
|
144
146
|
} = props;
|
|
145
147
|
const ariaDescribedBy = props["aria-describedby"];
|
|
146
148
|
|
|
@@ -481,7 +483,7 @@ export function MultiCombobox<T extends DataWithId>(
|
|
|
481
483
|
: (value as unknown as T[]);
|
|
482
484
|
|
|
483
485
|
return (
|
|
484
|
-
<Field>
|
|
486
|
+
<Field $fullWidth={fullWidth}>
|
|
485
487
|
<div ref={containerRef} style={{ position: "relative" }} />
|
|
486
488
|
<Combobox.Root
|
|
487
489
|
multiple
|
|
@@ -506,19 +508,28 @@ export function MultiCombobox<T extends DataWithId>(
|
|
|
506
508
|
}
|
|
507
509
|
: filter
|
|
508
510
|
}
|
|
509
|
-
inputValue={
|
|
510
|
-
|
|
511
|
-
creatableProp
|
|
512
|
-
? (v) => {
|
|
513
|
-
if (skipNextInputChangeRef.current) {
|
|
514
|
-
skipNextInputChangeRef.current = false;
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
setInternalInputValue(v);
|
|
518
|
-
onInputValueChange?.(v);
|
|
519
|
-
}
|
|
520
|
-
: onInputValueChange
|
|
511
|
+
inputValue={
|
|
512
|
+
creatableProp ? currentInputValue : inputValue ?? internalInputValue
|
|
521
513
|
}
|
|
514
|
+
onInputValueChange={(v, eventDetails) => {
|
|
515
|
+
// Preserve search query when an item is selected. Base UI fires
|
|
516
|
+
// 'input-clear' on item-press; ignore it while the popup stays open.
|
|
517
|
+
if (eventDetails.reason === "input-clear" && open) return;
|
|
518
|
+
|
|
519
|
+
if (creatableProp) {
|
|
520
|
+
if (skipNextInputChangeRef.current) {
|
|
521
|
+
skipNextInputChangeRef.current = false;
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
setInternalInputValue(v);
|
|
525
|
+
onInputValueChange?.(v);
|
|
526
|
+
} else {
|
|
527
|
+
if (inputValue === undefined) {
|
|
528
|
+
setInternalInputValue(v);
|
|
529
|
+
}
|
|
530
|
+
onInputValueChange?.(v);
|
|
531
|
+
}
|
|
532
|
+
}}
|
|
522
533
|
onItemHighlighted={
|
|
523
534
|
isVirtualized
|
|
524
535
|
? (item, { reason, index }) => {
|
|
@@ -413,6 +413,24 @@ export const LoadingWithToggle: Story = {
|
|
|
413
413
|
},
|
|
414
414
|
};
|
|
415
415
|
|
|
416
|
+
export const Inline: Story = {
|
|
417
|
+
name: "Inline (fullWidth=false)",
|
|
418
|
+
render: () => (
|
|
419
|
+
<FormField label="Pick books">
|
|
420
|
+
{({ id }) => (
|
|
421
|
+
<MultiSearchableSelect
|
|
422
|
+
id={id}
|
|
423
|
+
data={books}
|
|
424
|
+
itemToString={itemToString}
|
|
425
|
+
placeholder="Select books"
|
|
426
|
+
searchPlaceholder="Search books..."
|
|
427
|
+
fullWidth={false}
|
|
428
|
+
/>
|
|
429
|
+
)}
|
|
430
|
+
</FormField>
|
|
431
|
+
),
|
|
432
|
+
};
|
|
433
|
+
|
|
416
434
|
export const CustomSearch: Story = {
|
|
417
435
|
name: "Custom search (title + author)",
|
|
418
436
|
render: () => (
|