@elementor/editor-site-navigation 0.17.1 → 0.18.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.18.1](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.18.0...@elementor/editor-site-navigation@0.18.1) (2023-08-02)
7
+
8
+ **Note:** Version bump only for package @elementor/editor-site-navigation
9
+
10
+
11
+
12
+
13
+
14
+ # [0.18.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.17.1...@elementor/editor-site-navigation@0.18.0) (2023-08-02)
15
+
16
+
17
+ ### Features
18
+
19
+ * **site-navigation:** pages panel UI changes [ED-11348] ([#98](https://github.com/elementor/elementor-packages/issues/98)) ([d07930c](https://github.com/elementor/elementor-packages/commit/d07930c1c70c90ea59152648bfc5fe405a1f50e3))
20
+
21
+
22
+
23
+
24
+
6
25
  ## [0.17.1](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.17.0...@elementor/editor-site-navigation@0.17.1) (2023-08-01)
7
26
 
8
27
  **Note:** Version bump only for package @elementor/editor-site-navigation
package/dist/index.js CHANGED
@@ -258,14 +258,13 @@ var import_editor_panels2 = require("@elementor/editor-panels");
258
258
 
259
259
  // src/components/panel/shell.tsx
260
260
  var React23 = __toESM(require("react"));
261
- var import_ui15 = require("@elementor/ui");
262
261
  var import_editor_panels = require("@elementor/editor-panels");
263
262
  var import_i18n14 = require("@wordpress/i18n");
264
263
 
265
264
  // src/components/panel/posts-list/posts-collapsible-list.tsx
266
- var React21 = __toESM(require("react"));
267
- var import_icons13 = require("@elementor/icons");
268
- var import_ui13 = require("@elementor/ui");
265
+ var React22 = __toESM(require("react"));
266
+ var import_icons14 = require("@elementor/icons");
267
+ var import_ui14 = require("@elementor/ui");
269
268
 
270
269
  // src/hooks/use-posts.ts
271
270
  var import_query = require("@elementor/query");
@@ -392,7 +391,7 @@ function CollapsibleList({
392
391
  children
393
392
  }) {
394
393
  const [isOpen, setIsOpen] = (0, import_react5.useState)(isOpenByDefault);
395
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(import_ui6.ListItem, { disableGutters: true }, /* @__PURE__ */ React7.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React7.createElement(
394
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(import_ui6.ListItem, null, /* @__PURE__ */ React7.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React7.createElement(
396
395
  import_ui6.IconButton,
397
396
  {
398
397
  onClick: () => setIsOpen((prev) => !prev),
@@ -400,7 +399,7 @@ function CollapsibleList({
400
399
  size: "small"
401
400
  },
402
401
  /* @__PURE__ */ React7.createElement(RotateIcon, { fontSize: "small", isOpen })
403
- )), /* @__PURE__ */ React7.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React7.createElement(Icon, null)), /* @__PURE__ */ React7.createElement(import_ui6.ListItemText, null, label)), /* @__PURE__ */ React7.createElement(
402
+ )), /* @__PURE__ */ React7.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React7.createElement(Icon, null)), /* @__PURE__ */ React7.createElement(import_ui6.ListItemText, { primaryTypographyProps: { variant: "subtitle1", component: "span", sx: { fontWeight: "bold" } }, primary: label })), /* @__PURE__ */ React7.createElement(
404
403
  import_ui6.Collapse,
405
404
  {
406
405
  in: isOpen,
@@ -408,7 +407,7 @@ function CollapsibleList({
408
407
  unmountOnExit: true
409
408
  },
410
409
  /* @__PURE__ */ React7.createElement(import_ui6.List, { dense: true }, children)
411
- ));
410
+ ), /* @__PURE__ */ React7.createElement(import_ui6.Divider, { sx: { my: 3 } }));
412
411
  }
413
412
 
414
413
  // src/components/panel/posts-list/post-list-item.tsx
