@elementor/editor-site-navigation 0.8.1 → 0.9.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
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.9.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.8.1...@elementor/editor-site-navigation@0.9.0) (2023-06-26)
7
+
8
+
9
+ ### Features
10
+
11
+ * added panel infrastructure to pages panel [ED-10863] ([#65](https://github.com/elementor/elementor-packages/issues/65)) ([e743522](https://github.com/elementor/elementor-packages/commit/e743522558b9e7cdf40e2c2dcf71e4049c815992))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.8.1](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.8.0...@elementor/editor-site-navigation@0.8.1) (2023-06-25)
7
18
 
8
19
 
package/dist/index.js CHANGED
@@ -248,12 +248,19 @@ function RecentlyEdited() {
248
248
 
249
249
  // src/init.ts
250
250
  var import_editor_app_bar = require("@elementor/editor-app-bar");
251
- var import_editor = require("@elementor/editor");
251
+
252
+ // src/hooks/useToggleButtonProps.ts
253
+ var import_i18n9 = require("@wordpress/i18n");
254
+ var import_icons14 = require("@elementor/icons");
255
+
256
+ // src/components/panel/panel.ts
257
+ var import_editor_panels2 = require("@elementor/editor-panels");
252
258
 
253
259
  // src/components/panel/shell.tsx
254
260
  var React18 = __toESM(require("react"));
255
261
  var import_ui12 = require("@elementor/ui");
256
262
  var import_icons13 = require("@elementor/icons");
263
+ var import_editor_panels = require("@elementor/editor-panels");
257
264
 
258
265
  // src/components/panel/pages-list/pages-collapsible-list.tsx
259
266
  var React17 = __toESM(require("react"));
@@ -271,6 +278,31 @@ var RotateIcon = (0, import_ui6.styled)(import_icons5.ChevronDownIcon, {
271
278
  duration: theme.transitions.duration.standard
272
279
  })
273
280
  }));
281
+ function CollapsibleList({
282
+ label,
283
+ Icon,
284
+ isOpenByDefault = false,
285
+ children
286
+ }) {
287
+ const [isOpen, setIsOpen] = (0, import_react4.useState)(isOpenByDefault);
288
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(import_ui6.ListItem, { disableGutters: true }, /* @__PURE__ */ React6.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React6.createElement(
289
+ import_ui6.IconButton,
290
+ {
291
+ onClick: () => setIsOpen((prev) => !prev),
292
+ sx: { color: "inherit" },
293
+ size: "small"
294
+ },
295
+ /* @__PURE__ */ React6.createElement(RotateIcon, { fontSize: "small", isOpen })
296
+ )), /* @__PURE__ */ React6.createElement(import_ui6.ListItemIcon, null, /* @__PURE__ */ React6.createElement(Icon, null)), /* @__PURE__ */ React6.createElement(import_ui6.ListItemText, null, label)), /* @__PURE__ */ React6.createElement(
297
+ import_ui6.Collapse,
298
+ {
299
+ in: isOpen,
300
+ timeout: "auto",
301
+ unmountOnExit: true
302
+ },
303
+ /* @__PURE__ */ React6.createElement(import_ui6.List, { dense: true }, children)
304
+ ));
305
+ }
274
306
 
275
307
  // src/components/panel/pages-list/pages-collapsible-list.tsx
276
308
  var import_icons12 = require("@elementor/icons");
@@ -284,6 +316,45 @@ var import_editor_documents5 = require("@elementor/editor-documents");
284
316
  // src/components/shared/page-title-and-status.tsx
285
317
  var React7 = __toESM(require("react"));
286
318
  var import_ui7 = require("@elementor/ui");
319
+ var PageStatus = ({ status }) => {
320
+ if ("publish" === status) {
321
+ return null;
322
+ }
323
+ return /* @__PURE__ */ React7.createElement(
324
+ import_ui7.Typography,
325
+ {
326
+ component: "span",
327
+ variant: "body1",
328
+ sx: {
329
+ textTransform: "capitalize",
330
+ fontStyle: "italic",
331
+ whiteSpace: "nowrap",
332
+ flexBasis: "content"
333
+ }
334
+ },
335
+ "(",
336
+ status,
337
+ ")"
338
+ );
339
+ };
340
+ var PageTitle = ({ title }) => {
341
+ const modifiedTitle = useReverseHtmlEntities(title);
342
+ return /* @__PURE__ */ React7.createElement(
343
+ import_ui7.Typography,
344
+ {
345
+ component: "span",
346
+ variant: "body1",
347
+ noWrap: true,
348
+ sx: {
349
+ flexBasis: "auto"
350
+ }
351
+ },
352
+ modifiedTitle
353
+ );
354
+ };
355
+ function PageTitleAndStatus({ page }) {
356
+ return /* @__PURE__ */ React7.createElement(import_ui7.Box, { display: "flex" }, /* @__PURE__ */ React7.createElement(PageTitle, { title: page.title }), "\xA0", /* @__PURE__ */ React7.createElement(PageStatus, { status: page.status }));
357
+ }
287
358
 
