@sproutsocial/seeds-react-menu 1.16.5 → 1.16.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-menu",
3
- "version": "1.16.5",
3
+ "version": "1.16.7",
4
4
  "description": "Seeds React Menu",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -36,18 +36,18 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@radix-ui/react-popover": "^1.1.2",
39
- "@sproutsocial/seeds-react-box": "^1.1.24",
40
- "@sproutsocial/seeds-react-button": "^2.2.4",
41
- "@sproutsocial/seeds-react-checkbox": "^1.3.45",
42
- "@sproutsocial/seeds-react-icon": "^2.4.3",
43
- "@sproutsocial/seeds-react-input": "^1.5.31",
44
- "@sproutsocial/seeds-react-label": "^1.0.26",
45
- "@sproutsocial/seeds-react-popout": "^2.5.12",
46
- "@sproutsocial/seeds-react-radio": "^1.3.27",
47
- "@sproutsocial/seeds-react-switch": "^1.2.43",
39
+ "@sproutsocial/seeds-react-box": "^1.1.25",
40
+ "@sproutsocial/seeds-react-button": "^2.2.5",
41
+ "@sproutsocial/seeds-react-checkbox": "^1.3.46",
42
+ "@sproutsocial/seeds-react-icon": "^2.4.4",
43
+ "@sproutsocial/seeds-react-input": "^1.5.32",
44
+ "@sproutsocial/seeds-react-label": "^1.0.27",
45
+ "@sproutsocial/seeds-react-popout": "^2.5.13",
46
+ "@sproutsocial/seeds-react-radio": "^1.3.28",
47
+ "@sproutsocial/seeds-react-switch": "^1.2.44",
48
48
  "@sproutsocial/seeds-react-system-props": "^3.1.2",
49
- "@sproutsocial/seeds-react-theme": "^4.2.0",
50
- "@sproutsocial/seeds-react-token-input": "^1.4.53",
49
+ "@sproutsocial/seeds-react-theme": "^4.2.1",
50
+ "@sproutsocial/seeds-react-token-input": "^1.4.54",
51
51
  "@sproutsocial/seeds-react-utilities": "^4.3.0",
52
52
  "@base-ui/react": "^1.3.0",
53
53
  "@tanstack/react-virtual": "^3.13.12",
@@ -57,7 +57,7 @@
57
57
  "styled-system": "^5.1.5"
58
58
  },
59
59
  "devDependencies": {
60
- "@sproutsocial/seeds-react-tooltip": "^1.1.30",
60
+ "@sproutsocial/seeds-react-tooltip": "^1.1.31",
61
61
  "@sproutsocial/eslint-config-seeds": "*",
62
62
  "@sproutsocial/seeds-react-testing-library": "*",
63
63
  "@sproutsocial/seeds-testing": "*",
@@ -11,6 +11,12 @@ import {
11
11
  ModalBody,
12
12
  ModalFooter,
13
13
  } from "@sproutsocial/seeds-react-modal";
14
+ import {
15
+ PeekIn,
16
+ PeekInHeader,
17
+ PeekInContent,
18
+ PeekInPanel,
19
+ } from "@sproutsocial/seeds-react-peek-in";
14
20
  import { SingleSelect } from "./SingleSelect";
15
21
  import { MultiSelect } from "./MultiSelect";
16
22
  import { SingleCombobox } from "./SingleCombobox";
@@ -276,6 +282,112 @@ export const ActionMenuInV1Modal: Story = {
276
282
  },
277
283
  };
278
284
 
