@elementor/editor-site-navigation 0.7.0 → 0.8.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/index.mjs CHANGED
@@ -230,8 +230,349 @@ function RecentlyEdited() {
230
230
 
231
231
  // src/init.ts
232
232
  import { injectIntoPageIndication } from "@elementor/editor-app-bar";
233
+ import { injectIntoTop } from "@elementor/editor";
234
+
235
+ // src/components/panel/shell.tsx
236
+ import * as React18 from "react";
237
+ import { Box as Box3, Button as Button2, Divider as Divider3, Grid, List as List2, Paper, ThemeProvider, Typography as Typography4 } from "@elementor/ui";
238
+ import { PlusIcon as PlusIcon2 } from "@elementor/icons";
239
+
240
+ // src/components/panel/pages-list/pages-collapsible-list.tsx
241
+ import * as React17 from "react";
242
+
243
+ // src/components/panel/pages-list/collapsible-list.tsx
244
+ import * as React6 from "react";
245
+ import { useState as useState3 } from "react";
246
+ import { Collapse, IconButton, List, ListItem, ListItemIcon as ListItemIcon2, ListItemText, styled } from "@elementor/ui";
247
+ import { ChevronDownIcon as ChevronDownIcon2 } from "@elementor/icons";
248
+ var RotateIcon = styled(ChevronDownIcon2, {
249
+ shouldForwardProp: (prop) => prop !== "isOpen"
250
+ })(({ theme, isOpen }) => ({
251
+ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)",
252
+ transition: theme.transitions.create("transform", {
253
+ duration: theme.transitions.duration.standard
254
+ })
255
+ }));
256
+ function CollapsibleList({
257
+ label,
258
+ Icon,
259
+ isOpenByDefault = false,
260
+ children
261
+ }) {
262
+ const [isOpen, setIsOpen] = useState3(isOpenByDefault);
263
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ListItem, { disableGutters: true }, /* @__PURE__ */ React6.createElement(ListItemIcon2, null, /* @__PURE__ */ React6.createElement(
264
+ IconButton,
265
+ {
266
+ onClick: () => setIsOpen((prev) => !prev),
267
+ sx: { color: "inherit" },
268
+ size: "small"
269
+ },
270
+ /* @__PURE__ */ React6.createElement(RotateIcon, { fontSize: "small", isOpen })
271
+ )), /* @__PURE__ */ React6.createElement(ListItemIcon2, null, /* @__PURE__ */ React6.createElement(Icon, null)), /* @__PURE__ */ React6.createElement(ListItemText, null, label)), /* @__PURE__ */ React6.createElement(
272
+ Collapse,
273
+ {
274
+ in: isOpen,
275
+ timeout: "auto",
276
+ unmountOnExit: true
277
+ },
278
+ /* @__PURE__ */ React6.createElement(List, { dense: true }, children)
279
+ ));
280
+ }
281
+
282
+ // src/components/panel/pages-list/pages-collapsible-list.tsx
283
+ import { PageTypeIcon as PageTypeIcon2 } from "@elementor/icons";
284
+
285
+ // src/components/panel/pages-list/page-list-item.tsx
286
+ import * as React16 from "react";
287
+ import {
288
+ bindMenu as bindMenu2,
289
+ bindTrigger as bindTrigger2,
290
+ ListItem as ListItem2,
291
+ ListItemButton as ListItemButton2,
292
+ ListItemIcon as ListItemIcon4,
293
+ ListItemText as ListItemText3,
294
+ ToggleButton,
295
+ usePopupState as usePopupState2
296
+ } from "@elementor/ui";
297
+ import { DotsVerticalIcon, HomeIcon as HomeIcon2 } from "@elementor/icons";
298
+ import { useActiveDocument as useActiveDocument3, useNavigateToDocument as useNavigateToDocument3 } from "@elementor/editor-documents";
299
+
300
+ // src/components/shared/page-title-and-status.tsx
301
+ import * as React7 from "react";
302
+ import { Box as Box2, Typography as Typography3 } from "@elementor/ui";
303
+ var PageStatus = ({ status }) => {
304
+ if ("publish" === status) {
305
+ return null;
306
+ }
307
+ return /* @__PURE__ */ React7.createElement(
308
+ Typography3,
309
+ {
310
+ component: "span",
311
+ variant: "body1",
312
+ sx: {
313
+ textTransform: "capitalize",
314
+ fontStyle: "italic",
315
+ whiteSpace: "nowrap",
316
+ flexBasis: "content"
317
+ }
318
+ },
319
+ "(",
320
+ status,
321
+ ")"
322
+ );
323
+ };
324
+ var PageTitle = ({ title }) => {
325
+ const modifiedTitle = useReverseHtmlEntities(title);
326
+ return /* @__PURE__ */ React7.createElement(
327
+ Typography3,
328
+ {
329
+ component: "span",
330
+ variant: "body1",
331
+ noWrap: true,
332
+ sx: {
333
+ flexBasis: "auto"
334
+ }
335
+ },
336
+ modifiedTitle
337
+ );
338
+ };
339
+ function PageTitleAndStatus({ page }) {
340
+ return /* @__PURE__ */ React7.createElement(Box2, { display: "flex" }, /* @__PURE__ */ React7.createElement(PageTitle, { title: page.title }), "\xA0", /* @__PURE__ */ React7.createElement(PageStatus, { status: page.status }));
341
+ }
342
+
343
+ // src/components/panel/actions-menu/page-actions-menu.tsx
344
+ import * as React15 from "react";
345
+ import { Divider as Divider2, Menu as Menu2 } from "@elementor/ui";
346
+
347
+ // src/components/panel/pages-actions/rename.tsx
348
+ import * as React10 from "react";
349
+ import { EraseIcon } from "@elementor/icons";
350
+ import { __ as __3 } from "@wordpress/i18n";
351
+
352
+ // src/components/panel/actions-menu/action-menu-item.tsx
353
+ import * as React9 from "react";
354
+
355
+ // src/components/panel/actions-menu/action-list-item.tsx
356
+ import * as React8 from "react";
357
+ import { ListItemButton, ListItemIcon as ListItemIcon3, ListItemText as ListItemText2 } from "@elementor/ui";
358
+ function ActionListItem({ title, icon: Icon, disabled, onClick }) {
359
+ return /* @__PURE__ */ React8.createElement(
360
+ ListItemButton,
361
+ {
362
+ disabled,
363
+ onClick
364
+ },
365
+ /* @__PURE__ */ React8.createElement(ListItemIcon3, null, /* @__PURE__ */ React8.createElement(Icon, null)),
366
+ /* @__PURE__ */ React8.createElement(ListItemText2, null, title)
367
+ );
368
+ }
369
+
370
+ // src/components/panel/actions-menu/action-menu-item.tsx
371
+ import { MenuItem as MenuItem3 } from "@elementor/ui";
372
+ function ActionMenuItem(props) {
373
+ return /* @__PURE__ */ React9.createElement(MenuItem3, { disableGutters: true }, /* @__PURE__ */ React9.createElement(ActionListItem, { ...props }));
374
+ }
375
+
376
+ // src/components/panel/pages-actions/rename.tsx
377
+ function Rename() {
378
+ return /* @__PURE__ */ React10.createElement(
379
+ ActionMenuItem,
380
+ {
381
+ title: __3("Rename", "elementor"),
382
+ icon: EraseIcon,
383
+ onClick: () => null
384
+ }
385
+ );
386
+ }
387
+
388
+ // src/components/panel/pages-actions/duplicate.tsx
389
+ import * as React11 from "react";
390
+ import { __ as __4 } from "@wordpress/i18n";
391
+ import { CopyIcon } from "@elementor/icons";
392
+ function Duplicate() {
393
+ return /* @__PURE__ */ React11.createElement(
394
+ ActionMenuItem,
395
+ {
396
+ title: __4("Duplicate", "elementor"),
397
+ icon: CopyIcon,
398
+ onClick: () => null
399
+ }
400
+ );
401
+ }
402
+
403
+ // src/components/panel/pages-actions/delete.tsx
404
+ import * as React12 from "react";
405
+ import { TrashIcon } from "@elementor/icons";
406
+ import { useActiveDocument as useActiveDocument2 } from "@elementor/editor-documents";
407
+ import { __ as __5 } from "@wordpress/i18n";
408
+ function Delete({ page }) {
409
+ const activeDocument = useActiveDocument2();
410
+ const isActive = activeDocument?.id === page.id;
411
+ return /* @__PURE__ */ React12.createElement(
412
+ ActionMenuItem,
413
+ {
414
+ title: __5("Delete", "elementor"),
415
+ icon: TrashIcon,
416
+ disabled: page.isHome || isActive,
417
+ onClick: () => null
418
+ }
419
+ );
420
+ }
421
+
422
+ // src/components/panel/pages-actions/view.tsx
423
+ import * as React13 from "react";
424
+ import { EyeIcon } from "@elementor/icons";
425
+ import { __ as __6 } from "@wordpress/i18n";
426
+ function View() {
427
+ return /* @__PURE__ */ React13.createElement(
428
+ ActionMenuItem,
429
+ {
430
+ title: __6("View Page", "elementor"),
431
+ icon: EyeIcon,
432
+ onClick: () => null
433
+ }
434
+ );
435
+ }
436
+
437
+ // src/components/panel/pages-actions/set-home.tsx
438
+ import * as React14 from "react";
439
+ import { HomeIcon } from "@elementor/icons";
440
+ import { __ as __7 } from "@wordpress/i18n";
441
+ function SetHome({ page }) {
442
+ return /* @__PURE__ */ React14.createElement(
443
+ ActionMenuItem,
444
+ {
445
+ title: __7("Set as homepage", "elementor"),
446
+ icon: HomeIcon,
447
+ disabled: !!page.isHome,
448
+ onClick: () => null
449
+ }
450
+ );
451
+ }
452
+
453
+ // src/components/panel/actions-menu/page-actions-menu.tsx
454
+ function PageActionsMenu({ page, ...props }) {
455
+ return /* @__PURE__ */ React15.createElement(
456
+ Menu2,
457
+ {
458
+ PaperProps: { sx: { mt: 4, width: 200 } },
459
+ MenuListProps: { dense: true },
460
+ ...props
461
+ },
462
+ /* @__PURE__ */ React15.createElement(Rename, null),
463
+ /* @__PURE__ */ React15.createElement(Duplicate, null),
464
+ /* @__PURE__ */ React15.createElement(Delete, { page }),
465
+ /* @__PURE__ */ React15.createElement(View, null),
466
+ /* @__PURE__ */ React15.createElement(Divider2, null),
467
+ /* @__PURE__ */ React15.createElement(SetHome, { page })
468
+ );
469
+ }
470
+
471
+ // src/components/panel/pages-list/page-list-item.tsx
472
+ function PageListItem({ page }) {
473
+ const popupState = usePopupState2({
474
+ variant: "popover",
475
+ popupId: "page-actions"
476
+ });
477
+ const activeDocument = useActiveDocument3();
478
+ const navigateToDocument = useNavigateToDocument3();
479
+ const isActive = activeDocument?.id === page.id;
480
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
481
+ ListItem2,
482
+ {
483
+ disablePadding: true,
484
+ secondaryAction: /* @__PURE__ */ React16.createElement(
485
+ ToggleButton,
486
+ {
487
+ value: true,
488
+ color: "secondary",
489
+ size: "small",
490
+ selected: popupState.isOpen,
491
+ ...bindTrigger2(popupState)
492
+ },
493
+ /* @__PURE__ */ React16.createElement(DotsVerticalIcon, { fontSize: "small" })
494
+ )
495
+ },
496
+ /* @__PURE__ */ React16.createElement(
497
+ ListItemButton2,
498
+ {
499
+ selected: isActive,
500
+ onClick: () => navigateToDocument(page.id),
501
+ dense: true
502
+ },
503
+ /* @__PURE__ */ React16.createElement(ListItemIcon4, null),
504
+ /* @__PURE__ */ React16.createElement(
505
+ ListItemText3,
506
+ {
507
+ disableTypography: true
508
+ },
509
+ /* @__PURE__ */ React16.createElement(PageTitleAndStatus, { page })
510
+ ),
511
+ page.isHome && /* @__PURE__ */ React16.createElement(ListItemIcon4, null, /* @__PURE__ */ React16.createElement(HomeIcon2, { color: "disabled" }))
512
+ )
513
+ ), /* @__PURE__ */ React16.createElement(PageActionsMenu, { page, ...bindMenu2(popupState) }));
514
+ }
515
+
516
+ // src/components/panel/pages-list/pages-collapsible-list.tsx
517
+ function PagesCollapsibleList({ pages, isOpenByDefault = false }) {
518
+ const label = `Pages (${pages.length})`;
519
+ return /* @__PURE__ */ React17.createElement(
520
+ CollapsibleList,
521
+ {
522
+ label,
523
+ Icon: PageTypeIcon2,
524
+ isOpenByDefault
525
+ },
526
+ pages.map((page) => /* @__PURE__ */ React17.createElement(PageListItem, { key: page.id, page }))
527
+ );
528
+ }
529
+
530
+ // src/components/panel/shell.tsx
531
+ var mockPages = [
532
+ {
533
+ id: 1,
534
+ type: "page",
535
+ title: "This is a very long title that somebody wrote, a very very long line",
536
+ status: "pending approval"
537
+ },
538
+ { id: 2, type: "page", title: "About", status: "publish" },
539
+ { id: 3, type: "page", title: "Services", status: "publish", isHome: true },
540
+ { id: 4, type: "page", title: "Contact", status: "draft" },
541
+ { id: 5, type: "page", title: "FAQ", status: "publish" }
542
+ ];
543
+ var Shell = () => {
544
+ return /* @__PURE__ */ React18.createElement(ThemeProvider, { colorScheme: "light" }, /* @__PURE__ */ React18.createElement(Box3, { sx: { width: "100%", maxWidth: 360 } }, /* @__PURE__ */ React18.createElement(Paper, null, /* @__PURE__ */ React18.createElement(
545
+ Grid,
546
+ {
547
+ container: true,
548
+ justifyContent: "center",
549
+ alignItems: "center",
550
+ sx: { height: 51 }
551
+ },
552
+ /* @__PURE__ */ React18.createElement(Typography4, { variant: "h6" }, "Pages")
553
+ ), /* @__PURE__ */ React18.createElement(Divider3, null), /* @__PURE__ */ React18.createElement(
554
+ Box3,
555
+ {
556
+ display: "flex",
557
+ justifyContent: "flex-end",
558
+ alignItems: "center"
559
+ },
560
+ /* @__PURE__ */ React18.createElement(
561
+ Button2,
562
+ {
563
+ sx: { mt: 4, mb: 4, mr: 5 },
564
+ startIcon: /* @__PURE__ */ React18.createElement(PlusIcon2, null)
565
+ },
566
+ "Add New"
567
+ )
568
+ ), /* @__PURE__ */ React18.createElement(Box3, { sx: { width: "100%", maxWidth: 360 } }, /* @__PURE__ */ React18.createElement(List2, { dense: true }, /* @__PURE__ */ React18.createElement(PagesCollapsibleList, { pages: mockPages, isOpenByDefault: true }))), /* @__PURE__ */ React18.createElement(Divider3, null))));
569
+ };
570
+ var shell_default = Shell;
571
+
572
+ // src/init.ts
233
573
  function init() {
234
574
  registerTopBarMenuItems();
575
+ registerPanel();
235
576
  }