288
359
  // src/components/panel/actions-menu/page-actions-menu.tsx
289
360
  var React15 = __toESM(require("react"));
@@ -300,34 +371,251 @@ var React9 = __toESM(require("react"));
300
371
  // src/components/panel/actions-menu/action-list-item.tsx
301
372
  var React8 = __toESM(require("react"));
302
373
  var import_ui8 = require("@elementor/ui");
374
+ function ActionListItem({ title, icon: Icon, disabled, onClick }) {
375
+ return /* @__PURE__ */ React8.createElement(
376
+ import_ui8.ListItemButton,
377
+ {
378
+ disabled,
379
+ onClick
380
+ },
381
+ /* @__PURE__ */ React8.createElement(import_ui8.ListItemIcon, null, /* @__PURE__ */ React8.createElement(Icon, null)),
382
+ /* @__PURE__ */ React8.createElement(import_ui8.ListItemText, null, title)
383
+ );
384
+ }
303
385
 
304
386
  // src/components/panel/actions-menu/action-menu-item.tsx
305
387
  var import_ui9 = require("@elementor/ui");
388
+ function ActionMenuItem(props) {
389
+ return /* @__PURE__ */ React9.createElement(import_ui9.MenuItem, { disableGutters: true }, /* @__PURE__ */ React9.createElement(ActionListItem, { ...props }));
390
+ }
391
+
392
+ // src/components/panel/pages-actions/rename.tsx
393
+ function Rename() {
394
+ return /* @__PURE__ */ React10.createElement(
395
+ ActionMenuItem,
396
+ {
397
+ title: (0, import_i18n3.__)("Rename", "elementor"),
398
+ icon: import_icons6.EraseIcon,
399
+ onClick: () => null
400
+ }
401
+ );
402
+ }
306
403
 
307
404
  // src/components/panel/pages-actions/duplicate.tsx
308
405
  var React11 = __toESM(require("react"));
309
406
  var import_i18n4 = require("@wordpress/i18n");
310
407
  var import_icons7 = require("@elementor/icons");
408
+ function Duplicate() {
409
+ return /* @__PURE__ */ React11.createElement(
410
+ ActionMenuItem,
411
+ {
412
+ title: (0, import_i18n4.__)("Duplicate", "elementor"),
413
+ icon: import_icons7.CopyIcon,
414
+ onClick: () => null
415
+ }
416
+ );
417
+ }
311
418
 
312
419
  // src/components/panel/pages-actions/delete.tsx
313
420
  var React12 = __toESM(require("react"));
314
421
  var import_icons8 = require("@elementor/icons");
315
422
  var import_editor_documents4 = require("@elementor/editor-documents");
316
423
  var import_i18n5 = require("@wordpress/i18n");
424
+ function Delete({ page }) {
425
+ const activeDocument = (0, import_editor_documents4.useActiveDocument)();
426
+ const isActive = activeDocument?.id === page.id;
427
+ return /* @__PURE__ */ React12.createElement(
428
+ ActionMenuItem,
429
+ {
430
+ title: (0, import_i18n5.__)("Delete", "elementor"),
431
+ icon: import_icons8.TrashIcon,
432
+ disabled: page.isHome || isActive,
433
+ onClick: () => null
434
+ }
435
+ );
436
+ }
317
437
 
318
438
  // src/components/panel/pages-actions/view.tsx
319
439
  var React13 = __toESM(require("react"));
320
440
  var import_icons9 = require("@elementor/icons");
321
441
  var import_i18n6 = require("@wordpress/i18n");
442
+ function View() {
443
+ return /* @__PURE__ */ React13.createElement(
444
+ ActionMenuItem,
445
+ {
446
+ title: (0, import_i18n6.__)("View Page", "elementor"),
447
+ icon: import_icons9.EyeIcon,
448
+ onClick: () => null
449
+ }
450
+ );
451
+ }
322
452
 
323
453
  // src/components/panel/pages-actions/set-home.tsx
324
454
  var React14 = __toESM(require("react"));
325
455
  var import_icons10 = require("@elementor/icons");
326
456
  var import_i18n7 = require("@wordpress/i18n");
