@elementor/editor-components 3.35.0-448 → 3.35.0-450

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
@@ -1756,6 +1756,18 @@ import { AIIcon, ComponentsIcon as ComponentsIcon2 } from "@elementor/icons";
1756
1756
  import { Box as Box11, Button as Button4, Divider as Divider3, Link as Link3, List as List3, Stack as Stack10, Typography as Typography9 } from "@elementor/ui";
1757
1757
  import { __ as __20 } from "@wordpress/i18n";
1758
1758
 
1759
+ // src/hooks/use-components-permissions.ts
1760
+ import { useCurrentUserCapabilities } from "@elementor/editor-current-user";
1761
+ var useComponentsPermissions = () => {
1762
+ const { isAdmin } = useCurrentUserCapabilities();
1763
+ return {
1764
+ canCreate: isAdmin,
1765
+ canEdit: isAdmin,
1766
+ canDelete: isAdmin,
1767
+ canRename: isAdmin
1768
+ };
1769
+ };
1770
+
1759
1771
  // src/store/actions/rename-component.ts
1760
1772
  import { getV1DocumentsManager as getV1DocumentsManager4, setDocumentModifiedStatus as setDocumentModifiedStatus3 } from "@elementor/editor-documents";
1761
1773
  import { getAllDescendants } from "@elementor/editor-elements";
@@ -1837,9 +1849,9 @@ function createComponentType(options) {
1837
1849
  };
1838
1850
  }