236
577
  function registerTopBarMenuItems() {
237
578
  injectIntoPageIndication({
@@ -239,6 +580,12 @@ function registerTopBarMenuItems() {
239
580
  filler: RecentlyEdited
240
581
  });
241
582
  }
583
+ function registerPanel() {
584
+ injectIntoTop({
585
+ id: "navigation-panel",
586
+ filler: shell_default
587
+ });
588
+ }
242
589
 
243
590
  // src/index.ts
244
591
  init();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-site-navigation",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -32,10 +32,11 @@
32
32
  "dev": "tsup --config=../../tsup.dev.ts"
33
33
  },
34
34
  "dependencies": {
35
- "@elementor/editor-app-bar": "^0.6.2",
35
+ "@elementor/editor": "^0.6.1",
36
+ "@elementor/editor-app-bar": "^0.6.3",
36
37
  "@elementor/editor-documents": "^0.8.2",
37
- "@elementor/icons": "^0.4.0",
38
- "@elementor/ui": "^1.4.50",
38
+ "@elementor/icons": "^0.5.0",
39
+ "@elementor/ui": "^1.4.53",
39
40
  "@wordpress/api-fetch": "^6.27.0",
40
41
  "@wordpress/i18n": "^4.31.0",
41
42
  "@wordpress/url": "^3.31.0"
@@ -46,5 +47,5 @@
46
47
  "elementor": {
47
48
  "type": "extension"
48
49
  },
49
- "gitHead": "ad9032e095915dbef0f8543d83f73b9288adc8ad"
50
+ "gitHead": "d15192c0e60703e9831f7813d0a32d5943fe6c28"
50
51
  }
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { ComponentType } from 'react';
3
+ import { ListItemButton, ListItemIcon, ListItemText } from '@elementor/ui';
4
+ import { Page } from '../../../types';
5
+
6
+ export type Props = {
7
+ title: string;
8
+ icon: ComponentType;
9
+ disabled?: boolean;
10
+ onClick: ( page: Page ) => void;
11
+ }
12
+
13
+ export default function ActionListItem( { title, icon: Icon, disabled, onClick }: Props ) {
14
+ return (
15
+ <ListItemButton
16
+ disabled={ disabled }
17
+ onClick={ onClick }
18
+ >
19
+ <ListItemIcon>
20
+ <Icon />
21
+ </ListItemIcon>
22
+ <ListItemText>
23
+ { title }
24
+ </ListItemText>
25
+ </ListItemButton>
26
+ );
27
+ }
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import ActionListItem, { Props as ActionListItemProps } from './action-list-item';
3
+ import { MenuItem } from '@elementor/ui';
4
+
5
+ export default function ActionMenuItem( props: ActionListItemProps ) {
6
+ return (
7
+ <MenuItem disableGutters>
8
+ <ActionListItem { ...props } />
9
+ </MenuItem>
10
+ );
11
+ }
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import { Divider, Menu, MenuProps } from '@elementor/ui';
3
+ import Rename from '../pages-actions/rename';
4
+ import Duplicate from '../pages-actions/duplicate';
5
+ import Delete from '../pages-actions/delete';
6
+ import { Page } from '../../../types';
7
+ import View from '../pages-actions/view';
8
+ import SetHome from '../pages-actions/set-home';
9
+
10
+ type Props = MenuProps & {
11
+ page: Page
12
+ };
13
+
14
+ export default function PageActionsMenu( { page, ...props }: Props ) {
15
+ return (
16
+ <Menu
17
+ PaperProps={ { sx: { mt: 4, width: 200 } } }
18
+ MenuListProps={ { dense: true } }
19
+ { ...props }
20
+ >
21
+ <Rename />
22
+ <Duplicate />
23
+ <Delete page={ page } />
24
+ <View />
25
+ <Divider />
26
+ <SetHome page={ page } />
27
+ </Menu>
28
+ );
29
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { TrashIcon } from '@elementor/icons';
3
+ import { Page } from '../../../types';
4
+ import { useActiveDocument } from '@elementor/editor-documents';
5
+ import { __ } from '@wordpress/i18n';
6
+ import ActionMenuItem from '../actions-menu/action-menu-item';
7
+
8
+ export default function Delete( { page }: { page: Page } ) {
9
+ const activeDocument = useActiveDocument();
10
+
11
+ const isActive = activeDocument?.id === page.id;
12
+
13
+ return (
14
+ <ActionMenuItem
15
+ title={ __( 'Delete', 'elementor' ) }
16
+ icon={ TrashIcon }
17
+ disabled={ page.isHome || isActive }
18
+ onClick={ () => null }
19
+ />
20
+ );
21
+ }
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { __ } from '@wordpress/i18n';
3
+ import { CopyIcon } from '@elementor/icons';
4
+ import ActionMenuItem from '../actions-menu/action-menu-item';
5
+
6
+ export default function Duplicate() {
7
+ return (
8
+ <ActionMenuItem
9
+ title={ __( 'Duplicate', 'elementor' ) }
10
+ icon={ CopyIcon }
11
+ onClick={ () => null }
12
+ />
13
+ );
14
+ }
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { EraseIcon } from '@elementor/icons';
3
+ import { __ } from '@wordpress/i18n';
4
+ import ActionMenuItem from '../actions-menu/action-menu-item';
5
+
6
+ export default function Rename() {
7
+ return (
8
+ <ActionMenuItem
9
+ title={ __( 'Rename', 'elementor' ) }
10
+ icon={ EraseIcon }
11
+ onClick={ () => null }
12
+ />
13
+ );
14
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { Page } from '../../../types';
3
+ import { HomeIcon } from '@elementor/icons';
4
+ import { __ } from '@wordpress/i18n';
5
+ import ActionMenuItem from '../actions-menu/action-menu-item';
6
+
7
+ export default function SetHome( { page }: { page: Page } ) {
8
+ return (
9
+ <ActionMenuItem
10
+ title={ __( 'Set as homepage', 'elementor' ) }
11
+ icon={ HomeIcon }
12
+ disabled={ !! page.isHome }
13
+ onClick={ () => null }
14
+ />
15
+ );
16
+ }
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { EyeIcon } from '@elementor/icons';
3
+ import { __ } from '@wordpress/i18n';
4
+ import ActionMenuItem from '../actions-menu/action-menu-item';
5
+
6
+ export default function View() {
7
+ return (
8
+ <ActionMenuItem
9
+ title={ __( 'View Page', 'elementor' ) } // TODO 21/06/2023 : post label should come from post type
10
+ icon={ EyeIcon }
11
+ onClick={ () => null }
12
+ />
13
+ );
14
+ }
@@ -0,0 +1,110 @@
1
+ import * as React from 'react';
2
+ import { act, render } from '@testing-library/react';
3
+ import { Page } from '../../../../types';
4
+ import PageListItem from '../page-list-item';
5
+ import { useNavigateToDocument } from '@elementor/editor-documents';
6
+
7
+ jest.mock( '@elementor/editor-documents', () => ( {
8
+ useActiveDocument: jest.fn(),
9
+ useNavigateToDocument: jest.fn(),
10
+ } ) );
11
+
12
+ describe( '@elementor/editor-site-navigation - PageListItem', () => {
13
+ afterAll( () => {
14
+ jest.clearAllMocks();
15
+ } );
16
+
17
+ it( 'should render a published post', () => {
18
+ // Arrange.
19
+ const page: Page = {
20
+ id: 1,
21
+ title: 'Test Post',
22
+ status: 'publish',
23
+ type: 'page',
24
+ };
25
+
26
+ // Act.
27
+ const { getByText, queryByText } = render( <PageListItem page={ page } /> );
28
+
29
+ // Assert.
30
+ const label = getByText( 'Test Post' );
31
+ const publishedLabel = queryByText( 'publish', { exact: false } );
32
+
33
+ expect( label ).toBeInTheDocument();
34
+ expect( publishedLabel ).toBeNull();
35
+ } );
36
+
37
+ it( 'should show the post status for non-published posts', () => {
38
+ // Arrange.
39
+ const page: Page = {
40
+ id: 1,
41
+ title: 'Test Post',
42
+ status: 'draft',
43
+ type: 'page',
44
+ };
45
+
46
+ // Act.
47
+ const { getByText } = render( <PageListItem page={ page } /> );
48
+
49
+ // Assert.
50
+ const label = getByText( 'draft', { exact: false } );
51
+ expect( label ).toBeInTheDocument();
52
+ } );
53
+
54
+ it( 'should render actions menu', () => {
55
+ // Arrange.
56
+ const page: Page = {
57
+ id: 1,
58
+ title: 'Test Post',
59
+ status: 'draft',
60
+ type: 'page',
61
+ };
62
+
63
+ const actions = [ 'View Page', 'Rename', 'Duplicate', 'Delete', 'Set as homepage' ];
64
+
65
+ // Act.
66
+ const { getByText, getAllByRole } = render( <PageListItem page={ page } /> );
67
+ const buttons = getAllByRole( 'button' );
68
+ // Button to open menu
69
+ const button = buttons[ 1 ];
70
+
71
+ act( () => {
72
+ // Open menu
73
+ button.click();
74
+ } );
75
+
76
+ // Assert.
77
+ actions.forEach( ( action ) => {
78
+ const label = getByText( action );
79
+ expect( label ).toBeInTheDocument();
80
+ } );
81
+ } );
82
+
83
+ it( 'should navigate to document on click', () => {
84
+ // Arrange.
85
+ const navigateToDocument = jest.fn();
86
+ jest.mocked( useNavigateToDocument ).mockReturnValue( navigateToDocument );
87
+
88
+ const id = 10;
89
+
90
+ const page: Page = {
91
+ id,
92
+ title: 'Test Post',
93
+ status: 'draft',
94
+ type: 'page',
95
+ };
96
+
97
+ // Act.
98
+ const { getAllByRole } = render( <PageListItem page={ page } /> );
99
+ const buttons = getAllByRole( 'button' );
100
+ const button = buttons[ 0 ];
101
+
102
+ act( () => {
103
+ button.click();
104
+ } );
105
+
106
+ // Assert.
107
+ expect( navigateToDocument ).toHaveBeenCalledTimes( 1 );
108
+ expect( navigateToDocument ).toHaveBeenCalledWith( id );
109
+ } );
110
+ } );