457
+ function SetHome({ page }) {
458
+ return /* @__PURE__ */ React14.createElement(
459
+ ActionMenuItem,
460
+ {
461
+ title: (0, import_i18n7.__)("Set as homepage", "elementor"),
462
+ icon: import_icons10.HomeIcon,
463
+ disabled: !!page.isHome,
464
+ onClick: () => null
465
+ }
466
+ );
467
+ }
468
+
469
+ // src/components/panel/actions-menu/page-actions-menu.tsx
470
+ function PageActionsMenu({ page, ...props }) {
471
+ return /* @__PURE__ */ React15.createElement(
472
+ import_ui10.Menu,
473
+ {
474
+ PaperProps: { sx: { mt: 4, width: 200 } },
475
+ MenuListProps: { dense: true },
476
+ ...props
477
+ },
478
+ /* @__PURE__ */ React15.createElement(Rename, null),
479
+ /* @__PURE__ */ React15.createElement(Duplicate, null),
480
+ /* @__PURE__ */ React15.createElement(Delete, { page }),
481
+ /* @__PURE__ */ React15.createElement(View, null),
482
+ /* @__PURE__ */ React15.createElement(import_ui10.Divider, null),
483
+ /* @__PURE__ */ React15.createElement(SetHome, { page })
484
+ );
485
+ }
486
+
487
+ // src/components/panel/pages-list/page-list-item.tsx
488
+ function PageListItem({ page }) {
489
+ const popupState = (0, import_ui11.usePopupState)({
490
+ variant: "popover",
491
+ popupId: "page-actions"
492
+ });
493
+ const activeDocument = (0, import_editor_documents5.useActiveDocument)();
494
+ const navigateToDocument = (0, import_editor_documents5.useNavigateToDocument)();
495
+ const isActive = activeDocument?.id === page.id;
496
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
497
+ import_ui11.ListItem,
498
+ {
499
+ disablePadding: true,
500
+ secondaryAction: /* @__PURE__ */ React16.createElement(
501
+ import_ui11.ToggleButton,
502
+ {
503
+ value: true,
504
+ color: "secondary",
505
+ size: "small",
506
+ selected: popupState.isOpen,
507
+ ...(0, import_ui11.bindTrigger)(popupState)
508
+ },
509
+ /* @__PURE__ */ React16.createElement(import_icons11.DotsVerticalIcon, { fontSize: "small" })
510
+ )
511
+ },
512
+ /* @__PURE__ */ React16.createElement(
513
+ import_ui11.ListItemButton,
514
+ {
515
+ selected: isActive,
516
+ onClick: () => navigateToDocument(page.id),
517
+ dense: true
518
+ },
519
+ /* @__PURE__ */ React16.createElement(import_ui11.ListItemIcon, null),
520
+ /* @__PURE__ */ React16.createElement(
521
+ import_ui11.ListItemText,
522
+ {
523
+ disableTypography: true
524
+ },
525
+ /* @__PURE__ */ React16.createElement(PageTitleAndStatus, { page })
526
+ ),
527
+ page.isHome && /* @__PURE__ */ React16.createElement(import_ui11.ListItemIcon, null, /* @__PURE__ */ React16.createElement(import_icons11.HomeIcon, { color: "disabled" }))
528
+ )
529
+ ), /* @__PURE__ */ React16.createElement(PageActionsMenu, { page, ...(0, import_ui11.bindMenu)(popupState) }));
530
+ }
531
+
532
+ // src/components/panel/pages-list/pages-collapsible-list.tsx
533
+ function PagesCollapsibleList({ pages, isOpenByDefault = false }) {
534
+ const label = `Pages (${pages.length})`;
535
+ return /* @__PURE__ */ React17.createElement(
536
+ CollapsibleList,
537
+ {
538
+ label,
539
+ Icon: import_icons12.PageTypeIcon,
540
+ isOpenByDefault
541
+ },
542
+ pages.map((page) => /* @__PURE__ */ React17.createElement(PageListItem, { key: page.id, page }))
543
+ );
544
+ }
545
+
546
+ // src/components/panel/shell.tsx
547
+ var import_i18n8 = require("@wordpress/i18n");
548
+ var mockPages = [
549
+ {
550
+ id: 1,
551
+ type: "page",
552
+ title: "This is a very long title that somebody wrote, a very very long line",
553
+ status: "pending approval"
554
+ },
555
+ { id: 2, type: "page", title: "About", status: "publish" },
556
+ { id: 3, type: "page", title: "Services", status: "publish", isHome: true },
557
+ { id: 4, type: "page", title: "Contact", status: "draft" },
558
+ { id: 5, type: "page", title: "FAQ", status: "publish" }
559
+ ];
560
+ var Shell = () => {
561
+ return /* @__PURE__ */ React18.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React18.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React18.createElement(import_editor_panels.PanelHeaderTitle, null, (0, import_i18n8.__)("Pages", "elementor"))), /* @__PURE__ */ React18.createElement(import_editor_panels.PanelBody, null, /* @__PURE__ */ React18.createElement(
562
+ import_ui12.Box,
563
+ {
564
+ display: "flex",
565
+ justifyContent: "flex-end",
566
+ alignItems: "center"
567
+ },
568
+ /* @__PURE__ */ React18.createElement(
569
+ import_ui12.Button,
570
+ {
571
+ sx: { mt: 4, mb: 4, mr: 5 },
572
+ startIcon: /* @__PURE__ */ React18.createElement(import_icons13.PlusIcon, null)
573
+ },
574
+ "Add New"
575
+ )
576
+ ), /* @__PURE__ */ React18.createElement(import_ui12.List, { dense: true }, /* @__PURE__ */ React18.createElement(PagesCollapsibleList, { pages: mockPages, isOpenByDefault: true }))));
577
+ };
578
+ var shell_default = Shell;
579
+
580
+ // src/components/panel/panel.ts
581
+ var {
582
+ panel,
583
+ usePanelStatus,
584
+ usePanelActions
585
+ } = (0, import_editor_panels2.createPanel)({
586
+ id: "site-navigation-panel",
587
+ component: shell_default
588
+ });
589
+
590
+ // src/hooks/useToggleButtonProps.ts
591
+ function useToggleButtonProps() {
592
+ const { isOpen, isBlocked } = usePanelStatus();
593
+ const { open, close } = usePanelActions();
594
+ return {
595
+ title: (0, import_i18n9.__)("Pages", "elementor"),
596
+ icon: import_icons14.PagesIcon,
597
+ onClick: () => isOpen ? close() : open(),
598
+ selected: isOpen,
599
+ disabled: isBlocked
600
+ };
601
+ }
602
+
603
+ // src/init.ts
604
+ var import_editor_panels3 = require("@elementor/editor-panels");
605
+
606
+ // src/env.ts
607
+ var import_env = require("@elementor/env");
608
+ var { env, validateEnv } = (0, import_env.parseEnv)("@elementor/editor-site-navigation", (envData) => {
609
+ return envData;
610
+ });
327
611
 
