@elementor/editor-components 3.35.0-447 → 3.35.0-449

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.js CHANGED
@@ -1763,6 +1763,18 @@ var import_icons10 = require("@elementor/icons");
1763
1763
  var import_ui15 = require("@elementor/ui");
1764
1764
  var import_i18n20 = require("@wordpress/i18n");
1765
1765
 
1766
+ // src/hooks/use-components-permissions.ts
1767
+ var import_editor_current_user2 = require("@elementor/editor-current-user");
1768
+ var useComponentsPermissions = () => {
1769
+ const { isAdmin } = (0, import_editor_current_user2.useCurrentUserCapabilities)();
1770
+ return {
1771
+ canCreate: isAdmin,
1772
+ canEdit: isAdmin,
1773
+ canDelete: isAdmin,
1774
+ canRename: isAdmin
1775
+ };
1776
+ };
1777
+
1766
1778
  // src/store/actions/rename-component.ts
1767
1779
  var import_editor_documents7 = require("@elementor/editor-documents");
1768
1780
  var import_editor_elements5 = require("@elementor/editor-elements");
@@ -1842,9 +1854,9 @@ function createComponentType(options) {
1842
1854
  };
1843
1855
  }
1844
1856
  function createComponentView(options) {
1857
+ const legacyWindow = window;
1845
1858
  return class extends (0, import_editor_canvas4.createTemplatedElementView)(options) {
1846
- legacyWindow = window;
1847
- eventsManagerConfig = this.legacyWindow.elementorCommon.eventsManager.config;
1859
+ eventsManagerConfig = legacyWindow.elementorCommon.eventsManager.config;
1848
1860
  #componentRenderContext;
1849
1861
  isComponentCurrentlyEdited() {
1850
1862
  const currentDocument = (0, import_editor_documents6.getCurrentDocument)();
@@ -1880,9 +1892,7 @@ function createComponentView(options) {
1880
1892
  this.#componentRenderContext = {
1881
1893
  overrides: componentInstance.overrides ?? {}
1882
1894
  };
1883
- this.collection = this.legacyWindow.elementor.createBackboneElementsCollection(
1884
- componentInstance.elements
1885
- );
1895
+ this.collection = legacyWindow.elementor.createBackboneElementsCollection(componentInstance.elements);
1886
1896
  this.collection.models.forEach(setInactiveRecursively);
1887
1897
  settings.component_instance = "<template data-children-placeholder></template>";
1888
1898
  }
@@ -1916,9 +1926,7 @@ function createComponentView(options) {
1916
1926
  return newGroups;
1917
1927
  }
1918
1928
  _getContextMenuConfig() {
1919
- const legacyWindow = this.legacyWindow || window;
1920
- const elementorWithConfig = legacyWindow.elementor;
1921
- const isAdministrator = elementorWithConfig.config?.user?.is_administrator ?? false;
1929
+ const isAdministrator = isUserAdministrator();
1922
1930
  const addedGroup = {
1923
1931
  general: {
1924
1932
  index: 1,
@@ -1963,6 +1971,10 @@ function createComponentView(options) {
1963
1971
  }
1964
1972
  handleDblClick(e) {
1965
1973
  e.stopPropagation();
1974
+ const isAdministrator = isUserAdministrator();
1975
+ if (!isAdministrator) {
1976
+ return;
1977
+ }
1966
1978
  const { triggers, locations, secondaryLocations } = this.eventsManagerConfig;
1967
1979
  this.editComponent({
1968
1980
  trigger: triggers.doubleClick,
@@ -1996,6 +2008,10 @@ function setInactiveRecursively(model) {
1996
2008
  });
1997
2009
  }
1998
2010
  }
2011
+ function isUserAdministrator() {
2012
+ const legacyWindow = window;
2013
+ return legacyWindow.elementor.config?.user?.is_administrator ?? false;
2014
+ }
1999
2015
  function createComponentModel() {
2000
2016
  const legacyWindow = window;
2001
2017
  const WidgetType = legacyWindow.elementor.modules.elements.types.Widget;
@@ -2370,6 +2386,8 @@ function DeleteConfirmationDialog({ open, onClose, onConfirm }) {
2370
2386
  var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2371
2387
  const itemRef = (0, import_react8.useRef)(null);
2372
2388
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = (0, import_react8.useState)(false);
2389
+ const { canRename, canDelete } = useComponentsPermissions();
2390
+ const shouldShowActions = canRename || canDelete;
2373
2391
  const {
2374
2392
  ref: editableRef,
2375
2393
  isEditing,
@@ -2394,8 +2412,8 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2394
2412
  (0, import_editor_canvas5.endDragElementFromPanel)();
2395
2413
  };
2396
2414
  const handleDeleteClick = () => {
2397
- popupState.close();
2398
2415
  setIsDeleteDialogOpen(true);
2416
+ popupState.close();
2399
2417
  };
2400
2418
  const handleDeleteConfirm = () => {
2401
2419
  if (!component.id) {
@@ -2464,9 +2482,9 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2464
2482
  }
2465
2483
  )))
2466
2484
  ),
2467
- /* @__PURE__ */ React15.createElement(import_ui13.IconButton, { size: "tiny", ...(0, import_ui13.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React15.createElement(import_icons9.DotsVerticalIcon, { fontSize: "tiny" }))
2485
+ shouldShowActions && /* @__PURE__ */ React15.createElement(import_ui13.IconButton, { size: "tiny", ...(0, import_ui13.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React15.createElement(import_icons9.DotsVerticalIcon, { fontSize: "tiny" }))
2468
2486
  )
2469
- ), /* @__PURE__ */ React15.createElement(
2487
+ ), shouldShowActions && /* @__PURE__ */ React15.createElement(
2470
2488
  import_ui13.Menu,
2471
2489
  {
2472
2490
  ...(0, import_ui13.bindMenu)(popupState),
@@ -2479,10 +2497,11 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2479
2497
  horizontal: "right"
2480
2498
  }
2481
2499
  },
2482
- /* @__PURE__ */ React15.createElement(
2500
+ canRename && /* @__PURE__ */ React15.createElement(
2483
2501
  import_editor_ui7.MenuListItem,
2484
2502
  {
2485
2503
  sx: { minWidth: "160px" },
2504
+ primaryTypographyProps: { variant: "caption", color: "text.primary" },
2486
2505
  onClick: () => {
2487
2506
  popupState.close();
2488
2507
  openEditMode();
@@ -2490,7 +2509,15 @@ var ComponentItem = ({ component, renameComponent: renameComponent2 }) => {
2490
2509
  },
2491
2510
  (0, import_i18n19.__)("Rename", "elementor")
2492
2511
  ),
2493
- /* @__PURE__ */ React15.createElement(import_editor_ui7.MenuListItem, { sx: { minWidth: "160px" }, onClick: handleDeleteClick }, /* @__PURE__ */ React15.createElement(import_ui13.Typography, { variant: "caption", sx: { color: "error.light" } }, (0, import_i18n19.__)("Delete", "elementor")))
2512
+ canDelete && /* @__PURE__ */ React15.createElement(
2513
+ import_editor_ui7.MenuListItem,
2514
+ {
2515
+ sx: { minWidth: "160px" },
2516
+ primaryTypographyProps: { variant: "caption", color: "error.light" },
2517
+ onClick: handleDeleteClick
2518
+ },
2519
+ (0, import_i18n19.__)("Delete", "elementor")
2520
+ )
2494
2521
  ), /* @__PURE__ */ React15.createElement(
2495
2522
  DeleteConfirmationDialog,
2496
2523
  {
@@ -2612,6 +2639,7 @@ function ComponentsList() {
2612
2639
  }
2613
2640
  var EmptyState = () => {
2614
2641
  const [isAngieModalOpen, setIsAngieModalOpen] = (0, import_react9.useState)(false);
2642
+ const { canCreate } = useComponentsPermissions();
2615
2643
  const handleCreateWithAI = () => {
2616
2644
  const sdk = (0, import_editor_mcp.getAngieSdk)();
2617
2645
  if (sdk.isAngieReady()) {
@@ -2636,7 +2664,10 @@ var EmptyState = () => {
2636
2664
  gap: 2,
2637
2665
  overflow: "hidden"
2638
2666
  },
2639
- /* @__PURE__ */ React17.createElement(import_ui15.Stack, { alignItems: "center", gap: 1 }, /* @__PURE__ */ React17.createElement(import_icons10.ComponentsIcon, { fontSize: "large", sx: { color: "text.secondary" } }), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, (0, import_i18n20.__)("No components yet", "elementor")), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 200 } }, (0, import_i18n20.__)("Components are reusable blocks that sync across your site.", "elementor"), /* @__PURE__ */ React17.createElement("br", null), (0, import_i18n20.__)("Create once, use everywhere.", "elementor")), /* @__PURE__ */ React17.createElement(
2667
+ /* @__PURE__ */ React17.createElement(import_ui15.Stack, { alignItems: "center", gap: 1 }, /* @__PURE__ */ React17.createElement(import_icons10.ComponentsIcon, { fontSize: "large", sx: { color: "text.secondary" } }), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, (0, import_i18n20.__)("No components yet", "elementor")), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 200 } }, (0, import_i18n20.__)("Components are reusable blocks that sync across your site.", "elementor"), /* @__PURE__ */ React17.createElement("br", null), canCreate ? (0, import_i18n20.__)("Create once, use everywhere.", "elementor") : (0, import_i18n20.__)(
2668
+ "With your current role, you cannot create components. Contact an administrator to create one.",
2669
+ "elementor"
2670
+ )), /* @__PURE__ */ React17.createElement(
2640
2671
  import_ui15.Link,
2641
2672
  {
2642
2673
  href: LEARN_MORE_URL,
@@ -2647,8 +2678,16 @@ var EmptyState = () => {
2647
2678
  },
2648
2679
  (0, import_i18n20.__)("Learn more about components", "elementor")
2649
2680
  )),
2650
- /* @__PURE__ */ React17.createElement(import_ui15.Divider, { sx: { width: "100%" } }),
2651
- /* @__PURE__ */ React17.createElement(import_ui15.Stack, { alignItems: "center", gap: 1, width: "100%" }, /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "subtitle2", color: "text.secondary", sx: SUBTITLE_OVERRIDE_SX }, (0, import_i18n20.__)("Create your first one:", "elementor")), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 228 } }, (0, import_i18n20.__)(
2681
+ canCreate && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(import_ui15.Divider, { sx: { width: "100%" } }), /* @__PURE__ */ React17.createElement(import_ui15.Stack, { alignItems: "center", gap: 1, width: "100%" }, /* @__PURE__ */ React17.createElement(
2682
+ import_ui15.Typography,
2683
+ {
2684
+ align: "center",
2685
+ variant: "subtitle2",
2686
+ color: "text.secondary",
2687
+ sx: SUBTITLE_OVERRIDE_SX
2688
+ },
2689
+ (0, import_i18n20.__)("Create your first one:", "elementor")
2690
+ ), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "caption", color: "secondary", sx: { maxWidth: 228 } }, (0, import_i18n20.__)(
2652
2691
  'Right-click any div-block or flexbox on your canvas or structure and select "Create component"',
2653
2692
  "elementor"
2654
2693
  )), /* @__PURE__ */ React17.createElement(import_ui15.Typography, { align: "center", variant: "caption", color: "secondary" }, (0, import_i18n20.__)("Or", "elementor")), /* @__PURE__ */ React17.createElement(AngiePromotionModal, { open: isAngieModalOpen, onClose: () => setIsAngieModalOpen(false) }, /* @__PURE__ */ React17.createElement(
@@ -2661,7 +2700,7 @@ var EmptyState = () => {
2661
2700
  endIcon: /* @__PURE__ */ React17.createElement(import_icons10.AIIcon, null)
2662
2701
  },
2663
2702
  (0, import_i18n20.__)("Create component with AI", "elementor")
2664
- )))
2703
+ ))))
2665
2704
  );