285
+ export const ActionMenuInPeekIn: Story = {
286
+ name: "Action Menu in PeekIn",
287
+ render: () => {
288
+ const [open, setOpen] = React.useState(false);
289
+ return (
290
+ <>
291
+ <Button appearance="primary" onClick={() => setOpen(true)}>
292
+ Open PeekIn
293
+ </Button>
294
+ <PeekIn open={open} onOpenChange={setOpen} closeButtonAriaLabel="Close">
295
+ <PeekInHeader title="Actions">
296
+ <ActionMenu
297
+ trigger={<Button appearance="pill">More actions</Button>}
298
+ >
299
+ <MenuItem onClick={action("Edit")}>Edit</MenuItem>
300
+ <MenuItem onClick={action("Duplicate")}>Duplicate</MenuItem>
301
+ <MenuGroup label="Danger">
302
+ <MenuItem onClick={action("Delete")} disabled>
303
+ Delete
304
+ </MenuItem>
305
+ </MenuGroup>
306
+ </ActionMenu>
307
+ </PeekInHeader>
308
+ <PeekInContent>
309
+ <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
310
+ <ActionMenu
311
+ trigger={<Button appearance="secondary">Basic Menu</Button>}
312
+ >
313
+ <MenuItem onClick={action("Compose")}>Compose</MenuItem>
314
+ <MenuItem onClick={action("View Messages")}>
315
+ View Messages
316
+ </MenuItem>
317
+ <MenuItem onClick={action("Analyze post")}>
318
+ Analyze post
319
+ </MenuItem>
320
+ </ActionMenu>
321
+
322
+ <ActionMenu
323
+ trigger={
324
+ <Button appearance="secondary">Menu with Groups</Button>
325
+ }
326
+ >
327
+ <MenuGroup label="Actions" showSeparator>
328
+ <MenuItem onClick={action("Edit")}>Edit</MenuItem>
329
+ <MenuItem onClick={action("Duplicate")}>Duplicate</MenuItem>
330
+ </MenuGroup>
331
+ <MenuGroup label="Danger">
332
+ <MenuItem onClick={action("Delete")} disabled>
333
+ Delete
334
+ </MenuItem>
335
+ </MenuGroup>
336
+ </ActionMenu>
337
+
338
+ <ActionMenu
339
+ trigger={
340
+ <Button appearance="secondary">Menu with Submenu</Button>
341
+ }
342
+ >
343
+ <MenuItem onClick={action("Compose")}>Compose</MenuItem>
344
+ <MenuSub trigger={<MenuSubTrigger>Share</MenuSubTrigger>}>
345
+ <MenuItem onClick={action("Share to Twitter")}>
346
+ Twitter
347
+ </MenuItem>
348
+ <MenuItem onClick={action("Share to LinkedIn")}>
349
+ LinkedIn
350
+ </MenuItem>
351
+ <MenuSub
352
+ trigger={<MenuSubTrigger>More platforms</MenuSubTrigger>}
353
+ >
354
+ <MenuItem onClick={action("Share to Facebook")}>
355
+ Facebook
356
+ </MenuItem>
357
+ <MenuItem onClick={action("Share to Instagram")}>
358
+ Instagram
359
+ </MenuItem>
360
+ </MenuSub>
361
+ </MenuSub>
362
+ <MenuItem onClick={action("Delete")} disabled>
363
+ Delete
364
+ </MenuItem>
365
+ </ActionMenu>
366
+ </div>
367
+ </PeekInContent>
368
+ <PeekInPanel title="Details">
369
+ <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
370
+ <ActionMenu
371
+ trigger={
372
+ <Button appearance="secondary">Panel Action Menu</Button>
373
+ }
374
+ >
375
+ <MenuItem onClick={action("Pin")}>Pin</MenuItem>
376
+ <MenuItem onClick={action("Add to report")}>
377
+ Add to report
378
+ </MenuItem>
379
+ <MenuGroup label="Danger" showSeparator>
380
+ <MenuItem onClick={action("Remove")}>Remove</MenuItem>
381
+ </MenuGroup>
382
+ </ActionMenu>
383
+ </div>
384
+ </PeekInPanel>
385
+ </PeekIn>
386
+ </>
387
+ );
388
+ },
389
+ };
390
+
279
391
  export const ActionMenuInModal: Story = {
280
392
  name: "Action Menu in V2 Modal",
281
393
  render: () => (
@@ -8,6 +8,14 @@ import { DisablePortalToBodyContext } from "@sproutsocial/seeds-react-portal";
8
8
  * the popup stays inside the Radix Dialog's focus/pointer boundary.
9
9
  * Otherwise returns undefined, letting Base UI portal to document.body.
10
10
  *
11
+ * Module Federation note: when a remote chunk loads its own copy of
12
+ * seeds-react-portal, the context object identity differs from the host's
13
+ * copy, so DisablePortalToBodyContext will always read false in the remote
14
+ * even when a Modal/Drawer/PeekIn has provided true. As a fallback we walk
15
+ * the DOM from the containerRef anchor and treat any [role="dialog"] ancestor
16
+ * as an in-dialog boundary, matching the same behaviour the context would have
17
+ * triggered.
18
+ *
11
19
  * Usage:
12
20
  * const { containerRef, portalContainer } = useSeedsPortalContainer();
13
21
  * <div ref={containerRef} style={{ position: "relative" }} />
@@ -21,7 +29,17 @@ export function useSeedsPortalContainer() {
21
29
  >(undefined);
22
30
 
23
31
  React.useEffect(() => {
24
- if (disablePortalToBody && containerRef.current) {
32
+ if (!containerRef.current) return;
33
+
34
+ // Primary signal: context set by Modal V2 / Drawer / PeekIn in the same
35
+ // module federation chunk.
36
+ const insideDialog =
37
+ disablePortalToBody ||
38
+ // Fallback for cross-chunk MFE scenarios where context identity differs:
39
+ // detect the dialog boundary directly from the DOM.
40
+ !!containerRef.current.closest("[role='dialog']");
41
+
42
+ if (insideDialog) {
25
43
  // Portal to the Radix Dialog content element so the popup escapes the
26
44
  // ModalBody scroll container while staying inside the Dialog boundary
27
45
  // (required for Radix focus/pointer-events containment).