328
612
  // src/init.ts
329
613
  function init() {
330
614
  registerTopBarMenuItems();
615
+ if (env.is_panel_active) {
616
+ (0, import_editor_panels3.registerPanel)(panel);
617
+ registerButton();
618
+ }
331
619
  }
332
620
  function registerTopBarMenuItems() {
333
621
  (0, import_editor_app_bar.injectIntoPageIndication)({
@@ -335,6 +623,13 @@ function registerTopBarMenuItems() {
335
623
  filler: RecentlyEdited
336
624
  });
337
625
  }
626
+ function registerButton() {
627
+ import_editor_app_bar.toolsMenu.registerToggleAction({
628
+ id: "toggle-site-navigation-panel",
629
+ priority: 2,
630
+ useProps: useToggleButtonProps
631
+ });
632
+ }
338
633
 
339
634
  // src/index.ts
340
635
  init();
package/dist/index.mjs CHANGED
@@ -229,13 +229,20 @@ function RecentlyEdited() {
229
229
  }
230
230
 
231
231
  // src/init.ts
232
- import { injectIntoPageIndication } from "@elementor/editor-app-bar";
233
- import { injectIntoTop } from "@elementor/editor";
232
+ import { injectIntoPageIndication, toolsMenu } from "@elementor/editor-app-bar";
233
+
234
+ // src/hooks/useToggleButtonProps.ts
235
+ import { __ as __9 } from "@wordpress/i18n";
236
+ import { PagesIcon } from "@elementor/icons";
237
+
238
+ // src/components/panel/panel.ts
239
+ import { createPanel } from "@elementor/editor-panels";
234
240
 
235
241
  // src/components/panel/shell.tsx
236
242
  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";
243
+ import { Box as Box3, Button as Button2, List as List2 } from "@elementor/ui";
238
244
  import { PlusIcon as PlusIcon2 } from "@elementor/icons";
245
+ import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from "@elementor/editor-panels";
239
246
 
240
247
  // src/components/panel/pages-list/pages-collapsible-list.tsx
241
248
  import * as React17 from "react";
@@ -253,6 +260,31 @@ var RotateIcon = styled(ChevronDownIcon2, {
253
260
  duration: theme.transitions.duration.standard
254
261
  })
255
262
  }));
263
+ function CollapsibleList({
264
+ label,
265
+ Icon,
266
+ isOpenByDefault = false,
267
+ children
268
+ }) {
269
+ const [isOpen, setIsOpen] = useState3(isOpenByDefault);
270
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ListItem, { disableGutters: true }, /* @__PURE__ */ React6.createElement(ListItemIcon2, null, /* @__PURE__ */ React6.createElement(
271
+ IconButton,
272
+ {
273
+ onClick: () => setIsOpen((prev) => !prev),
274
+ sx: { color: "inherit" },
275
+ size: "small"
276
+ },
277
+ /* @__PURE__ */ React6.createElement(RotateIcon, { fontSize: "small", isOpen })
278
+ )), /* @__PURE__ */ React6.createElement(ListItemIcon2, null, /* @__PURE__ */ React6.createElement(Icon, null)), /* @__PURE__ */ React6.createElement(ListItemText, null, label)), /* @__PURE__ */ React6.createElement(
279
+ Collapse,
280
+ {
281
+ in: isOpen,
282
+ timeout: "auto",
283
+ unmountOnExit: true
284
+ },
285
+ /* @__PURE__ */ React6.createElement(List, { dense: true }, children)
286
+ ));
287
+ }
256
288
 
257
289
  // src/components/panel/pages-list/pages-collapsible-list.tsx
258
290
  import { PageTypeIcon as PageTypeIcon2 } from "@elementor/icons";