2666
2705
  };
2667
2706
  var EmptySearchResult = () => {
@@ -3494,6 +3533,14 @@ var import_icons13 = require("@elementor/icons");
3494
3533
  var import_ui18 = require("@elementor/ui");
3495
3534
  var import_i18n25 = require("@wordpress/i18n");
3496
3535
  var EmptyState2 = ({ onEditComponent }) => {
3536
+ const { canEdit } = useComponentsPermissions();
3537
+ const message = canEdit ? (0, import_i18n25.__)(
3538
+ "Edit the component to add properties, manage them or update the design across all instances.",
3539
+ "elementor"
3540
+ ) : (0, import_i18n25.__)(
3541
+ "With your current role, you cannot edit this component. Contact an administrator to add properties.",
3542
+ "elementor"
3543
+ );
3497
3544
  return /* @__PURE__ */ React23.createElement(
3498
3545
  import_ui18.Stack,
3499
3546
  {
@@ -3506,11 +3553,8 @@ var EmptyState2 = ({ onEditComponent }) => {
3506
3553
  },
3507
3554
  /* @__PURE__ */ React23.createElement(import_icons13.ComponentPropListIcon, { fontSize: "large" }),
3508
3555
  /* @__PURE__ */ React23.createElement(import_ui18.Typography, { align: "center", variant: "subtitle2" }, (0, import_i18n25.__)("No properties yet", "elementor")),
3509
- /* @__PURE__ */ React23.createElement(import_ui18.Typography, { align: "center", variant: "caption", maxWidth: "170px" }, (0, import_i18n25.__)(
3510
- "Edit the component to add properties, manage them or update the design across all instances.",
3511
- "elementor"
3512
- )),
3513
- /* @__PURE__ */ React23.createElement(import_ui18.Button, { variant: "outlined", color: "secondary", size: "small", sx: { mt: 1 }, onClick: onEditComponent }, /* @__PURE__ */ React23.createElement(import_icons13.PencilIcon, { fontSize: "small" }), (0, import_i18n25.__)("Edit component", "elementor"))
3556
+ /* @__PURE__ */ React23.createElement(import_ui18.Typography, { align: "center", variant: "caption", maxWidth: "170px" }, message),
3557
+ canEdit && /* @__PURE__ */ React23.createElement(import_ui18.Button, { variant: "outlined", color: "secondary", size: "small", sx: { mt: 1 }, onClick: onEditComponent }, /* @__PURE__ */ React23.createElement(import_icons13.PencilIcon, { fontSize: "small" }), (0, import_i18n25.__)("Edit component", "elementor"))
3514
3558
  );
3515
3559
  };
3516
3560
 
@@ -3874,6 +3918,7 @@ function OverridePropsGroup({ group, props, overrides }) {
3874
3918
 
3875
3919
  // src/components/instance-editing-panel/instance-editing-panel.tsx
3876
3920
  function InstanceEditingPanel() {
3921
+ const { canEdit } = useComponentsPermissions();
3877
3922
  const settings = useComponentInstanceSettings();
3878
3923
  const componentId = settings?.component_id?.value;
3879
3924
  const overrides = settings?.overrides?.value;
@@ -3888,7 +3933,7 @@ function InstanceEditingPanel() {
3888
3933
  const isNonEmptyGroup = (group) => group !== null && group.props.length > 0;
3889
3934
  const groups = overridableProps.groups.order.map((groupId) => overridableProps.groups.items[groupId] ?? null).filter(isNonEmptyGroup);
3890
3935
  const isEmpty = groups.length === 0 || Object.keys(overridableProps.props).length === 0;
3891
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(import_editor_panels3.PanelHeader, { sx: { justifyContent: "start", px: 2 } }, /* @__PURE__ */ React28.createElement(import_ui22.Stack, { direction: "row", alignItems: "center", flexGrow: 1, gap: 1, maxWidth: "100%" }, /* @__PURE__ */ React28.createElement(import_icons14.ComponentsIcon, { fontSize: "small", sx: { color: "text.tertiary" } }), /* @__PURE__ */ React28.createElement(import_editor_ui12.EllipsisWithTooltip, { title: component.name, as: import_editor_panels3.PanelHeaderTitle }), /* @__PURE__ */ React28.createElement(import_ui22.Tooltip, { title: panelTitle, sx: { marginLeft: "auto" } }, /* @__PURE__ */ React28.createElement(import_ui22.IconButton, { size: "tiny", onClick: handleEditComponent, "aria-label": panelTitle }, /* @__PURE__ */ React28.createElement(import_icons14.PencilIcon, { fontSize: "tiny" }))))), /* @__PURE__ */ React28.createElement(import_editor_panels3.PanelBody, null, /* @__PURE__ */ React28.createElement(import_editor_controls4.ControlAdornmentsProvider, { items: (0, import_editor_editing_panel5.getFieldIndicators)("settings") }, isEmpty ? /* @__PURE__ */ React28.createElement(EmptyState2, { onEditComponent: handleEditComponent }) : /* @__PURE__ */ React28.createElement(import_ui22.Stack, { direction: "column", alignItems: "stretch" }, groups.map((group) => /* @__PURE__ */ React28.createElement(React28.Fragment, { key: group.id }, /* @__PURE__ */ React28.createElement(
3936
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(import_editor_panels3.PanelHeader, { sx: { justifyContent: "start", px: 2 } }, /* @__PURE__ */ React28.createElement(import_ui22.Stack, { direction: "row", alignItems: "center", flexGrow: 1, gap: 1, maxWidth: "100%" }, /* @__PURE__ */ React28.createElement(import_icons14.ComponentsIcon, { fontSize: "small", sx: { color: "text.tertiary" } }), /* @__PURE__ */ React28.createElement(import_editor_ui12.EllipsisWithTooltip, { title: component.name, as: import_editor_panels3.PanelHeaderTitle }), canEdit && /* @__PURE__ */ React28.createElement(import_ui22.Tooltip, { title: panelTitle }, /* @__PURE__ */ React28.createElement(import_ui22.IconButton, { size: "tiny", onClick: handleEditComponent, "aria-label": panelTitle }, /* @__PURE__ */ React28.createElement(import_icons14.PencilIcon, { fontSize: "tiny" }))))), /* @__PURE__ */ React28.createElement(import_editor_panels3.PanelBody, null, /* @__PURE__ */ React28.createElement(import_editor_controls4.ControlAdornmentsProvider, { items: (0, import_editor_editing_panel5.getFieldIndicators)("settings") }, isEmpty ? /* @__PURE__ */ React28.createElement(EmptyState2, { onEditComponent: handleEditComponent }) : /* @__PURE__ */ React28.createElement(import_ui22.Stack, { direction: "column", alignItems: "stretch" }, groups.map((group) => /* @__PURE__ */ React28.createElement(React28.Fragment, { key: group.id }, /* @__PURE__ */ React28.createElement(
3892
3937
  OverridePropsGroup,
3893
3938
  {
3894
3939
  group,