1839
1851
  function createComponentView(options) {
1852
+ const legacyWindow = window;
1840
1853
  return class extends createTemplatedElementView(options) {
1841
- legacyWindow = window;
1842
- eventsManagerConfig = this.legacyWindow.elementorCommon.eventsManager.config;
1854
+ eventsManagerConfig = legacyWindow.elementorCommon.eventsManager.config;
1843
1855
  #componentRenderContext;
1844
1856
  isComponentCurrentlyEdited() {
1845
1857
  const currentDocument = getCurrentDocument();
@@ -1875,9 +1887,7 @@ function createComponentView(options) {
1875
1887
  this.#componentRenderContext = {
1876
1888
  overrides: componentInstance.overrides ?? {}
1877
1889
  };
1878
- this.collection = this.legacyWindow.elementor.createBackboneElementsCollection(
1879
- componentInstance.elements
1880
- );
1890
+ this.collection = legacyWindow.elementor.createBackboneElementsCollection(componentInstance.elements);
1881
1891
  this.collection.models.forEach(setInactiveRecursively);
1882
1892
  settings.component_instance = "<template data-children-placeholder></template>";
1883
1893
  }
@@ -1911,9 +1921,7 @@ function createComponentView(options) {
1911
1921
  return newGroups;
1912
1922
  }
1913
1923
  _getContextMenuConfig() {
1914
- const legacyWindow = this.legacyWindow || window;
1915
- const elementorWithConfig = legacyWindow.elementor;
1916
- const isAdministrator = elementorWithConfig.config?.user?.is_administrator ?? false;
1924
+ const isAdministrator = isUserAdministrator();
1917
1925
  const addedGroup = {
1918
1926
  general: {
1919
1927
  index: 1,
@@ -1958,6 +1966,10 @@ function createComponentView(options) {
1958
1966
  }
1959
1967
  handleDblClick(e) {
1960
1968
  e.stopPropagation();
1969
+ const isAdministrator = isUserAdministrator();
1970
+ if (!isAdministrator) {
1971
+ return;
1972
+ }
1961
1973
  const { triggers, locations, secondaryLocations } = this.eventsManagerConfig;
1962
1974
  this.editComponent({
1963
1975
  trigger: triggers.doubleClick,
@@ -1991,6 +2003,10 @@ function setInactiveRecursively(model) {
1991
2003
  });
1992
2004
  }
1993
2005
  }
2006
+ function isUserAdministrator() {
2007
+ const legacyWindow = window;
2008
+ return legacyWindow.elementor.config?.user?.is_administrator ?? false;
2009
+ }
1994
2010
  function createComponentModel() {
1995
2011
  const legacyWindow = window;
1996
2012
  const WidgetType = legacyWindow.elementor.modules.elements.types.Widget;
@@ -2392,6 +2408,8 @@ function DeleteConfirmationDialog({ open, onClose, onConfirm }) {
2392
2408
  var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2393
2409
  const itemRef = useRef4(null);
2394
2410
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState6(false);
2411
+ const { canRename, canDelete } = useComponentsPermissions();
2412
+ const shouldShowActions = canRename || canDelete;
2395
2413
  const {
2396
2414
  ref: editableRef,
2397
2415
  isEditing,
@@ -2416,8 +2434,8 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2416
2434
  endDragElementFromPanel();
2417
2435
  };
2418
2436
  const handleDeleteClick = () => {
2419
- popupState.close();
2420
2437
  setIsDeleteDialogOpen(true);
2438
+ popupState.close();
2421
2439
  };
2422
2440
  const handleDeleteConfirm = () => {
2423
2441
  if (!component.id) {
@@ -2486,9 +2504,9 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2486
2504
  }
2487
2505
  )))
2488
2506
  ),
2489
- /* @__PURE__ */ React15.createElement(IconButton5, { size: "tiny", ...bindTrigger3(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React15.createElement(DotsVerticalIcon2, { fontSize: "tiny" }))
2507
+ shouldShowActions && /* @__PURE__ */ React15.createElement(IconButton5, { size: "tiny", ...bindTrigger3(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React15.createElement(DotsVerticalIcon2, { fontSize: "tiny" }))
2490
2508
  )
2491
- ), /* @__PURE__ */ React15.createElement(
2509
+ ), shouldShowActions && /* @__PURE__ */ React15.createElement(
2492
2510
  Menu2,
2493
2511
  {
2494
2512
  ...bindMenu2(popupState),
@@ -2501,10 +2519,11 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2501
2519
  horizontal: "right"
2502
2520
  }
2503
2521
  },
2504
- /* @__PURE__ */ React15.createElement(
2522
+ canRename && /* @__PURE__ */ React15.createElement(
2505
2523
  MenuListItem3,
2506
2524
  {
2507
2525
  sx: { minWidth: "160px" },
2526
+ primaryTypographyProps: { variant: "caption", color: "text.primary" },
2508
2527
  onClick: () => {
2509
2528
  popupState.close();
2510
2529
  openEditMode();
@@ -2512,7 +2531,15 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2512
2531
  },
2513
2532
  __19("Rename", "elementor")
2514
2533
  ),
2515
- /* @__PURE__ */ React15.createElement(MenuListItem3, { sx: { minWidth: "160px" }, onClick: handleDeleteClick }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "caption", sx: { color: "error.light" } }, __19("Delete", "elementor")))
2534
+ canDelete && /* @__PURE__ */ React15.createElement(
2535
+ MenuListItem3,
2536
+ {
2537
+ sx: { minWidth: "160px" },
2538
+ primaryTypographyProps: { variant: "caption", color: "error.light" },
2539
+ onClick: handleDeleteClick
2540
+ },
2541
+ __19("Delete", "elementor")
2542
+ )
2516
2543
  ), /* @__PURE__ */ React15.createElement(
2517
2544
  DeleteConfirmationDialog,
2518
2545
  {
@@ -2634,6 +2661,7 @@ function ComponentsList() {
2634
2661
  }
2635
2662
  var EmptyState = () => {
2636
2663
  const [isAngieModalOpen, setIsAngieModalOpen] = useState7(false);
2664
+ const { canCreate } = useComponentsPermissions();
2637
2665
  const handleCreateWithAI = () => {
2638
2666
  const sdk = getAngieSdk();
2639
2667
  if (sdk.isAngieReady()) {
@@ -2658,7 +2686,10 @@ var EmptyState = () => {
2658
2686
  gap: 2,
2659
2687
  overflow: "hidden"
2660
2688
  },
2661
- /* @__PURE__ */ React17.createElement(Stack10, { alignItems: "center", gap: 1 }, /* @__PURE__ */ React17.createElement(ComponentsIcon2, { fontSize: "large", sx: { color: "text.secondary" } }), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, __20("No components yet", "elementor")), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 200 } }, __20("Components are reusable blocks that sync across your site.", "elementor"), /* @__PURE__ */ React17.createElement("br", null), __20("Create once, use everywhere.", "elementor")), /* @__PURE__ */ React17.createElement(
2689
+ /* @__PURE__ */ React17.createElement(Stack10, { alignItems: "center", gap: 1 }, /* @__PURE__ */ React17.createElement(ComponentsIcon2, { fontSize: "large", sx: { color: "text.secondary" } }), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, __20("No components yet", "elementor")), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 200 } }, __20("Components are reusable blocks that sync across your site.", "elementor"), /* @__PURE__ */ React17.createElement("br", null), canCreate ? __20("Create once, use everywhere.", "elementor") : __20(
2690
+ "With your current role, you cannot create components. Contact an administrator to create one.",
2691
+ "elementor"
2692
+ )), /* @__PURE__ */ React17.createElement(
2662
2693
  Link3,
2663
2694
  {
2664
2695
  href: LEARN_MORE_URL,
@@ -2669,8 +2700,16 @@ var EmptyState = () => {
2669
2700
  },
2670
2701
  __20("Learn more about components", "elementor")
2671
2702
  )),
2672
- /* @__PURE__ */ React17.createElement(Divider3, { sx: { width: "100%" } }),
2673
- /* @__PURE__ */ React17.createElement(Stack10, { alignItems: "center", gap: 1, width: "100%" }, /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, __20("Create your first one:", "elementor")), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 228 } }, __20(
2703
+ canCreate && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(Divider3, { sx: { width: "100%" } }), /* @__PURE__ */ React17.createElement(Stack10, { alignItems: "center", gap: 1, width: "100%" }, /* @__PURE__ */ React17.createElement(
2704
+ Typography9,
2705
+ {
2706
+ align: "center",
2707
+ variant: "subtitle2",
2708
+ color: "text.secondary",
2709
+ sx: SUBTITLE_OVERRIDE_SX
2710
+ },
2711
+ __20("Create your first one:", "elementor")
2712
+ ), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 228 } }, __20(
2674
2713
  'Right-click any div-block or flexbox on your canvas or structure and select "Create component"',
2675
2714
  "elementor"
2676
2715
  )), /* @__PURE__ */ React17.createElement(Typography9, { align: "center", variant: "caption", color: "secondary" }, __20("Or", "elementor")), /* @__PURE__ */ React17.createElement(AngiePromotionModal, { open: isAngieModalOpen, onClose: () => setIsAngieModalOpen(false) }, /* @__PURE__ */ React17.createElement(
@@ -2683,7 +2722,7 @@ var EmptyState = () => {
2683
2722
  endIcon: /* @__PURE__ */ React17.createElement(AIIcon, null)
2684
2723
  },
2685
2724
  __20("Create component with AI", "elementor")
2686
- )))
2725
+ ))))
2687
2726
  );