@@ -275,6 +307,45 @@ import { useActiveDocument as useActiveDocument3, useNavigateToDocument as useNa
275
307
  // src/components/shared/page-title-and-status.tsx
276
308
  import * as React7 from "react";
277
309
  import { Box as Box2, Typography as Typography3 } from "@elementor/ui";
310
+ var PageStatus = ({ status }) => {
311
+ if ("publish" === status) {
312
+ return null;
313
+ }
314
+ return /* @__PURE__ */ React7.createElement(
315
+ Typography3,
316
+ {
317
+ component: "span",
318
+ variant: "body1",
319
+ sx: {
320
+ textTransform: "capitalize",
321
+ fontStyle: "italic",
322
+ whiteSpace: "nowrap",
323
+ flexBasis: "content"
324
+ }
325
+ },
326
+ "(",
327
+ status,
328
+ ")"
329
+ );
330
+ };
331
+ var PageTitle = ({ title }) => {
332
+ const modifiedTitle = useReverseHtmlEntities(title);
333
+ return /* @__PURE__ */ React7.createElement(
334
+ Typography3,
335
+ {
336
+ component: "span",
337
+ variant: "body1",
338
+ noWrap: true,
339
+ sx: {
340
+ flexBasis: "auto"
341
+ }
342
+ },
343
+ modifiedTitle
344
+ );
345
+ };
346
+ function PageTitleAndStatus({ page }) {
347
+ return /* @__PURE__ */ React7.createElement(Box2, { display: "flex" }, /* @__PURE__ */ React7.createElement(PageTitle, { title: page.title }), "\xA0", /* @__PURE__ */ React7.createElement(PageStatus, { status: page.status }));
348
+ }
278
349
 
279
350
  // src/components/panel/actions-menu/page-actions-menu.tsx
280
351
  import * as React15 from "react";
@@ -291,34 +362,251 @@ import * as React9 from "react";
291
362
  // src/components/panel/actions-menu/action-list-item.tsx
292
363
  import * as React8 from "react";
293
364
  import { ListItemButton, ListItemIcon as ListItemIcon3, ListItemText as ListItemText2 } from "@elementor/ui";
365
+ function ActionListItem({ title, icon: Icon, disabled, onClick }) {
366
+ return /* @__PURE__ */ React8.createElement(
367
+ ListItemButton,
368
+ {
369
+ disabled,
370
+ onClick
371
+ },
372
+ /* @__PURE__ */ React8.createElement(ListItemIcon3, null, /* @__PURE__ */ React8.createElement(Icon, null)),
373
+ /* @__PURE__ */ React8.createElement(ListItemText2, null, title)
374
+ );
375
+ }
294
376
 
295
377
  // src/components/panel/actions-menu/action-menu-item.tsx
296
378
  import { MenuItem as MenuItem3 } from "@elementor/ui";
379
+ function ActionMenuItem(props) {
380
+ return /* @__PURE__ */ React9.createElement(MenuItem3, { disableGutters: true }, /* @__PURE__ */ React9.createElement(ActionListItem, { ...props }));
381
+ }
382
+
383
+ // src/components/panel/pages-actions/rename.tsx
384
+ function Rename() {
385
+ return /* @__PURE__ */ React10.createElement(
386
+ ActionMenuItem,
387
+ {
388
+ title: __3("Rename", "elementor"),
389
+ icon: EraseIcon,
390
+ onClick: () => null
391
+ }
392
+ );
393
+ }
297
394
 
298
395
  // src/components/panel/pages-actions/duplicate.tsx
299
396
  import * as React11 from "react";
300
397
  import { __ as __4 } from "@wordpress/i18n";
301
398
  import { CopyIcon } from "@elementor/icons";
399
+ function Duplicate() {
400
+ return /* @__PURE__ */ React11.createElement(
401
+ ActionMenuItem,
402
+ {
403
+ title: __4("Duplicate", "elementor"),
404
+ icon: CopyIcon,
405
+ onClick: () => null
406
+ }
407
+ );
408
+ }
302
409
 
303
410
  // src/components/panel/pages-actions/delete.tsx
304
411
  import * as React12 from "react";
305
412
  import { TrashIcon } from "@elementor/icons";
306
413
  import { useActiveDocument as useActiveDocument2 } from "@elementor/editor-documents";
307
414
  import { __ as __5 } from "@wordpress/i18n";
415
+ function Delete({ page }) {
416
+ const activeDocument = useActiveDocument2();
417
+ const isActive = activeDocument?.id === page.id;
418
+ return /* @__PURE__ */ React12.createElement(
419
+ ActionMenuItem,
420
+ {
421
+ title: __5("Delete", "elementor"),
422
+ icon: TrashIcon,
423
+ disabled: page.isHome || isActive,
424
+ onClick: () => null
425
+ }
426
+ );
427
+ }
308
428
 
309
429
  // src/components/panel/pages-actions/view.tsx
310
430
  import * as React13 from "react";
311
431
  import { EyeIcon } from "@elementor/icons";
312
432
  import { __ as __6 } from "@wordpress/i18n";
433
+ function View() {
434
+ return /* @__PURE__ */ React13.createElement(
435
+ ActionMenuItem,
436
+ {
437
+ title: __6("View Page", "elementor"),
438
+ icon: EyeIcon,
439
+ onClick: () => null
440
+ }
441
+ );
442
+ }
313
443
 
314
444
  // src/components/panel/pages-actions/set-home.tsx
315
445
  import * as React14 from "react";
316
446
  import { HomeIcon } from "@elementor/icons";
317
447
  import { __ as __7 } from "@wordpress/i18n";
448
+ function SetHome({ page }) {
449
+ return /* @__PURE__ */ React14.createElement(
450
+ ActionMenuItem,
451
+ {
452
+ title: __7("Set as homepage", "elementor"),
453
+ icon: HomeIcon,
454
+ disabled: !!page.isHome,
455
+ onClick: () => null
456
+ }
457
+ );
458
+ }
459
+
460
+ // src/components/panel/actions-menu/page-actions-menu.tsx
461
+ function PageActionsMenu({ page, ...props }) {
462
+ return /* @__PURE__ */ React15.createElement(
463
+ Menu2,
464
+ {
465
+ PaperProps: { sx: { mt: 4, width: 200 } },
466
+ MenuListProps: { dense: true },
467
+ ...props
468
+ },
469
+ /* @__PURE__ */ React15.createElement(Rename, null),
470
+ /* @__PURE__ */ React15.createElement(Duplicate, null),
471
+ /* @__PURE__ */ React15.createElement(Delete, { page }),
472
+ /* @__PURE__ */ React15.createElement(View, null),
473
+ /* @__PURE__ */ React15.createElement(Divider2, null),
474
+ /* @__PURE__ */ React15.createElement(SetHome, { page })
475
+ );
476
+ }
477
+
478
+ // src/components/panel/pages-list/page-list-item.tsx
479
+ function PageListItem({ page }) {
480
+ const popupState = usePopupState2({
481
+ variant: "popover",
482
+ popupId: "page-actions"
483
+ });
484
+ const activeDocument = useActiveDocument3();
485
+ const navigateToDocument = useNavigateToDocument3();
486
+ const isActive = activeDocument?.id === page.id;
487
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
488
+ ListItem2,
489
+ {
490
+ disablePadding: true,
491
+ secondaryAction: /* @__PURE__ */ React16.createElement(
492
+ ToggleButton,
493
+ {
494
+ value: true,
495
+ color: "secondary",
496
+ size: "small",
497
+ selected: popupState.isOpen,
498
+ ...bindTrigger2(popupState)
499
+ },
500
+ /* @__PURE__ */ React16.createElement(DotsVerticalIcon, { fontSize: "small" })
501
+ )
502
+ },
503
+ /* @__PURE__ */ React16.createElement(
504
+ ListItemButton2,
505
+ {
506
+ selected: isActive,
507
+ onClick: () => navigateToDocument(page.id),
508
+ dense: true
509
+ },
510
+ /* @__PURE__ */ React16.createElement(ListItemIcon4, null),
511
+ /* @__PURE__ */ React16.createElement(
512
+ ListItemText3,
513
+ {
514
+ disableTypography: true
515
+ },
516
+ /* @__PURE__ */ React16.createElement(PageTitleAndStatus, { page })
517
+ ),
518
+ page.isHome && /* @__PURE__ */ React16.createElement(ListItemIcon4, null, /* @__PURE__ */ React16.createElement(HomeIcon2, { color: "disabled" }))
519
+ )
520
+ ), /* @__PURE__ */ React16.createElement(PageActionsMenu, { page, ...bindMenu2(popupState) }));
521
+ }
522
+
523
+ // src/components/panel/pages-list/pages-collapsible-list.tsx
524
+ function PagesCollapsibleList({ pages, isOpenByDefault = false }) {
525
+ const label = `Pages (${pages.length})`;
526
+ return /* @__PURE__ */ React17.createElement(
527
+ CollapsibleList,
528
+ {
529
+ label,
530
+ Icon: PageTypeIcon2,
531
+ isOpenByDefault
532
+ },
533
+ pages.map((page) => /* @__PURE__ */ React17.createElement(PageListItem, { key: page.id, page }))
534
+ );
535
+ }
536
+
537
+ // src/components/panel/shell.tsx
538
+ import { __ as __8 } from "@wordpress/i18n";
539
+ var mockPages = [
540
+ {
541
+ id: 1,
542
+ type: "page",
543
+ title: "This is a very long title that somebody wrote, a very very long line",
544
+ status: "pending approval"
545
+ },
546
+ { id: 2, type: "page", title: "About", status: "publish" },
547
+ { id: 3, type: "page", title: "Services", status: "publish", isHome: true },
548
+ { id: 4, type: "page", title: "Contact", status: "draft" },
549
+ { id: 5, type: "page", title: "FAQ", status: "publish" }
550
+ ];
551
+ var Shell = () => {
552
+ return /* @__PURE__ */ React18.createElement(Panel, null, /* @__PURE__ */ React18.createElement(PanelHeader, null, /* @__PURE__ */ React18.createElement(PanelHeaderTitle, null, __8("Pages", "elementor"))), /* @__PURE__ */ React18.createElement(PanelBody, null, /* @__PURE__ */ React18.createElement(
553
+ Box3,
554
+ {
555
+ display: "flex",
556
+ justifyContent: "flex-end",
557
+ alignItems: "center"
558
+ },
559
+ /* @__PURE__ */ React18.createElement(
560
+ Button2,
561
+ {
562
+ sx: { mt: 4, mb: 4, mr: 5 },
563
+ startIcon: /* @__PURE__ */ React18.createElement(PlusIcon2, null)
564
+ },
565
+ "Add New"
566
+ )
567
+ ), /* @__PURE__ */ React18.createElement(List2, { dense: true }, /* @__PURE__ */ React18.createElement(PagesCollapsibleList, { pages: mockPages, isOpenByDefault: true }))));
568
+ };
569
+ var shell_default = Shell;
570
+
571
+ // src/components/panel/panel.ts
572
+ var {
573
+ panel,
574
+ usePanelStatus,
575
+ usePanelActions
576
+ } = createPanel({
577
+ id: "site-navigation-panel",
578
+ component: shell_default
579
+ });
580
+
581
+ // src/hooks/useToggleButtonProps.ts
582
+ function useToggleButtonProps() {
583
+ const { isOpen, isBlocked } = usePanelStatus();
584
+ const { open, close } = usePanelActions();
585
+ return {
586
+ title: __9("Pages", "elementor"),
587
+ icon: PagesIcon,
588
+ onClick: () => isOpen ? close() : open(),
589
+ selected: isOpen,
590
+ disabled: isBlocked
591
+ };
592
+ }
593
+
594
+ // src/init.ts
595
+ import { registerPanel } from "@elementor/editor-panels";
596
+
597
+ // src/env.ts
598
+ import { parseEnv } from "@elementor/env";
599
+ var { env, validateEnv } = parseEnv("@elementor/editor-site-navigation", (envData) => {
600
+ return envData;
601
+ });
318
602
 