@@ -490,22 +489,23 @@ function EditModeTemplate({ postTitle, isLoading, callback }) {
490
489
  return /* @__PURE__ */ React8.createElement(
491
490
  import_ui7.ListItem,
492
491
  {
493
- selected: true,
494
- disablePadding: true,
492
+ sx: { pt: 1, pl: 0 },
495
493
  secondaryAction: /* @__PURE__ */ React8.createElement(CloseButton, { isLoading, closeButton })
496
494
  },
497
- /* @__PURE__ */ React8.createElement(import_ui7.ListItemIcon, null),
498
- /* @__PURE__ */ React8.createElement(import_ui7.Box, { component: "form", onSubmit: onFormSubmit }, /* @__PURE__ */ React8.createElement(
495
+ /* @__PURE__ */ React8.createElement(import_ui7.Box, { width: "100%", sx: { ml: 4, pr: 3 }, component: "form", onSubmit: onFormSubmit }, /* @__PURE__ */ React8.createElement(
499
496
  import_ui7.TextField,
500
497
  {
501
498
  autoFocus: true,
499
+ fullWidth: true,
502
500
  ref: inputRef,
503
501
  defaultValue: postTitle,
504
502
  disabled: isLoading,
505
503
  error: !!inputError,
506
504
  onBlur,
507
505
  variant: "outlined",
508
- size: "small"
506
+ color: "secondary",
507
+ size: "small",
508
+ margin: "dense"
509
509
  }
510
510
  ))
511
511
  );
@@ -516,6 +516,7 @@ function CloseButton({ isLoading, closeButton }) {
516
516
  import_ui7.IconButton,
517
517
  {
518
518
  size: "small",
519
+ color: "secondary",
519
520
  onClick: resetEditMode,
520
521
  ref: closeButton,
521
522
  disabled: isLoading
@@ -547,16 +548,19 @@ function ListItemRename({ post }) {
547
548
  // src/components/panel/posts-list/list-items/list-item-create.tsx
548
549
  var React10 = __toESM(require("react"));
549
550
  var import_i18n5 = require("@wordpress/i18n");
551
+ var import_editor_documents4 = require("@elementor/editor-documents");
550
552
  function ListItemCreate() {
551
553
  const { type, resetEditMode } = usePostListContext();
552
554
  const { createPost } = usePostActions(type);
555
+ const navigateToDocument = (0, import_editor_documents4.useNavigateToDocument)();
553
556
  const createPostCallback = (inputValue) => {
554
557
  createPost.mutateAsync({
555
558
  title: inputValue,
556
559
  status: "draft"
557
560
  }, {
558
- onSuccess: () => {
561
+ onSuccess: (data) => {
559
562
  resetEditMode();
563
+ navigateToDocument(data.id);
560
564
  }
561
565
  });
562
566
  };
@@ -566,8 +570,10 @@ function ListItemCreate() {
566
570
  // src/components/panel/posts-list/list-items/list-item-duplicate.tsx
567
571
  var React11 = __toESM(require("react"));
568
572
  var import_i18n6 = require("@wordpress/i18n");
573
+ var import_editor_documents5 = require("@elementor/editor-documents");
569
574
  function ListItemDuplicate() {
570
575
  const { type, editMode, resetEditMode } = usePostListContext();
576
+ const navigateToDocument = (0, import_editor_documents5.useNavigateToDocument)();
571
577
  const { duplicatePost } = usePostActions(type);
572
578
  if ("duplicate" !== editMode.mode) {
573
579
  return null;
@@ -577,8 +583,9 @@ function ListItemDuplicate() {
577
583
  id: editMode.details.postId,
578
584
  title: inputValue
579
585
  }, {
580
- onSuccess: () => {
586
+ onSuccess: (data) => {
581
587
  resetEditMode();
588
+ navigateToDocument(data.post_id);
582
589
  }
583
590
  });
584
591
  };
@@ -589,7 +596,7 @@ function ListItemDuplicate() {
589
596
  var React19 = __toESM(require("react"));
590
597
  var import_ui12 = require("@elementor/ui");
591
598
  var import_icons12 = require("@elementor/icons");
592
- var import_editor_documents5 = require("@elementor/editor-documents");
599
+ var import_editor_documents7 = require("@elementor/editor-documents");
593
600
 
594
601
  // src/components/shared/page-title-and-status.tsx
595
602
  var React12 = __toESM(require("react"));
@@ -602,7 +609,7 @@ var PageStatus = ({ status }) => {
602
609
  import_ui8.Typography,
603
610
  {
604
611
  component: "span",
605
- variant: "body1",
612
+ variant: "body2",
606
613
  sx: {
607
614
  textTransform: "capitalize",
608
615
  fontStyle: "italic",
@@ -621,7 +628,7 @@ var PageTitle = ({ title }) => {
621
628
  import_ui8.Typography,
622
629
  {
623
630
  component: "span",
624
- variant: "body1",
631
+ variant: "body2",
625
632
  noWrap: true,
626
633
  sx: {
627
634
  flexBasis: "auto"
@@ -709,10 +716,10 @@ var import_icons9 = require("@elementor/icons");
709
716
  var import_i18n9 = require("@wordpress/i18n");
710
717
  var import_ui10 = require("@elementor/ui");
711
718
  var import_react7 = require("react");
712
- var import_editor_documents4 = require("@elementor/editor-documents");
719
+ var import_editor_documents6 = require("@elementor/editor-documents");
713
720
  function Delete({ post }) {
714
721
  const [isDialogOpen, setIsDialogOpen] = (0, import_react7.useState)(false);
715
- const activeDocument = (0, import_editor_documents4.useActiveDocument)();
722
+ const activeDocument = (0, import_editor_documents6.useActiveDocument)();
716
723
  const isPostActive = activeDocument?.id === post.id;
717
724
  return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
718
725
  ActionMenuItem,
@@ -730,7 +737,7 @@ function Delete({ post }) {
730
737
  function DeleteDialog({ post, setIsDialogOpen }) {
731
738
  const { type } = usePostListContext();
732
739
  const { deletePost } = usePostActions(type);
733
- const dialogTitle = (0, import_i18n9.sprintf)((0, import_i18n9.__)("Delete \u201C%s\u201D?", "elementor"), post.title.rendered);
740
+ const dialogTitle = (0, import_i18n9.sprintf)((0, import_i18n9.__)('Delete "%s"?', "elementor"), post.title.rendered);
734
741
  const deletePage = async () => {
735
742
  await deletePost.mutateAsync(post.id);
736
743
  };
@@ -747,7 +754,7 @@ function DeleteDialog({ post, setIsDialogOpen }) {
747
754
  onClose: handleCancel,
748
755
  "aria-labelledby": "delete-dialog"
749
756
  },
750
- /* @__PURE__ */ React16.createElement(import_ui10.DialogTitle, null, dialogTitle),
757
+ /* @__PURE__ */ React16.createElement(import_ui10.DialogTitle, { noWrap: true }, dialogTitle),
751
758
  /* @__PURE__ */ React16.createElement(import_ui10.Divider, null),
752
759
  /* @__PURE__ */ React16.createElement(import_ui10.DialogContent, null, /* @__PURE__ */ React16.createElement(import_ui10.DialogContentText, null, (0, import_i18n9.__)("The page and its content will be deleted forever and we won\u2019t be able to recover them.", "elementor"))),
753
760
  /* @__PURE__ */ React16.createElement(import_ui10.DialogActions, null, /* @__PURE__ */ React16.createElement(import_ui10.Button, { variant: "contained", color: "secondary", onClick: handleCancel, disabled: deletePost.isLoading }, (0, import_i18n9.__)("Cancel", "elementor")), /* @__PURE__ */ React16.createElement(import_ui10.Button, { variant: "contained", color: "error", onClick: deletePage, disabled: deletePost.isLoading }, !deletePost.isLoading ? (0, import_i18n9.__)("Delete", "elementor") : /* @__PURE__ */ React16.createElement(import_ui10.CircularProgress, null)))
@@ -851,8 +858,8 @@ function SetHome({ post }) {
851
858
  // src/components/panel/posts-list/list-items/list-item-view.tsx
852
859
  var import_i18n12 = require("@wordpress/i18n");
853
860
  function ListItemView({ post }) {
854
- const activeDocument = (0, import_editor_documents5.useActiveDocument)();
855
- const navigateToDocument = (0, import_editor_documents5.useNavigateToDocument)();
861
+ const activeDocument = (0, import_editor_documents7.useActiveDocument)();
862
+ const navigateToDocument = (0, import_editor_documents7.useNavigateToDocument)();
856
863
  const popupState = (0, import_ui12.usePopupState)({
857
864
  variant: "popover",
858
865
  popupId: "post-actions",
@@ -867,6 +874,7 @@ function ListItemView({ post }) {
867
874
  import_ui12.ToggleButton,
868
875
  {
869
876
  value: true,
877
+ color: "secondary",
870
878
  size: "small",
871
879
  selected: popupState.isOpen,
872
880
  ...(0, import_ui12.bindTrigger)(popupState)
@@ -883,7 +891,8 @@ function ListItemView({ post }) {
883
891
  navigateToDocument(post.id);
884
892
  }
885
893
  },
886
- dense: true
894
+ dense: true,
895
+ disableGutters: true
887
896
  },
888
897
  /* @__PURE__ */ React19.createElement(import_ui12.ListItemIcon, null),
889
898
  /* @__PURE__ */ React19.createElement(
@@ -898,7 +907,7 @@ function ListItemView({ post }) {
898
907
  ), /* @__PURE__ */ React19.createElement(
899
908
  import_ui12.Menu,
900
909
  {
901
- PaperProps: { sx: { mt: 4, width: 200 } },
910
+ PaperProps: { sx: { mt: 2, width: 200 } },
902
911
  MenuListProps: { dense: true },
903
912
  ...(0, import_ui12.bindMenu)(popupState)
904
913
  },
@@ -929,64 +938,72 @@ function PostListItem2({ post }) {
929
938
  return /* @__PURE__ */ React20.createElement(ListItemView, { post });
930
939
  }
931
940
 
941
+ // src/components/panel/add-new-button.tsx
942
+ var React21 = __toESM(require("react"));
943
+ var import_ui13 = require("@elementor/ui");
944
+ var import_icons13 = require("@elementor/icons");
945
+ var import_i18n13 = require("@wordpress/i18n");
946
+ function AddNewButton() {
947
+ const { setEditMode } = usePostListContext();
948
+ return /* @__PURE__ */ React21.createElement(
949
+ import_ui13.Button,
950
+ {
951
+ size: "small",
952
+ sx: { mt: 4, mb: 4, mr: 5 },
953
+ startIcon: /* @__PURE__ */ React21.createElement(import_icons13.PlusIcon, null),
954
+ onClick: () => {
955
+ setEditMode({ mode: "create", details: {} });
956
+ }
957
+ },
958
+ (0, import_i18n13.__)("Add New", "elementor")
959
+ );
960
+ }
961
+
932
962
  // src/components/panel/posts-list/posts-collapsible-list.tsx
933
963
  function PostsCollapsibleList({ isOpenByDefault = false }) {
934
964
  const { type, editMode } = usePostListContext();
935
965
  const { data: posts, isLoading: postsLoading } = usePosts(type);
936
966
  const { data: homepageSettings } = useHomepage();
937
967
  if (!posts || postsLoading) {
938
- return /* @__PURE__ */ React21.createElement(import_ui13.Box, { spacing: 4, sx: { px: 6 } }, /* @__PURE__ */ React21.createElement(import_ui13.Skeleton, { variant: "text", sx: { fontSize: "2rem" } }), /* @__PURE__ */ React21.createElement(import_ui13.Skeleton, { variant: "rounded", width: "100%", height: "48" }));
968
+ return /* @__PURE__ */ React22.createElement(import_ui14.Box, { sx: { px: 5 } }, /* @__PURE__ */ React22.createElement(
969
+ import_ui14.Box,
970
+ {
971
+ display: "flex",
972
+ justifyContent: "flex-end",
973
+ alignItems: "center"
974
+ },
975
+ /* @__PURE__ */ React22.createElement(import_ui14.Skeleton, { sx: { my: 4 }, animation: "wave", variant: "rounded", width: "110px", height: "28px" })
976
+ ), /* @__PURE__ */ React22.createElement(import_ui14.Box, null, /* @__PURE__ */ React22.createElement(import_ui14.Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "100%", height: "24px" }), /* @__PURE__ */ React22.createElement(import_ui14.Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" }), /* @__PURE__ */ React22.createElement(import_ui14.Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" }), /* @__PURE__ */ React22.createElement(import_ui14.Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" })));
939
977
  }
940
978
  const label = `${postTypesMap[type].labels.plural_name} (${posts.length.toString()})`;
941
979
  const isHomepageSet = homepageSettings?.show_on_front === "page" && !!homepageSettings?.page_on_front;
942
980
  const homepageId = isHomepageSet ? homepageSettings.page_on_front : null;
943
- return /* @__PURE__ */ React21.createElement(import_ui13.List, { dense: true }, /* @__PURE__ */ React21.createElement(
981
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(
982
+ import_ui14.Box,
983
+ {
984
+ display: "flex",
985
+ justifyContent: "flex-end",
986
+ alignItems: "center"
987
+ },
988
+ /* @__PURE__ */ React22.createElement(AddNewButton, null)
989
+ ), /* @__PURE__ */ React22.createElement(import_ui14.List, { dense: true }, /* @__PURE__ */ React22.createElement(
944
990
  CollapsibleList,
945
991
  {
946
992
  label,
947
- Icon: import_icons13.PageTypeIcon,
993
+ Icon: import_icons14.PageTypeIcon,
948
994
  isOpenByDefault: isOpenByDefault || false
949
995
  },
950
996
  posts.map((post) => {
951
997
  post = { ...post, isHome: post.id === homepageId };
952
- return /* @__PURE__ */ React21.createElement(PostListItem2, { key: post.id, post });
998
+ return /* @__PURE__ */ React22.createElement(PostListItem2, { key: post.id, post });
953
999
  }),
954
- ["duplicate", "create"].includes(editMode.mode) && /* @__PURE__ */ React21.createElement(PostListItem2, null)
955
- ));
956
- }
957
-
958
- // src/components/panel/add-new-button.tsx
959
- var React22 = __toESM(require("react"));
960
- var import_ui14 = require("@elementor/ui");
961
- var import_icons14 = require("@elementor/icons");
962
- var import_i18n13 = require("@wordpress/i18n");
963
- function AddNewButton() {
964
- const { setEditMode } = usePostListContext();
965
- return /* @__PURE__ */ React22.createElement(
966
- import_ui14.Button,
967
- {
968
- size: "small",
969
- sx: { mt: 4, mb: 4, mr: 5 },
970
- startIcon: /* @__PURE__ */ React22.createElement(import_icons14.PlusIcon, null),
971
- onClick: () => {
972
- setEditMode({ mode: "create", details: {} });
973
- }
974
- },
975
- (0, import_i18n13.__)("Add New", "elementor")
976
- );
1000
+ ["duplicate", "create"].includes(editMode.mode) && /* @__PURE__ */ React22.createElement(PostListItem2, null)
1001
+ )));
977
1002
  }
978
1003
 
979
1004
  // src/components/panel/shell.tsx
980
1005
  var Shell = () => {
981
- return /* @__PURE__ */ React23.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React23.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React23.createElement(import_editor_panels.PanelHeaderTitle, null, (0, import_i18n14.__)("Pages", "elementor"))), /* @__PURE__ */ React23.createElement(import_editor_panels.PanelBody, null, /* @__PURE__ */ React23.createElement(PostListContextProvider, { type: "page" }, /* @__PURE__ */ React23.createElement(
982
- import_ui15.Box,
983
- {
984
- display: "flex",
985
- justifyContent: "flex-end",
986
- alignItems: "center"
987
- },
988
- /* @__PURE__ */ React23.createElement(AddNewButton, null)
989
- ), /* @__PURE__ */ React23.createElement(PostsCollapsibleList, { isOpenByDefault: true }))));
1006
+ return /* @__PURE__ */ React23.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React23.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React23.createElement(import_editor_panels.PanelHeaderTitle, null, (0, import_i18n14.__)("Pages", "elementor"))), /* @__PURE__ */ React23.createElement(import_editor_panels.PanelBody, null, /* @__PURE__ */ React23.createElement(PostListContextProvider, { type: "page" }, /* @__PURE__ */ React23.createElement(PostsCollapsibleList, { isOpenByDefault: true }))));
990
1007
  };
991
1008
  var shell_default = Shell;
992
1009
 
package/dist/index.mjs CHANGED
@@ -240,12 +240,11 @@ import { createPanel } from "@elementor/editor-panels";
240
240
 
241
241
  // src/components/panel/shell.tsx
242
242
  import * as React23 from "react";
243
- import { Box as Box5 } from "@elementor/ui";
244
243
  import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from "@elementor/editor-panels";
245
244
  import { __ as __14 } from "@wordpress/i18n";
246
245
 
247
246
  // src/components/panel/posts-list/posts-collapsible-list.tsx
248
- import * as React21 from "react";
247
+ import * as React22 from "react";
249
248
  import { PageTypeIcon as PageTypeIcon2 } from "@elementor/icons";
250
249
  import { Skeleton, Box as Box4, List as List2 } from "@elementor/ui";
251
250
 
@@ -357,7 +356,7 @@ function usePostListContext() {
357
356
  // src/components/panel/posts-list/collapsible-list.tsx
358
357
  import * as React7 from "react";
359
358
  import { useState as useState4 } from "react";
360
- import { Collapse, IconButton, List, ListItem, ListItemIcon as ListItemIcon2, ListItemText, styled } from "@elementor/ui";
359
+ import { Collapse, IconButton, List, ListItem, ListItemIcon as ListItemIcon2, ListItemText, styled, Divider as Divider2 } from "@elementor/ui";
361
360
  import { ChevronDownIcon as ChevronDownIcon2 } from "@elementor/icons";
362
361
  var RotateIcon = styled(ChevronDownIcon2, {
363
362
  shouldForwardProp: (prop) => prop !== "isOpen"
@@ -374,7 +373,7 @@ function CollapsibleList({
374
373
  children
375
374
  }) {
376
375
  const [isOpen, setIsOpen] = useState4(isOpenByDefault);
377
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(ListItem, { disableGutters: true }, /* @__PURE__ */ React7.createElement(ListItemIcon2, null, /* @__PURE__ */ React7.createElement(
376
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(ListItem, null, /* @__PURE__ */ React7.createElement(ListItemIcon2, null, /* @__PURE__ */ React7.createElement(
378
377
  IconButton,
379
378
  {
380
379
  onClick: () => setIsOpen((prev) => !prev),
@@ -382,7 +381,7 @@ function CollapsibleList({
382
381
  size: "small"
383
382
  },
384
383
  /* @__PURE__ */ React7.createElement(RotateIcon, { fontSize: "small", isOpen })
385
- )), /* @__PURE__ */ React7.createElement(ListItemIcon2, null, /* @__PURE__ */ React7.createElement(Icon, null)), /* @__PURE__ */ React7.createElement(ListItemText, null, label)), /* @__PURE__ */ React7.createElement(
384
+ )), /* @__PURE__ */ React7.createElement(ListItemIcon2, null, /* @__PURE__ */ React7.createElement(Icon, null)), /* @__PURE__ */ React7.createElement(ListItemText, { primaryTypographyProps: { variant: "subtitle1", component: "span", sx: { fontWeight: "bold" } }, primary: label })), /* @__PURE__ */ React7.createElement(
386
385
  Collapse,
387
386
  {
388
387
  in: isOpen,
@@ -390,7 +389,7 @@ function CollapsibleList({
390
389
  unmountOnExit: true
391
390
  },
392
391
  /* @__PURE__ */ React7.createElement(List, { dense: true }, children)
393
- ));
392
+ ), /* @__PURE__ */ React7.createElement(Divider2, { sx: { my: 3 } }));
394
393
  }
395
394
 
396
395
  // src/components/panel/posts-list/post-list-item.tsx
@@ -441,7 +440,6 @@ import { useState as useState5, useRef } from "react";
441
440
  import {
442
441
  Box as Box2,
443
442
  ListItem as ListItem2,
444
- ListItemIcon as ListItemIcon3,
445
443
  TextField,
446
444
  IconButton as IconButton2,
447
445
  CircularProgress as CircularProgress2
@@ -479,22 +477,23 @@ function EditModeTemplate({ postTitle, isLoading, callback }) {
479
477
  return /* @__PURE__ */ React8.createElement(
480
478
  ListItem2,
481
479
  {
482
- selected: true,
483
- disablePadding: true,
480
+ sx: { pt: 1, pl: 0 },
484
481
  secondaryAction: /* @__PURE__ */ React8.createElement(CloseButton, { isLoading, closeButton })
485
482
  },
486
- /* @__PURE__ */ React8.createElement(ListItemIcon3, null),
487
- /* @__PURE__ */ React8.createElement(Box2, { component: "form", onSubmit: onFormSubmit }, /* @__PURE__ */ React8.createElement(
483
+ /* @__PURE__ */ React8.createElement(Box2, { width: "100%", sx: { ml: 4, pr: 3 }, component: "form", onSubmit: onFormSubmit }, /* @__PURE__ */ React8.createElement(
488
484
  TextField,
489
485
  {
490
486
  autoFocus: true,
487
+ fullWidth: true,
491
488
  ref: inputRef,
492
489
  defaultValue: postTitle,
493
490
  disabled: isLoading,
494
491
  error: !!inputError,
495
492
  onBlur,
496
493
  variant: "outlined",
497
- size: "small"
494
+ color: "secondary",
495
+ size: "small",
496
+ margin: "dense"
498
497
  }
499
498
  ))
500
499
  );
@@ -505,6 +504,7 @@ function CloseButton({ isLoading, closeButton }) {
505
504
  IconButton2,
506
505
  {
507
506
  size: "small",
507
+ color: "secondary",
508
508
  onClick: resetEditMode,
509
509
  ref: closeButton,
510
510
  disabled: isLoading
@@ -536,16 +536,19 @@ function ListItemRename({ post }) {
536
536
  // src/components/panel/posts-list/list-items/list-item-create.tsx
537
537
  import * as React10 from "react";
538
538
  import { __ as __5 } from "@wordpress/i18n";
539
+ import { useNavigateToDocument as useNavigateToDocument3 } from "@elementor/editor-documents";
539
540
  function ListItemCreate() {
540
541
  const { type, resetEditMode } = usePostListContext();
541
542
  const { createPost } = usePostActions(type);
543
+ const navigateToDocument = useNavigateToDocument3();
542
544
  const createPostCallback = (inputValue) => {
543
545
  createPost.mutateAsync({
544
546
  title: inputValue,
545
547
  status: "draft"
546
548
  }, {
547
- onSuccess: () => {
549
+ onSuccess: (data) => {
548
550
  resetEditMode();
551
+ navigateToDocument(data.id);
549
552
  }
550
553
  });
551
554
  };
@@ -555,8 +558,10 @@ function ListItemCreate() {
555
558
  // src/components/panel/posts-list/list-items/list-item-duplicate.tsx
556
559
  import * as React11 from "react";
557
560
  import { __ as __6 } from "@wordpress/i18n";
561
+ import { useNavigateToDocument as useNavigateToDocument4 } from "@elementor/editor-documents";
558
562
  function ListItemDuplicate() {
559
563
  const { type, editMode, resetEditMode } = usePostListContext();
564
+ const navigateToDocument = useNavigateToDocument4();
560
565
  const { duplicatePost } = usePostActions(type);
561
566
  if ("duplicate" !== editMode.mode) {
562
567
  return null;
@@ -566,8 +571,9 @@ function ListItemDuplicate() {
566
571
  id: editMode.details.postId,
567
572
  title: inputValue
568
573
  }, {
569
- onSuccess: () => {
574
+ onSuccess: (data) => {
570
575
  resetEditMode();
576
+ navigateToDocument(data.post_id);
571
577
  }
572
578
  });
573
579
  };
@@ -579,17 +585,17 @@ import * as React19 from "react";
579
585
  import {
580
586
  bindMenu as bindMenu2,
581
587
  bindTrigger as bindTrigger2,
582
- Divider as Divider3,
588
+ Divider as Divider4,
583
589
  ListItem as ListItem3,
584
590
  ListItemButton as ListItemButton2,
585
- ListItemIcon as ListItemIcon5,
591
+ ListItemIcon as ListItemIcon4,
586
592
  ListItemText as ListItemText3,
587
593
  Menu as Menu2,
588
594
  ToggleButton,
589
595
  usePopupState as usePopupState2
590
596
  } from "@elementor/ui";
591
597
  import { DotsVerticalIcon, HomeIcon as HomeIcon2 } from "@elementor/icons";
592
- import { useActiveDocument as useActiveDocument3, useNavigateToDocument as useNavigateToDocument3 } from "@elementor/editor-documents";
598
+ import { useActiveDocument as useActiveDocument3, useNavigateToDocument as useNavigateToDocument5 } from "@elementor/editor-documents";
593
599
 
594
600
  // src/components/shared/page-title-and-status.tsx
595
601
  import * as React12 from "react";
@@ -602,7 +608,7 @@ var PageStatus = ({ status }) => {
602
608
  Typography3,
603
609
  {
604
610
  component: "span",
605
- variant: "body1",
611
+ variant: "body2",
606
612
  sx: {
607
613
  textTransform: "capitalize",
608
614
  fontStyle: "italic",
@@ -621,7 +627,7 @@ var PageTitle = ({ title }) => {
621
627
  Typography3,
622
628
  {
623
629
  component: "span",
624
- variant: "body1",
630
+ variant: "body2",
625
631
  noWrap: true,
626
632
  sx: {
627
633
  flexBasis: "auto"
@@ -641,14 +647,19 @@ import { __ as __7 } from "@wordpress/i18n";
641
647
 
642
648
  // src/components/panel/actions-menu/action-menu-item.tsx
643
649
  import * as React13 from "react";
644
- import { ListItemButton, ListItemIcon as ListItemIcon4, ListItemText as ListItemText2, MenuItem as MenuItem3 } from "@elementor/ui";
650
+ import {
651
+ ListItemButton,
652
+ ListItemIcon as ListItemIcon3,
653
+ ListItemText as ListItemText2,
654
+ MenuItem as MenuItem3
655
+ } from "@elementor/ui";
645
656
  function ActionMenuItem({ title, icon: Icon, ListItemButtonProps }) {
646
657
  return /* @__PURE__ */ React13.createElement(MenuItem3, { disableGutters: true }, /* @__PURE__ */ React13.createElement(
647
658
  ListItemButton,
648
659
  {
649
660
  ...ListItemButtonProps
650
661
  },
651
- /* @__PURE__ */ React13.createElement(ListItemIcon4, null, /* @__PURE__ */ React13.createElement(Icon, null)),
662
+ /* @__PURE__ */ React13.createElement(ListItemIcon3, null, /* @__PURE__ */ React13.createElement(Icon, null)),
652
663
  /* @__PURE__ */ React13.createElement(ListItemText2, null, title)
653
664
  ));
654
665
  }
@@ -715,7 +726,7 @@ import {
715
726
  DialogContent,
716
727
  DialogContentText,
717
728
  DialogTitle,
718
- Divider as Divider2
729
+ Divider as Divider3
719
730
  } from "@elementor/ui";
720
731
  import { useState as useState6 } from "react";
721
732
  import { useActiveDocument as useActiveDocument2 } from "@elementor/editor-documents";
@@ -739,7 +750,7 @@ function Delete({ post }) {
739
750
  function DeleteDialog({ post, setIsDialogOpen }) {
740
751
  const { type } = usePostListContext();
741
752
  const { deletePost } = usePostActions(type);
742
- const dialogTitle = sprintf(__9("Delete \u201C%s\u201D?", "elementor"), post.title.rendered);
753
+ const dialogTitle = sprintf(__9('Delete "%s"?', "elementor"), post.title.rendered);
743
754
  const deletePage = async () => {
744
755
  await deletePost.mutateAsync(post.id);
745
756
  };
@@ -756,8 +767,8 @@ function DeleteDialog({ post, setIsDialogOpen }) {
756
767
  onClose: handleCancel,
757
768
  "aria-labelledby": "delete-dialog"
758
769
  },
759
- /* @__PURE__ */ React16.createElement(DialogTitle, null, dialogTitle),
760
- /* @__PURE__ */ React16.createElement(Divider2, null),
770
+ /* @__PURE__ */ React16.createElement(DialogTitle, { noWrap: true }, dialogTitle),
771
+ /* @__PURE__ */ React16.createElement(Divider3, null),
761
772
  /* @__PURE__ */ React16.createElement(DialogContent, null, /* @__PURE__ */ React16.createElement(DialogContentText, null, __9("The page and its content will be deleted forever and we won\u2019t be able to recover them.", "elementor"))),
762
773
  /* @__PURE__ */ React16.createElement(DialogActions, null, /* @__PURE__ */ React16.createElement(Button2, { variant: "contained", color: "secondary", onClick: handleCancel, disabled: deletePost.isLoading }, __9("Cancel", "elementor")), /* @__PURE__ */ React16.createElement(Button2, { variant: "contained", color: "error", onClick: deletePage, disabled: deletePost.isLoading }, !deletePost.isLoading ? __9("Delete", "elementor") : /* @__PURE__ */ React16.createElement(CircularProgress3, null)))
763
774
  );
@@ -861,7 +872,7 @@ function SetHome({ post }) {
861
872
  import { __ as __12 } from "@wordpress/i18n";
862
873
  function ListItemView({ post }) {
863
874
  const activeDocument = useActiveDocument3();
864
- const navigateToDocument = useNavigateToDocument3();
875
+ const navigateToDocument = useNavigateToDocument5();
865
876
  const popupState = usePopupState2({
866
877
  variant: "popover",
867
878
  popupId: "post-actions",
@@ -876,6 +887,7 @@ function ListItemView({ post }) {
876
887
  ToggleButton,
877
888
  {
878
889
  value: true,
890
+ color: "secondary",
879
891
  size: "small",
880
892
  selected: popupState.isOpen,
881
893
  ...bindTrigger2(popupState)
@@ -892,9 +904,10 @@ function ListItemView({ post }) {
892
904
  navigateToDocument(post.id);
893
905
  }
894
906
  },
895
- dense: true
907
+ dense: true,
908
+ disableGutters: true
896
909
  },
897
- /* @__PURE__ */ React19.createElement(ListItemIcon5, null),
910
+ /* @__PURE__ */ React19.createElement(ListItemIcon4, null),
898
911
  /* @__PURE__ */ React19.createElement(
899
912
  ListItemText3,
900
913
  {
@@ -902,12 +915,12 @@ function ListItemView({ post }) {
902
915
  },
903
916
  /* @__PURE__ */ React19.createElement(PageTitleAndStatus, { page: post })
904
917
  ),
905
- post.isHome && /* @__PURE__ */ React19.createElement(ListItemIcon5, null, /* @__PURE__ */ React19.createElement(HomeIcon2, { titleAccess: __12("Homepage", "elementor"), color: "disabled" }))
918
+ post.isHome && /* @__PURE__ */ React19.createElement(ListItemIcon4, null, /* @__PURE__ */ React19.createElement(HomeIcon2, { titleAccess: __12("Homepage", "elementor"), color: "disabled" }))
906
919
  )
907
920
  ), /* @__PURE__ */ React19.createElement(
908
921
  Menu2,
909
922
  {
910
- PaperProps: { sx: { mt: 4, width: 200 } },
923
+ PaperProps: { sx: { mt: 2, width: 200 } },
911
924
  MenuListProps: { dense: true },
912
925
  ...bindMenu2(popupState)
913
926
  },
@@ -915,7 +928,7 @@ function ListItemView({ post }) {
915
928
  /* @__PURE__ */ React19.createElement(Duplicate, { post, popupState }),
916
929
  /* @__PURE__ */ React19.createElement(Delete, { post }),
917
930
  /* @__PURE__ */ React19.createElement(View, { post }),
918
- /* @__PURE__ */ React19.createElement(Divider3, null),
931
+ /* @__PURE__ */ React19.createElement(Divider4, null),
919
932
  /* @__PURE__ */ React19.createElement(SetHome, { post })
920
933
  ));
921
934
  }
@@ -938,45 +951,19 @@ function PostListItem2({ post }) {
938
951
  return /* @__PURE__ */ React20.createElement(ListItemView, { post });
939
952
  }
940
953
 
941
- // src/components/panel/posts-list/posts-collapsible-list.tsx
942
- function PostsCollapsibleList({ isOpenByDefault = false }) {
943
- const { type, editMode } = usePostListContext();
944
- const { data: posts, isLoading: postsLoading } = usePosts(type);
945
- const { data: homepageSettings } = useHomepage();
946
- if (!posts || postsLoading) {
947
- return /* @__PURE__ */ React21.createElement(Box4, { spacing: 4, sx: { px: 6 } }, /* @__PURE__ */ React21.createElement(Skeleton, { variant: "text", sx: { fontSize: "2rem" } }), /* @__PURE__ */ React21.createElement(Skeleton, { variant: "rounded", width: "100%", height: "48" }));
948
- }
949
- const label = `${postTypesMap[type].labels.plural_name} (${posts.length.toString()})`;
950
- const isHomepageSet = homepageSettings?.show_on_front === "page" && !!homepageSettings?.page_on_front;
951
- const homepageId = isHomepageSet ? homepageSettings.page_on_front : null;
952
- return /* @__PURE__ */ React21.createElement(List2, { dense: true }, /* @__PURE__ */ React21.createElement(
953
- CollapsibleList,
954
- {
955
- label,
956
- Icon: PageTypeIcon2,
957
- isOpenByDefault: isOpenByDefault || false
958
- },
959
- posts.map((post) => {
960
- post = { ...post, isHome: post.id === homepageId };
961
- return /* @__PURE__ */ React21.createElement(PostListItem2, { key: post.id, post });
962
- }),
963
- ["duplicate", "create"].includes(editMode.mode) && /* @__PURE__ */ React21.createElement(PostListItem2, null)
964
- ));
965
- }
966
-
967
954
  // src/components/panel/add-new-button.tsx
968
- import * as React22 from "react";
955
+ import * as React21 from "react";
969
956
  import { Button as Button3 } from "@elementor/ui";
970
957
  import { PlusIcon as PlusIcon2 } from "@elementor/icons";
971
958
  import { __ as __13 } from "@wordpress/i18n";
972
959
  function AddNewButton() {
973
960
  const { setEditMode } = usePostListContext();
974
- return /* @__PURE__ */ React22.createElement(
961
+ return /* @__PURE__ */ React21.createElement(
975
962
  Button3,
976
963
  {
977
964
  size: "small",
978
965
  sx: { mt: 4, mb: 4, mr: 5 },
979
- startIcon: /* @__PURE__ */ React22.createElement(PlusIcon2, null),
966
+ startIcon: /* @__PURE__ */ React21.createElement(PlusIcon2, null),
980
967
  onClick: () => {
981
968
  setEditMode({ mode: "create", details: {} });
982
969
  }
@@ -985,17 +972,51 @@ function AddNewButton() {
985
972
  );
986
973
  }
987
974
 
988
- // src/components/panel/shell.tsx
989
- var Shell = () => {
990
- return /* @__PURE__ */ React23.createElement(Panel, null, /* @__PURE__ */ React23.createElement(PanelHeader, null, /* @__PURE__ */ React23.createElement(PanelHeaderTitle, null, __14("Pages", "elementor"))), /* @__PURE__ */ React23.createElement(PanelBody, null, /* @__PURE__ */ React23.createElement(PostListContextProvider, { type: "page" }, /* @__PURE__ */ React23.createElement(
991
- Box5,
975
+ // src/components/panel/posts-list/posts-collapsible-list.tsx
976
+ function PostsCollapsibleList({ isOpenByDefault = false }) {
977
+ const { type, editMode } = usePostListContext();
978
+ const { data: posts, isLoading: postsLoading } = usePosts(type);
979
+ const { data: homepageSettings } = useHomepage();
980
+ if (!posts || postsLoading) {
981
+ return /* @__PURE__ */ React22.createElement(Box4, { sx: { px: 5 } }, /* @__PURE__ */ React22.createElement(
982
+ Box4,
983
+ {
984
+ display: "flex",
985
+ justifyContent: "flex-end",
986
+ alignItems: "center"
987
+ },
988
+ /* @__PURE__ */ React22.createElement(Skeleton, { sx: { my: 4 }, animation: "wave", variant: "rounded", width: "110px", height: "28px" })
989
+ ), /* @__PURE__ */ React22.createElement(Box4, null, /* @__PURE__ */ React22.createElement(Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "100%", height: "24px" }), /* @__PURE__ */ React22.createElement(Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" }), /* @__PURE__ */ React22.createElement(Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" }), /* @__PURE__ */ React22.createElement(Skeleton, { sx: { my: 3 }, animation: "wave", variant: "rounded", width: "70%", height: "24px" })));
990
+ }
991
+ const label = `${postTypesMap[type].labels.plural_name} (${posts.length.toString()})`;
992
+ const isHomepageSet = homepageSettings?.show_on_front === "page" && !!homepageSettings?.page_on_front;
993
+ const homepageId = isHomepageSet ? homepageSettings.page_on_front : null;
994
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(
995
+ Box4,
992
996
  {
993
997
  display: "flex",
994
998
  justifyContent: "flex-end",
995
999
  alignItems: "center"
996
1000
  },
997
- /* @__PURE__ */ React23.createElement(AddNewButton, null)
998
- ), /* @__PURE__ */ React23.createElement(PostsCollapsibleList, { isOpenByDefault: true }))));
1001
+ /* @__PURE__ */ React22.createElement(AddNewButton, null)
1002
+ ), /* @__PURE__ */ React22.createElement(List2, { dense: true }, /* @__PURE__ */ React22.createElement(
1003
+ CollapsibleList,
1004
+ {
1005
+ label,
1006
+ Icon: PageTypeIcon2,
1007
+ isOpenByDefault: isOpenByDefault || false
1008
+ },
1009
+ posts.map((post) => {
1010
+ post = { ...post, isHome: post.id === homepageId };
1011
+ return /* @__PURE__ */ React22.createElement(PostListItem2, { key: post.id, post });
1012
+ }),
1013
+ ["duplicate", "create"].includes(editMode.mode) && /* @__PURE__ */ React22.createElement(PostListItem2, null)
1014
+ )));
1015
+ }
1016
+
1017
+ // src/components/panel/shell.tsx
1018
+ var Shell = () => {
1019
+ return /* @__PURE__ */ React23.createElement(Panel, null, /* @__PURE__ */ React23.createElement(PanelHeader, null, /* @__PURE__ */ React23.createElement(PanelHeaderTitle, null, __14("Pages", "elementor"))), /* @__PURE__ */ React23.createElement(PanelBody, null, /* @__PURE__ */ React23.createElement(PostListContextProvider, { type: "page" }, /* @__PURE__ */ React23.createElement(PostsCollapsibleList, { isOpenByDefault: true }))));
999
1020
  };
1000
1021
  var shell_default = Shell;
1001
1022
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-site-navigation",
3
- "version": "0.17.1",
3
+ "version": "0.18.1",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -32,9 +32,9 @@
32
32
  "dev": "tsup --config=../../tsup.dev.ts"
33
33
  },
34
34
  "dependencies": {
35
- "@elementor/editor-app-bar": "^0.7.0",
35
+ "@elementor/editor-app-bar": "^0.7.1",
36
36
  "@elementor/editor-documents": "^0.8.3",
37
- "@elementor/editor-panels": "^0.1.6",
37
+ "@elementor/editor-panels": "^0.2.1",
38
38
  "@elementor/env": "^0.2.0",
39
39
  "@elementor/icons": "^0.7.0",
40
40
  "@elementor/query": "^0.1.1",
@@ -49,5 +49,5 @@
49
49
  "elementor": {
50
50
  "type": "extension"
51
51
  },
52
- "gitHead": "3a35a0487b8a72853b7f307fed47fd72ea311d06"
52
+ "gitHead": "43abed846a5beaf6b0c6c5a8420c81a5bea33152"
53
53
  }
package/src/api/post.ts CHANGED
@@ -44,7 +44,7 @@ export const getRequest = ( postTypeSlug: Slug ) => {
44
44
  export const createRequest = ( postTypeSlug: Slug, newPost: NewPost ) => {
45
45
  const path = `/wp/v2/${ postTypesMap[ postTypeSlug ].rest_base }`;
46
46
 
47
- return apiFetch( {
47
+ return apiFetch<{ id: number }>( {
48
48
  path,
49
49
  method: 'POST',
50
50
  data: newPost,
@@ -74,7 +74,7 @@ export const deleteRequest = ( postTypeSlug: Slug, postId: number ) => {
74
74
  export const duplicateRequest = ( originalPost: UpdatePost ) => {
75
75
  const path = `/elementor/v1/site-navigation/duplicate-post`;
76
76
 
77
- return apiFetch( {
77
+ return apiFetch<{ post_id: number }>( {
78
78
  path,
79
79
  method: 'POST',
80
80
  data: {
@@ -1,5 +1,11 @@
1
1
  import * as React from 'react';
2
- import { ListItemButton, ListItemIcon, ListItemText, MenuItem, ListItemButtonProps as ListItemButtonPropsType } from '@elementor/ui';
2
+ import {
3
+ ListItemButton,
4
+ ListItemIcon,
5
+ ListItemText,
6
+ MenuItem,
7
+ ListItemButtonProps as ListItemButtonPropsType,
8
+ } from '@elementor/ui';
3
9
  import { ComponentType } from 'react';
4
10
 
5
11
  export type Props = {
@@ -45,7 +45,7 @@ describe( '@elementor/editor-site-navigation/pages-panel-actions - Delete', () =
45
45
  // Open the modal.
46
46
  fireEvent.click( button );
47
47
 
48
- const modal = screen.getByText( 'Delete Test Page”?' );
48
+ const modal = screen.getByText( 'Delete "Test Page"?' );
49
49
  expect( modal ).toBeInTheDocument();
50
50
 
51
51
  const modalButtons = screen.getAllByRole( 'button' );
@@ -52,7 +52,7 @@ function DeleteDialog( { post, setIsDialogOpen }: { post: Post, setIsDialogOpen:
52
52
  const { deletePost } = usePostActions( type );
53
53
 
54
54
  /* translators: %s: Post title. */
55
- const dialogTitle = sprintf( __( 'Delete “%s”?', 'elementor' ), post.title.rendered );
55
+ const dialogTitle = sprintf( __( 'Delete "%s"?', 'elementor' ), post.title.rendered );
56
56
 
57
57
  const deletePage = async () => {
58
58
  await deletePost.mutateAsync( post.id );
@@ -72,7 +72,7 @@ function DeleteDialog( { post, setIsDialogOpen }: { post: Post, setIsDialogOpen:
72
72
  onClose={ handleCancel }
73
73
  aria-labelledby="delete-dialog"
74
74
  >
75
- <DialogTitle>
75
+ <DialogTitle noWrap>
76
76
  { dialogTitle }
77
77
  </DialogTitle>
78
78
  <Divider />
@@ -1,9 +1,20 @@
1
1
  import * as React from 'react';
2
- import { act, screen } from '@testing-library/react';
2
+ import { act, fireEvent, screen, waitFor } from '@testing-library/react';
3
3
  import { Post } from '../../../../types';
4
4
  import PostListItem from '../post-list-item';
5
5
  import { useNavigateToDocument } from '@elementor/editor-documents';
6
6
  import { renderWithQuery } from 'test-utils';
7
+ import { PostListContextProvider } from '../../../../contexts/post-list-context';
8
+
9
+ const mockMutateAsync = jest.fn();
10
+ jest.mock( '../../../../hooks/use-posts-actions', () => ( {
11
+ usePostActions: () => ( {
12
+ updatePost: {
13
+ mutateAsync: mockMutateAsync,
14
+ isLoading: false,
15
+ },
16
+ } ),
17
+ } ) );
7
18
 
8
19
  jest.mock( '@elementor/editor-documents', () => ( {
9
20
  useActiveDocument: jest.fn(),
@@ -122,4 +133,59 @@ describe( '@elementor/editor-site-navigation - PostListItem', () => {
122
133
  expect( navigateToDocument ).toHaveBeenCalledTimes( 1 );
123
134
  expect( navigateToDocument ).toHaveBeenCalledWith( id );
124
135
  } );
136
+
137
+ it( 'should put the list item in edit mode, when "Rename" action is clicked', () => {
138
+ // Arrange.
139
+ const post: Post = {
140
+ id: 10,
141
+ title: {
142
+ rendered: 'Test Page',
143
+ },
144
+ status: 'publish',
145
+ type: 'page',
146
+ link: 'https://example.local/test-page',
147
+ };
148
+
149
+ renderWithQuery(
150
+ <PostListContextProvider type={ 'page' }>
151
+ <PostListItem post={ post } />
152
+ </PostListContextProvider>
153
+ );
154
+
155
+ // Act #1 - enter edit mode.
156
+ const buttons = screen.getAllByRole( 'button' );
157
+ fireEvent.click( buttons[ 1 ] ); // Button to open the actions' menu of the post.
158
+
159
+ const renameButton = screen.getByRole( 'button', { name: 'Rename' } );
160
+ fireEvent.click( renameButton );
161
+
162
+ // Assert.
163
+ waitFor( () => {
164
+ expect( renameButton ).not.toBeInTheDocument();
165
+ } ).then();
166
+
167
+ const input = screen.getByRole( 'textbox' );
168
+
169
+ expect( input ).toBeInTheDocument();
170
+ expect( input ).toHaveValue( 'Test Page' );
171
+
172
+ // Act #2 - rename and reset edit mode.
173
+ fireEvent.change( input, { target: { value: 'Renamed Title' } } );
174
+ fireEvent.blur( input );
175
+
176
+ // Assert.
177
+ waitFor( () => {
178
+ expect( input ).toHaveAttribute( 'aria-disabled', 'true' );
179
+ } ).then();
180
+
181
+ expect( mockMutateAsync ).toHaveBeenCalledTimes( 1 );
182
+
183
+ waitFor( () => {
184
+ expect( input ).not.toBeInTheDocument();
185
+ } ).then();
186
+
187
+ waitFor( () => {
188
+ expect( screen.getByText( 'Renamed Title' ) ).toBeInTheDocument();
189
+ } ).then();
190
+ } );
125
191
  } );
@@ -1,7 +1,22 @@
1
1
  import * as React from 'react';
2
- import { screen } from '@testing-library/react';
2
+ import { fireEvent, screen, waitFor } from '@testing-library/react';
3
3
  import PostsCollapsibleList from '../posts-collapsible-list';
4
4
  import { renderWithQuery } from 'test-utils';
5
+ import { PostListContextProvider } from '../../../../contexts/post-list-context';
6
+
7
+ const mockMutateAsync = jest.fn();
8
+ jest.mock( '../../../../hooks/use-posts-actions', () => ( {
9
+ usePostActions: () => ( {
10
+ createPost: {
11
+ mutateAsync: mockMutateAsync,
12
+ isLoading: false,
13
+ },
14
+ duplicatePost: {
15
+ mutateAsync: mockMutateAsync,
16
+ isLoading: false,
17
+ },
18
+ } ),
19
+ } ) );
5
20
 
6
21
  jest.mock( '../../../../hooks/use-posts', () => ( {
7
22
  __esModule: true,
@@ -66,4 +81,69 @@ describe( '@elementor/editor-site-navigation - PostsCollapsibleList', () => {
66
81
  expect( items[ 2 ] ).toHaveTextContent( 'About' );
67
82
  expect( items[ 2 ] ).toHaveTextContent( '(draft)' );
68
83
  } );
84
+
85
+ it( 'should create a new post after clicking "Add New" button', async () => {
86
+ // Arrange.
87
+ renderWithQuery(
88
+ <PostListContextProvider type={ 'page' }>
89
+ <PostsCollapsibleList isOpenByDefault={ true } />
90
+ </PostListContextProvider>
91
+ );
92
+
93
+ // Act.
94
+ const addNewButton = screen.getByRole( 'button', { name: 'Add New' } );
95
+ fireEvent.click( addNewButton );
96
+
97
+ const input = screen.getByRole( 'textbox' );
98
+
99
+ if ( ! input || ! ( input instanceof HTMLInputElement ) ) {
100
+ throw new Error( 'No input field found.' );
101
+ }
102
+
103
+ expect( input ).toHaveValue( 'New Page' );
104
+
105
+ fireEvent.change( input, { target: { value: 'New Page Title' } } );
106
+ fireEvent.blur( input );
107
+
108
+ // Assert.
109
+ waitFor( () => {
110
+ expect( input ).toHaveAttribute( 'aria-disabled', 'true' );
111
+ } ).then();
112
+
113
+ expect( mockMutateAsync ).toHaveBeenCalledTimes( 1 );
114
+
115
+ waitFor( () => {
116
+ expect( input ).not.toBeInTheDocument();
117
+ } ).then();
118
+
119
+ waitFor( () => {
120
+ expect( screen.getByText( 'New Page Title' ) ).toBeInTheDocument();
121
+ } ).then();
122
+ } );
123
+
124
+ it( 'should append a new list item in edit mode, when "Duplicate" action is clicked', () => {
125
+ // Arrange.
126
+ renderWithQuery(
127
+ <PostListContextProvider type={ 'page' }>
128
+ <PostsCollapsibleList isOpenByDefault={ true } />
129
+ </PostListContextProvider>
130
+ );
131
+
132
+ // Act.
133
+ const buttons = screen.getAllByRole( 'button' );
134
+ fireEvent.click( buttons[ 3 ] ); // Button to open the actions' menu of the first post.
135
+
136
+ const duplicateButton = screen.getByRole( 'button', { name: 'Duplicate' } );
137
+ fireEvent.click( duplicateButton );
138
+
139
+ // Assert.
140
+ waitFor( () => {
141
+ expect( duplicateButton ).not.toBeInTheDocument();
142
+ } ).then();
143
+
144
+ const input = screen.getByRole( 'textbox' );
145
+
146
+ expect( input ).toBeInTheDocument();
147
+ expect( input ).toHaveValue( 'Home copy' );
148
+ } );
69
149
  } );
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentType, PropsWithChildren, useState } from 'react';
3
- import { Collapse, IconButton, List, ListItem, ListItemIcon, ListItemText, styled, SvgIconProps } from '@elementor/ui';
3
+ import { Collapse, IconButton, List, ListItem, ListItemIcon, ListItemText, styled, SvgIconProps, Divider } from '@elementor/ui';
4
4
  import { ChevronDownIcon } from '@elementor/icons';
5
5
 
6
6
  type Props = {
@@ -35,7 +35,7 @@ export default function CollapsibleList(
35
35
 
36
36
  return (
37
37
  <>
38
- <ListItem disableGutters>
38
+ <ListItem>
39
39
  <ListItemIcon>
40
40
  <IconButton
41
41
  onClick={ () => setIsOpen( ( prev ) => ! prev ) }
@@ -48,7 +48,7 @@ export default function CollapsibleList(
48
48
  <ListItemIcon>
49
49
  <Icon />
50
50
  </ListItemIcon>
51
- <ListItemText>{ label }</ListItemText>
51
+ <ListItemText primaryTypographyProps={ { variant: 'subtitle1', component: 'span', sx: { fontWeight: 'bold' } } } primary={ label } />
52
52
  </ListItem>
53
53
  <Collapse
54
54
  in={ isOpen }
@@ -58,6 +58,7 @@ export default function CollapsibleList(
58
58
  { children }
59
59
  </List>
60
60
  </Collapse>
61
+ <Divider sx={ { my: 3 } } />
61
62
  </>
62
63
  );
63
64
  }
@@ -3,7 +3,6 @@ import { useState, useRef, FormEvent, MutableRefObject, FocusEvent } from 'react
3
3
  import {
4
4
  Box,
5
5
  ListItem,
6
- ListItemIcon,
7
6
  TextField,
8
7
  IconButton,
9
8
  CircularProgress,
@@ -57,21 +56,22 @@ export default function EditModeTemplate( { postTitle, isLoading, callback }: Pr
57
56
 
58
57
  return (
59
58
  <ListItem
60
- selected={ true }
61
- disablePadding
59
+ sx={ { pt: 1, pl: 0 } }
62
60
  secondaryAction={ <CloseButton isLoading={ isLoading } closeButton={ closeButton } /> }
63
61
  >
64
- <ListItemIcon />
65
- <Box component="form" onSubmit={ onFormSubmit }>
62
+ <Box width="100%" sx={ { ml: 4, pr: 3 } } component="form" onSubmit={ onFormSubmit }>
66
63
  <TextField
67
64
  autoFocus // eslint-disable-line jsx-a11y/no-autofocus
65
+ fullWidth
68
66
  ref={ inputRef }
69
67
  defaultValue={ postTitle }
70
68
  disabled={ isLoading }
71
69
  error={ !! inputError }
72
70
  onBlur={ onBlur }
73
71
  variant="outlined"
72
+ color="secondary"
74
73
  size="small"
74
+ margin="dense"
75
75
  />
76
76
  </Box>
77
77
  </ListItem>
@@ -89,6 +89,7 @@ function CloseButton( { isLoading, closeButton }: CloseButtonProps ) {
89
89
  return (
90
90
  <IconButton
91
91
  size="small"
92
+ color="secondary"
92
93
  onClick={ resetEditMode }
93
94
  ref={ closeButton }
94
95
  disabled={ isLoading }
@@ -3,18 +3,22 @@ import { __ } from '@wordpress/i18n';
3
3
  import { usePostListContext } from '../../../../contexts/post-list-context';
4
4
  import { usePostActions } from '../../../../hooks/use-posts-actions';
5
5
  import EditModeTemplate from './edit-mode-template';
6
+ import { useNavigateToDocument } from '@elementor/editor-documents';
6
7
 
7
8
  export default function ListItemCreate() {
8
9
  const { type, resetEditMode } = usePostListContext();
9
10
  const { createPost } = usePostActions( type );
11
+ const navigateToDocument = useNavigateToDocument();
10
12
 
11
13
  const createPostCallback = ( inputValue: string ) => {
12
14
  createPost.mutateAsync( {
13
15
  title: inputValue,
14
16
  status: 'draft',
15
17
  }, {
16
- onSuccess: () => {
18
+ onSuccess: ( data ) => {
17
19
  resetEditMode();
20
+
21
+ navigateToDocument( data.id );
18
22
  },
19
23
  } );
20
24
  };
@@ -3,9 +3,11 @@ import { __ } from '@wordpress/i18n';
3
3
  import { usePostListContext } from '../../../../contexts/post-list-context';
4
4
  import { usePostActions } from '../../../../hooks/use-posts-actions';
5
5
  import EditModeTemplate from './edit-mode-template';
6
+ import { useNavigateToDocument } from '@elementor/editor-documents';
6
7
 
7
8
  export default function ListItemDuplicate() {
8
9
  const { type, editMode, resetEditMode } = usePostListContext();
10
+ const navigateToDocument = useNavigateToDocument();
9
11
  const { duplicatePost } = usePostActions( type );
10
12
 
11
13
  if ( 'duplicate' !== editMode.mode ) {
@@ -17,8 +19,10 @@ export default function ListItemDuplicate() {
17
19
  id: editMode.details.postId,
18
20
  title: inputValue,
19
21
  }, {
20
- onSuccess: () => {
22
+ onSuccess: ( data ) => {
21
23
  resetEditMode();
24
+
25
+ navigateToDocument( data.post_id );
22
26
  },
23
27
  } );
24
28
  };
@@ -41,6 +41,7 @@ export default function ListItemView( { post }: { post: Post } ) {
41
41
  secondaryAction={
42
42
  <ToggleButton
43
43
  value
44
+ color="secondary"
44
45
  size="small"
45
46
  selected={ popupState.isOpen }
46
47
  { ...bindTrigger( popupState ) }
@@ -57,6 +58,7 @@ export default function ListItemView( { post }: { post: Post } ) {
57
58
  }
58
59
  } }
59
60
  dense
61
+ disableGutters
60
62
  >
61
63
  <ListItemIcon />
62
64
  <ListItemText
@@ -72,7 +74,7 @@ export default function ListItemView( { post }: { post: Post } ) {
72
74
  </ListItemButton>
73
75
  </ListItem>
74
76
  <Menu
75
- PaperProps={ { sx: { mt: 4, width: 200 } } }
77
+ PaperProps={ { sx: { mt: 2, width: 200 } } }
76
78
  MenuListProps={ { dense: true } }
77
79
  { ...bindMenu( popupState ) }
78
80
  >
@@ -7,6 +7,7 @@ import { postTypesMap } from '../../../api/post';
7
7
  import CollapsibleList from './collapsible-list';
8
8
  import PostListItem from './post-list-item';
9
9
  import { useHomepage } from '../../../hooks/use-homepage';
10
+ import AddNewButton from '../add-new-button';
10
11
 
11
12
  type Props = {
12
13
  isOpenByDefault?: boolean,
@@ -19,9 +20,20 @@ export default function PostsCollapsibleList( { isOpenByDefault = false }: Props
19
20
 
20
21
  if ( ! posts || postsLoading ) {
21
22
  return (
22
- <Box spacing={ 4 } sx={ { px: 6 } }>
23
- <Skeleton variant="text" sx={ { fontSize: '2rem' } } />
24
- <Skeleton variant="rounded" width="100%" height="48" />
23
+ <Box sx={ { px: 5 } }>
24
+ <Box
25
+ display="flex"
26
+ justifyContent="flex-end"
27
+ alignItems="center"
28
+ >
29
+ <Skeleton sx={ { my: 4 } } animation="wave" variant="rounded" width="110px" height="28px" />
30
+ </Box>
31
+ <Box >
32
+ <Skeleton sx={ { my: 3 } } animation="wave" variant="rounded" width="100%" height="24px" />
33
+ <Skeleton sx={ { my: 3 } } animation="wave" variant="rounded" width="70%" height="24px" />
34
+ <Skeleton sx={ { my: 3 } } animation="wave" variant="rounded" width="70%" height="24px" />
35
+ <Skeleton sx={ { my: 3 } } animation="wave" variant="rounded" width="70%" height="24px" />
36
+ </Box>
25
37
  </Box>
26
38
  );
27
39
  }
@@ -32,21 +44,30 @@ export default function PostsCollapsibleList( { isOpenByDefault = false }: Props
32
44
  const homepageId = isHomepageSet ? homepageSettings.page_on_front : null;
33
45
 
34
46
  return (
35
- <List dense>
36
- <CollapsibleList
37
- label={ label }
38
- Icon={ PageTypeIcon }
39
- isOpenByDefault={ isOpenByDefault || false }
47
+ <>
48
+ <Box
49
+ display="flex"
50
+ justifyContent="flex-end"
51
+ alignItems="center"
40
52
  >
41
- { posts.map( ( post ) => {
42
- post = { ...post, isHome: post.id === homepageId };
43
- return <PostListItem key={ post.id } post={ post } />;
44
- } ) }
45
- {
46
- [ 'duplicate', 'create' ].includes( editMode.mode ) &&
53
+ <AddNewButton />
54
+ </Box>
55
+ <List dense>
56
+ <CollapsibleList
57
+ label={ label }
58
+ Icon={ PageTypeIcon }
59
+ isOpenByDefault={ isOpenByDefault || false }
60
+ >
61
+ { posts.map( ( post ) => {
62
+ post = { ...post, isHome: post.id === homepageId };
63
+ return <PostListItem key={ post.id } post={ post } />;
64
+ } ) }
65
+ {
66
+ [ 'duplicate', 'create' ].includes( editMode.mode ) &&
47
67
  <PostListItem />
48
- }
49
- </CollapsibleList>
50
- </List>
68
+ }
69
+ </CollapsibleList>
70
+ </List>
71
+ </>
51
72
  );
52
73
  }
@@ -1,10 +1,8 @@
1
1
  import * as React from 'react';
2
- import { Box } from '@elementor/ui';
3
2
  import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from '@elementor/editor-panels';
4
3
  import { __ } from '@wordpress/i18n';
5
4
  import PostsCollapsibleList from './posts-list/posts-collapsible-list';
6
5
  import { PostListContextProvider } from '../../contexts/post-list-context';
7
- import AddNewButton from './add-new-button';
8
6
 
9
7
  const Shell = () => {
10
8
  return (
@@ -14,13 +12,6 @@ const Shell = () => {
14
12
  </PanelHeader>
15
13
  <PanelBody>
16
14
  <PostListContextProvider type={ 'page' }>
17
- <Box
18
- display="flex"
19
- justifyContent="flex-end"
20
- alignItems="center"
21
- >
22
- <AddNewButton />
23
- </Box>
24
15
  <PostsCollapsibleList isOpenByDefault={ true } />
25
16
  </PostListContextProvider>
26
17
  </PanelBody>
@@ -11,7 +11,7 @@ const PageStatus = ( { status }: { status: string } ) => {
11
11
  return (
12
12
  <Typography
13
13
  component="span"
14
- variant="body1"
14
+ variant="body2"
15
15
  sx={ {
16
16
  textTransform: 'capitalize',
17
17
  fontStyle: 'italic',
@@ -30,7 +30,7 @@ const PageTitle = ( { title }: { title: string } ) => {
30
30
  return (
31
31
  <Typography
32
32
  component="span"
33
- variant="body1"
33
+ variant="body2"
34
34
  noWrap
35
35
  sx={ {
36
36
  flexBasis: 'auto',