2688
2727
  };
2689
2728
  var EmptySearchResult = () => {
@@ -3520,6 +3559,14 @@ import { ComponentPropListIcon as ComponentPropListIcon4, PencilIcon } from "@el
3520
3559
  import { Button as Button7, Stack as Stack13, Typography as Typography12 } from "@elementor/ui";
3521
3560
  import { __ as __25 } from "@wordpress/i18n";
3522
3561
  var EmptyState2 = ({ onEditComponent }) => {
3562
+ const { canEdit } = useComponentsPermissions();
3563
+ const message = canEdit ? __25(
3564
+ "Edit the component to add properties, manage them or update the design across all instances.",
3565
+ "elementor"
3566
+ ) : __25(
3567
+ "With your current role, you cannot edit this component. Contact an administrator to add properties.",
3568
+ "elementor"
3569
+ );
3523
3570
  return /* @__PURE__ */ React23.createElement(
3524
3571
  Stack13,
3525
3572
  {
@@ -3532,11 +3579,8 @@ var EmptyState2 = ({ onEditComponent }) => {
3532
3579
  },
3533
3580
  /* @__PURE__ */ React23.createElement(ComponentPropListIcon4, { fontSize: "large" }),
3534
3581
  /* @__PURE__ */ React23.createElement(Typography12, { align: "center", variant: "subtitle2" }, __25("No properties yet", "elementor")),
3535
- /* @__PURE__ */ React23.createElement(Typography12, { align: "center", variant: "caption", maxWidth: "170px" }, __25(
3536
- "Edit the component to add properties, manage them or update the design across all instances.",
3537
- "elementor"
3538
- )),
3539
- /* @__PURE__ */ React23.createElement(Button7, { variant: "outlined", color: "secondary", size: "small", sx: { mt: 1 }, onClick: onEditComponent }, /* @__PURE__ */ React23.createElement(PencilIcon, { fontSize: "small" }), __25("Edit component", "elementor"))
3582
+ /* @__PURE__ */ React23.createElement(Typography12, { align: "center", variant: "caption", maxWidth: "170px" }, message),
3583
+ canEdit && /* @__PURE__ */ React23.createElement(Button7, { variant: "outlined", color: "secondary", size: "small", sx: { mt: 1 }, onClick: onEditComponent }, /* @__PURE__ */ React23.createElement(PencilIcon, { fontSize: "small" }), __25("Edit component", "elementor"))
3540
3584
  );
3541
3585
  };
3542
3586
 
@@ -3908,6 +3952,7 @@ function OverridePropsGroup({ group, props, overrides }) {
3908
3952
 
3909
3953
  // src/components/instance-editing-panel/instance-editing-panel.tsx
3910
3954
  function InstanceEditingPanel() {
3955
+ const { canEdit } = useComponentsPermissions();
3911
3956
  const settings = useComponentInstanceSettings();
3912
3957
  const componentId = settings?.component_id?.value;
3913
3958
  const overrides = settings?.overrides?.value;
@@ -3922,7 +3967,7 @@ function InstanceEditingPanel() {
3922
3967
  const isNonEmptyGroup = (group) => group !== null && group.props.length > 0;
3923
3968
  const groups = overridableProps.groups.order.map((groupId) => overridableProps.groups.items[groupId] ?? null).filter(isNonEmptyGroup);
3924
3969
  const isEmpty = groups.length === 0 || Object.keys(overridableProps.props).length === 0;
3925
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(PanelHeader2, { sx: { justifyContent: "start", px: 2 } }, /* @__PURE__ */ React28.createElement(Stack17, { direction: "row", alignItems: "center", flexGrow: 1, gap: 1, maxWidth: "100%" }, /* @__PURE__ */ React28.createElement(ComponentsIcon4, { fontSize: "small", sx: { color: "text.tertiary" } }), /* @__PURE__ */ React28.createElement(EllipsisWithTooltip2, { title: component.name, as: PanelHeaderTitle2 }), /* @__PURE__ */ React28.createElement(Tooltip4, { title: panelTitle, sx: { marginLeft: "auto" } }, /* @__PURE__ */ React28.createElement(IconButton6, { size: "tiny", onClick: handleEditComponent, "aria-label": panelTitle }, /* @__PURE__ */ React28.createElement(PencilIcon2, { fontSize: "tiny" }))))), /* @__PURE__ */ React28.createElement(PanelBody2, null, /* @__PURE__ */ React28.createElement(ControlAdornmentsProvider, { items: getFieldIndicators("settings") }, isEmpty ? /* @__PURE__ */ React28.createElement(EmptyState2, { onEditComponent: handleEditComponent }) : /* @__PURE__ */ React28.createElement(Stack17, { direction: "column", alignItems: "stretch" }, groups.map((group) => /* @__PURE__ */ React28.createElement(React28.Fragment, { key: group.id }, /* @__PURE__ */ React28.createElement(
3970
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(PanelHeader2, { sx: { justifyContent: "start", px: 2 } }, /* @__PURE__ */ React28.createElement(Stack17, { direction: "row", alignItems: "center", flexGrow: 1, gap: 1, maxWidth: "100%" }, /* @__PURE__ */ React28.createElement(ComponentsIcon4, { fontSize: "small", sx: { color: "text.tertiary" } }), /* @__PURE__ */ React28.createElement(EllipsisWithTooltip2, { title: component.name, as: PanelHeaderTitle2 }), canEdit && /* @__PURE__ */ React28.createElement(Tooltip4, { title: panelTitle }, /* @__PURE__ */ React28.createElement(IconButton6, { size: "tiny", onClick: handleEditComponent, "aria-label": panelTitle }, /* @__PURE__ */ React28.createElement(PencilIcon2, { fontSize: "tiny" }))))), /* @__PURE__ */ React28.createElement(PanelBody2, null, /* @__PURE__ */ React28.createElement(ControlAdornmentsProvider, { items: getFieldIndicators("settings") }, isEmpty ? /* @__PURE__ */ React28.createElement(EmptyState2, { onEditComponent: handleEditComponent }) : /* @__PURE__ */ React28.createElement(Stack17, { direction: "column", alignItems: "stretch" }, groups.map((group) => /* @__PURE__ */ React28.createElement(React28.Fragment, { key: group.id }, /* @__PURE__ */ React28.createElement(
3926
3971
  OverridePropsGroup,
3927
3972
  {
3928
3973
  group,