319
603
  // src/init.ts
320
604
  function init() {
321
605
  registerTopBarMenuItems();
606
+ if (env.is_panel_active) {
607
+ registerPanel(panel);
608
+ registerButton();
609
+ }
322
610
  }
323
611
  function registerTopBarMenuItems() {
324
612
  injectIntoPageIndication({
@@ -326,6 +614,13 @@ function registerTopBarMenuItems() {
326
614
  filler: RecentlyEdited
327
615
  });
328
616
  }
617
+ function registerButton() {
618
+ toolsMenu.registerToggleAction({
619
+ id: "toggle-site-navigation-panel",
620
+ priority: 2,
621
+ useProps: useToggleButtonProps
622
+ });
623
+ }
329
624
 
330
625
  // src/index.ts
331
626
  init();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-site-navigation",
3
- "version": "0.8.1",
3
+ "version": "0.9.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": "^0.6.1",
36
- "@elementor/editor-app-bar": "^0.6.3",
35
+ "@elementor/editor-app-bar": "^0.6.4",
37
36
  "@elementor/editor-documents": "^0.8.2",
38
- "@elementor/icons": "^0.5.0",
37
+ "@elementor/editor-panels": "^0.1.1",
38
+ "@elementor/env": "^0.2.0",
39
+ "@elementor/icons": "^0.6.0",
39
40
  "@elementor/ui": "^1.4.53",
40
41
  "@wordpress/api-fetch": "^6.27.0",
41
42
  "@wordpress/i18n": "^4.31.0",
@@ -47,5 +48,5 @@
47
48
  "elementor": {
48
49
  "type": "extension"
49
50
  },
50
- "gitHead": "ada7204a85dbd362c29518f8ab28defe6942a4b7"
51
+ "gitHead": "ed96d6908a9c9d3bab7fe15df52dba55bd64dff5"
51
52
  }
@@ -0,0 +1,11 @@
1
+ import { createPanel } from '@elementor/editor-panels';
2
+ import Shell from './shell';
3
+
4
+ export const {
5
+ panel,
6
+ usePanelStatus,
7
+ usePanelActions,
8
+ } = createPanel( {
9
+ id: 'site-navigation-panel',
10
+ component: Shell,
11
+ } );
@@ -1,8 +1,10 @@
1
1
  import * as React from 'react';
2
- import { Box, Button, Divider, Grid, List, Paper, ThemeProvider, Typography } from '@elementor/ui';
2
+ import { Box, Button, List } from '@elementor/ui';
3
3
  import { PlusIcon } from '@elementor/icons';
4
4
  import { Page } from '../../types';
5
+ import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from '@elementor/editor-panels';
5
6
  import PagesCollapsibleList from './pages-list/pages-collapsible-list';
7
+ import { __ } from '@wordpress/i18n';
6
8
 
7
9
  // TODO: Remove once connected to real data fetching.
8
10
  const mockPages: Page[] = [
@@ -20,38 +22,28 @@ const mockPages: Page[] = [
20
22
 
21
23
  const Shell = () => {
22
24
  return (
23
- <ThemeProvider colorScheme="light">
24
- <Box sx={ { width: '100%', maxWidth: 360 } }>
25
- <Paper>
26
- <Grid
27
- container
28
- justifyContent="center"
29
- alignItems="center"
30
- sx={ { height: 51 } }>
31
- <Typography variant="h6">Pages</Typography>
32
- </Grid>
33
- <Divider />
34
- <Box
35
- display="flex"
36
- justifyContent="flex-end"
37
- alignItems="center"
25
+ <Panel>
26
+ <PanelHeader>
27
+ <PanelHeaderTitle>{ __( 'Pages', 'elementor' ) }</PanelHeaderTitle>
28
+ </PanelHeader>
29
+ <PanelBody>
30
+ <Box
31
+ display="flex"
32
+ justifyContent="flex-end"
33
+ alignItems="center"
34
+ >
35
+ <Button
36
+ sx={ { mt: 4, mb: 4, mr: 5 } }
37
+ startIcon={ <PlusIcon /> }
38
38
  >
39
- <Button
40
- sx={ { mt: 4, mb: 4, mr: 5 } }
41
- startIcon={ <PlusIcon /> }
42
- >
43
- Add New
44
- </Button>
45
- </Box>
46
- <Box sx={ { width: '100%', maxWidth: 360 } }>
47
- <List dense>
48
- <PagesCollapsibleList pages={ mockPages } isOpenByDefault={ true } />
49
- </List>
50
- </Box>
51
- <Divider />
52
- </Paper>
53
- </Box>
54
- </ThemeProvider>
39
+ Add New
40
+ </Button>
41
+ </Box>
42
+ <List dense>
43
+ <PagesCollapsibleList pages={ mockPages } isOpenByDefault={ true } />
44
+ </List>
45
+ </PanelBody>
46
+ </Panel>
55
47
  );
56
48
  };
57
49
 
package/src/env.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { parseEnv } from '@elementor/env';
2
+
3
+ export const { env, validateEnv } = parseEnv<{
4
+ is_panel_active: boolean;
5
+ }>( '@elementor/editor-site-navigation', ( envData ) => {
6
+ return envData as {
7
+ is_panel_active: boolean;
8
+ };
9
+ } );
@@ -0,0 +1,20 @@
1
+ import { __ } from '@wordpress/i18n';
2
+ import { PagesIcon } from '@elementor/icons';
3
+ import { usePanelActions, usePanelStatus } from '../components/panel/panel';
4
+
5
+ export function useToggleButtonProps() {
6
+ const { isOpen, isBlocked } = usePanelStatus();
7
+ const { open, close } = usePanelActions();
8
+
9
+ return {
10
+ title: __( 'Pages', 'elementor' ),
11
+ icon: PagesIcon,
12
+ onClick: () => (
13
+ isOpen
14
+ ? close()
15
+ : open()
16
+ ),
17
+ selected: isOpen,
18
+ disabled: isBlocked,
19
+ };
20
+ }
package/src/init.ts CHANGED
@@ -1,12 +1,17 @@
1
1
  import RecentlyEdited from './components/top-bar/recently-edited';
2
- import { injectIntoPageIndication } from '@elementor/editor-app-bar';
3
- import { injectIntoTop } from '@elementor/editor';
4
- import Shell from './components/panel/shell';
2
+ import { injectIntoPageIndication, toolsMenu } from '@elementor/editor-app-bar';
3
+ import { useToggleButtonProps } from './hooks/useToggleButtonProps';
4
+ import { registerPanel } from '@elementor/editor-panels';
5
+ import { panel } from './components/panel/panel';
6
+ import { env } from './env';
5
7
 
6
8
  export default function init() {
7
9
  registerTopBarMenuItems();
8
- // TODO 06/06/2023 : uncomment registerPanel() when we are ready to release
9
- // registerPanel();
10
+ // TODO 06/06/2023 : remove if when we are production ready
11
+ if ( env.is_panel_active ) {
12
+ registerPanel( panel );
13
+ registerButton();
14
+ }
10
15
  }
11
16
 
12
17
  function registerTopBarMenuItems() {
@@ -16,10 +21,10 @@ function registerTopBarMenuItems() {
16
21
  } );
17
22
  }
18
23
 
19
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
- function registerPanel() {
21
- injectIntoTop( {
22
- id: 'navigation-panel',
23
- filler: Shell,
24
+ function registerButton() {
25
+ toolsMenu.registerToggleAction( {
26
+ id: 'toggle-site-navigation-panel',
27
+ priority: 2,
28
+ useProps: useToggleButtonProps,
24
29
  } );
25
30
  }