PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.2
Elementor Website Builder – more than just a page builder v4.3.2
4.3.2 4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 All 455 releases
← All changes | assets/js/packages/editor-variables/editor-variables.js +3893 -2 4.1.0-dev2 → 4.3.2 View file →
@@ -1,3 +1,3894 @@
1 -/*! For license information please see editor-variables.js.LICENSE.txt */
2 -!function(){"use strict";var e={"./packages/packages/core/editor-variables/src/api.ts":function(e,a,r){r.r(a),r.d(a,{apiClient:function(){return o}});var t=r("@elementor/http-client");const n="elementor/v1/variables",o={list:()=>(0,t.httpService)().get(n+"/list"),create:(e,a,r)=>(0,t.httpService)().post(n+"/create",{type:e,label:a,value:r}),update:(e,a,r,o)=>(0,t.httpService)().put(n+"/update",{id:e,label:a,value:r,type:o}),delete:e=>(0,t.httpService)().post(n+"/delete",{id:e}),restore:(e,a,r,o)=>{const i={id:e};return a&&(i.label=a),r&&(i.value=r),o&&(i.type=o),(0,t.httpService)().post(n+"/restore",i)},batch:e=>(0,t.httpService)().post(n+"/batch",e)}},"./packages/packages/core/editor-variables/src/batch-operations.ts":function(e,a,r){r.r(a),r.d(a,{buildOperationsArray:function(){return buildOperationsArray},generateTempId:function(){return generateTempId},isTempId:function(){return isTempId}});const generateTempId=()=>`tmp-${Date.now().toString(36)}-${Math.random().toString(36).substring(2,8)}`,isTempId=e=>e.startsWith("tmp-"),buildOperationsArray=(e,a,r)=>{const t=[];return Object.entries(a).forEach(([a,r])=>{if(isTempId(a))t.push({type:"create",variable:{...r,id:a}});else if(e[a]){const n=e[a],o=n.sync_to_v3!==r.sync_to_v3;n.deleted&&!r.deleted?t.push({type:"restore",id:a,...n.label!==r.label&&{label:r.label},...n.value!==r.value&&{value:r.value}}):r.deleted||n.label===r.label&&n.value===r.value&&n.order===r.order&&n.type===r.type&&!o||t.push({type:"update",id:a,variable:{...n.label!==r.label&&{label:r.label},...n.value!==r.value&&{value:r.value},...n.order!==r.order&&{order:r.order},...n.type!==r.type&&{type:r.type},...o&&{sync_to_v3:r.sync_to_v3}}})}}),r.forEach(e=>{t.push({type:"delete",id:e})}),t.filter(e=>{const r=e.id||e.variable?.id;return r&&!(isTempId(r)&&a[r]?.deleted)})}},"./packages/packages/core/editor-variables/src/components/fields/color-field.tsx":function(e,a,r){r.r(a),r.d(a,{ColorField:function(){return ColorField}});var t=r("react"),n=r("@elementor/ui"),o=r("./packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx"),i=r("./packages/packages/core/editor-variables/src/utils/validations.ts");const ColorField=({value:e,onChange:a,onValidationChange:r})=>{const[s,l]=(0,t.useState)(e),[c,p]=(0,t.useState)(""),u=(0,t.useRef)(null),d=(0,o.usePopoverContentRef)()??u.current;return t.createElement(n.UnstableColorField,{id:"color-variable-field",size:"tiny",fullWidth:!0,value:s,onChange:e=>{l(e);const t=(0,i.validateValue)(e);p(t),r?.(t),a(t?"":e)},error:c||void 0,slotProps:{colorPicker:{anchorEl:d,anchorOrigin:{vertical:"top",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:-10},slotProps:{colorIndicator:{size:"inherit",sx:{borderRadius:.5}}}}}})}},"./packages/packages/core/editor-variables/src/components/fields/font-field.tsx":function(e,a,r){r.r(a),r.d(a,{FontField:function(){return FontField}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-ui"),i=r("@elementor/icons"),s=r("@elementor/ui"),l=r("@wordpress/i18n"),c=r("./packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx"),p=r("./packages/packages/core/editor-variables/src/utils/validations.ts");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const FontField=({value:e,onChange:a,onValidationChange:r})=>{const[u,d]=(0,t.useState)(e),b=(0,t.useRef)(null),m=(0,c.usePopoverContentRef)()??b.current,v=(0,s.usePopupState)({variant:"popover"}),g=(0,n.useFontFamilies)(),f=(0,o.useSectionWidth)(),y=(0,t.useMemo)(()=>g.map(({label:e,fonts:a})=>({label:e,items:a})),[g]),k=(0,t.useId)();return t.createElement(t.Fragment,null,t.createElement(s.UnstableTag,_extends({id:k,variant:"outlined",label:u,endIcon:t.createElement(i.ChevronDownIcon,{fontSize:"tiny"})},(0,s.bindTrigger)(v),{fullWidth:!0})),t.createElement(s.Popover,_extends({disablePortal:!0,disableScrollLock:!0,anchorEl:m,anchorOrigin:{vertical:"top",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:-28}},(0,s.bindPopover)(v)),t.createElement(n.ItemSelector,{id:"font-family-variables-selector",itemsList:y,selectedItem:u,onItemChange:e=>{(e=>{d(e);const t=(0,p.validateValue)(e);r?.(t),a(t?"":e)})(e),v.close()},onClose:v.close,sectionWidth:f,title:(0,l.__)("Font family","elementor"),itemStyle:e=>({fontFamily:e.value}),onDebounce:n.enqueueFont,icon:i.TextIcon})))}},"./packages/packages/core/editor-variables/src/components/fields/label-field.tsx":function(e,a,r){r.r(a),r.d(a,{LabelField:function(){return LabelField},useLabelError:function(){return useLabelError}});var t=r("react"),n=r("@elementor/editor-ui"),o=r("@elementor/ui"),i=r("./packages/packages/core/editor-variables/src/utils/validations.ts");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}function isLabelEqual(e,a){return e.trim().toLowerCase()===a.trim().toLowerCase()}const useLabelError=e=>{const[a,r]=(0,t.useState)(e??{value:"",message:""});return{labelFieldError:a,setLabelFieldError:r}},LabelField=({value:e,error:a,onChange:r,id:s,onErrorChange:l,size:c="tiny",focusOnShow:p=!1,selectOnShow:u=!1,showWarningInfotip:d=!1,variables:b,onKeyDown:m})=>{const[v,g]=(0,t.useState)(e),[f,y]=(0,t.useState)(""),k=(0,t.useRef)(null);let h=f;isLabelEqual(v,a?.value??"")&&a?.message&&(h=a.message);const E=h?"":(0,i.labelHint)(v),_=t.createElement(o.TextField,{ref:k,id:s,size:c,fullWidth:!0,value:v,error:!!h,onChange:e=>(e=>{g(e);const t=(0,i.validateLabel)(e,b);y(t),l?.(t),r(isLabelEqual(e,a?.value??"")||t?"":e)})(e.target.value),inputProps:{maxLength:i.VARIABLE_LABEL_MAX_LENGTH,...u&&{onFocus:e=>e.target.select()},"aria-label":"Name",onKeyDown:m},autoFocus:p});if(d){const e=Math.max(240,k.current?.getBoundingClientRect().width??240);return t.createElement(n.WarningInfotip,_extends({open:Boolean(h||E),text:h||E,placement:"bottom-start",width:e,offset:[0,-15]},E&&{hasError:!1}),_)}return _}},"./packages/packages/core/editor-variables/src/components/global-styles-import-listener.tsx":function(e,a,r){r.r(a),r.d(a,{GlobalStylesImportListener:function(){return GlobalStylesImportListener}});var t=r("react"),n=r("@elementor/editor-canvas"),o=r("./packages/packages/core/editor-variables/src/service.ts");function GlobalStylesImportListener(){return(0,t.useEffect)(()=>{const handleGlobalStylesImported=()=>{o.service.load()};return window.addEventListener(n.GLOBAL_STYLES_IMPORTED_EVENT,handleGlobalStylesImported),()=>{window.removeEventListener(n.GLOBAL_STYLES_IMPORTED_EVENT,handleGlobalStylesImported)}},[]),null}},"./packages/packages/core/editor-variables/src/components/open-panel-from-event.tsx":function(e,a,r){r.r(a),r.d(a,{OpenPanelFromEvent:function(){return OpenPanelFromEvent}});var t=r("react"),n=r("@elementor/editor-v1-adapters"),o=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx");const i="elementor/open-variables-manager",s="panel/elements/categories";function OpenPanelFromEvent(){const{open:e}=(0,o.usePanelActions)(),a=(0,t.useRef)(!1),[r,l]=(0,t.useState)(!1);return(0,t.useEffect)(()=>{r&&(l(!1),e())},[r,e]),(0,t.useEffect)(()=>(0,n.__privateListenTo)((0,n.routeOpenEvent)(s),()=>{a.current&&(a.current=!1,l(!0))}),[]),(0,t.useEffect)(()=>{const handler=()=>{a.current=!0,(0,n.__privateOpenRoute)(s)};return window.addEventListener(i,handler),()=>window.removeEventListener(i,handler)},[]),null}},"./packages/packages/core/editor-variables/src/components/open-panel-from-url.tsx":function(e,a,r){r.r(a),r.d(a,{OpenPanelFromUrl:function(){return OpenPanelFromUrl}});var t=r("react"),n=r("@elementor/editor-v1-adapters"),o=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx");const i="active-panel",s="variables-manager",l="panel/elements";function OpenPanelFromUrl(){const{open:e}=(0,o.usePanelActions)(),a=(0,t.useRef)(!1);return(0,t.useEffect)(()=>{if(new URLSearchParams(window.location.search).get(i)!==s)return;return(0,n.__privateListenTo)((0,n.routeOpenEvent)(l),()=>{a.current||(a.current=!0,requestAnimationFrame(()=>{e()}))})},[e]),null}},"./packages/packages/core/editor-variables/src/components/ui/color-indicator.tsx":function(e,a,r){r.r(a),r.d(a,{ColorIndicator:function(){return n}});var t=r("@elementor/ui");const n=(0,t.styled)(t.UnstableColorIndicator)(({theme:e})=>({borderRadius:e.shape.borderRadius/2+"px",marginRight:e.spacing(.25)}))},"./packages/packages/core/editor-variables/src/components/ui/delete-confirmation-dialog.tsx":function(e,a,r){r.r(a),r.d(a,{DeleteConfirmationDialog:function(){return DeleteConfirmationDialog}});var t=r("react"),n=r("@elementor/editor-ui"),o=r("@elementor/ui"),i=r("@wordpress/i18n");const DeleteConfirmationDialog=({open:e,label:a,closeDialog:r,onConfirm:s})=>t.createElement(n.ConfirmationDialog,{open:e,onClose:r},t.createElement(n.ConfirmationDialog.Title,null,(0,i.__)("Delete this variable?","elementor")),t.createElement(n.ConfirmationDialog.Content,null,t.createElement(n.ConfirmationDialog.ContentText,null,(0,i.__)("All elements using","elementor")," ",t.createElement(o.Typography,{variant:"subtitle2",component:"span",sx:{lineBreak:"anywhere"}},a)," ",(0,i.__)("will keep their current values, but the variable itself will be removed.","elementor"))),t.createElement(n.ConfirmationDialog.Actions,{onClose:r,onConfirm:s}))},"./packages/packages/core/editor-variables/src/components/ui/deleted-variable-alert.tsx":function(e,a,r){r.r(a),r.d(a,{DeletedVariableAlert:function(){return DeletedVariableAlert}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n");const DeletedVariableAlert=({onClose:e,onUnlink:a,onRestore:r,label:i})=>t.createElement(n.ClickAwayListener,{onClickAway:e},t.createElement(n.Alert,{variant:"standard",severity:"warning",onClose:e,action:t.createElement(t.Fragment,null,a&&t.createElement(n.AlertAction,{variant:"contained",onClick:a},(0,o.__)("Unlink","elementor")),r&&t.createElement(n.AlertAction,{variant:"outlined",onClick:r},(0,o.__)("Restore","elementor"))),sx:{maxWidth:300}},t.createElement(n.AlertTitle,null,(0,o.__)("Deleted variable","elementor")),t.createElement(n.Typography,{variant:"body2",color:"textPrimary"},(0,o.__)("The variable","elementor")," '",t.createElement(n.Typography,{variant:"body2",component:"span",sx:{lineBreak:"anywhere"}},i),"' ",(0,o.__)("has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.","elementor"))))},"./packages/packages/core/editor-variables/src/components/ui/edit-confirmation-dialog.tsx":function(e,a,r){r.r(a),r.d(a,{EDIT_CONFIRMATION_DIALOG_ID:function(){return s},EditConfirmationDialog:function(){return EditConfirmationDialog}});var t=r("react"),n=r("@elementor/icons"),o=r("@elementor/ui"),i=r("@wordpress/i18n");const s="edit-confirmation-dialog",EditConfirmationDialog=({closeDialog:e,onConfirm:a,onSuppressMessage:r})=>{const[s,l]=(0,t.useState)(!1);return t.createElement(o.Dialog,{open:!0,onClose:e,maxWidth:"xs"},t.createElement(o.DialogTitle,{display:"flex",alignItems:"center",gap:1},t.createElement(n.AlertTriangleFilledIcon,{color:"secondary"}),(0,i.__)("Changes to variables go live right away.","elementor")),t.createElement(o.DialogContent,null,t.createElement(o.DialogContentText,{variant:"body2",color:"textPrimary"},(0,i.__)("Don't worry - all other changes you make will wait until you publish your site.","elementor"))),t.createElement(o.DialogActions,{sx:{justifyContent:"space-between",alignItems:"center"}},t.createElement(o.FormControlLabel,{control:t.createElement(o.Checkbox,{checked:s,onChange:e=>l(e.target.checked),size:"small"}),label:t.createElement(o.Typography,{variant:"body2"},(0,i.__)("Don't show me again","elementor"))}),t.createElement("div",null,t.createElement(o.Button,{color:"secondary",onClick:e},(0,i.__)("Keep editing","elementor")),t.createElement(o.Button,{variant:"contained",color:"secondary",onClick:()=>{s&&r?.(),a?.()},sx:{ml:1}},(0,i.__)("Save","elementor")))))}},"./packages/packages/core/editor-variables/src/components/ui/empty-state.tsx":function(e,a,r){r.r(a),r.d(a,{EmptyState:function(){return EmptyState}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n"),i=r("./packages/packages/core/editor-variables/src/hooks/use-permissions.ts");const EmptyState=({icon:e,title:a,message:r,onAdd:s,children:l})=>{const c=(0,i.usePermissions)().canAdd(),p=c?a:(0,o.__)("There are no variables","elementor"),u=c?r:(0,o.__)("With your current role, you can only connect and detach variables.","elementor");return t.createElement(Content,{title:p,message:u,icon:e},l||s&&t.createElement(n.Button,{variant:"outlined",color:"secondary",size:"small",onClick:s},(0,o.__)("Create a variable","elementor")))};function Content({title:e,message:a,icon:r,children:o}){return t.createElement(n.Stack,{gap:1,alignItems:"center",justifyContent:"flex-start",height:"100%",color:"text.secondary",sx:{p:2.5,pt:8,pb:5.5}},r,t.createElement(n.Typography,{align:"center",variant:"subtitle2"},e),t.createElement(n.Typography,{align:"center",variant:"caption",maxWidth:"180px"},a),o)}},"./packages/packages/core/editor-variables/src/components/ui/form-field.tsx":function(e,a,r){r.r(a),r.d(a,{FormField:function(){return FormField}});var t=r("react"),n=r("@elementor/ui");const FormField=({id:e,label:a,errorMsg:r,noticeMsg:o,children:i})=>t.createElement(n.Grid,{container:!0,gap:.75,alignItems:"center"},t.createElement(n.Grid,{item:!0,xs:12},t.createElement(n.FormLabel,{htmlFor:e,size:"tiny"},a)),t.createElement(n.Grid,{item:!0,xs:12},i,r&&t.createElement(n.FormHelperText,{error:!0},r),o&&t.createElement(n.FormHelperText,null,o)))},"./packages/packages/core/editor-variables/src/components/ui/menu-item-content.tsx":function(e,a,r){r.r(a),r.d(a,{MenuItemContent:function(){return MenuItemContent}});var t=r("react"),n=r("@elementor/editor-ui"),o=r("@elementor/icons"),i=r("@elementor/ui"),s=r("@wordpress/i18n");const l=(0,s.__)("Edit variable","elementor"),MenuItemContent=({item:e,disabled:a=!1})=>{const r=e.onEdit;return t.createElement(t.Fragment,null,t.createElement(i.ListItemIcon,{sx:{color:a?"text.disabled":"inherit"}},e.icon),t.createElement(i.Box,{sx:{flex:1,minWidth:0,display:"flex",alignItems:"center",gap:1}},t.createElement(n.EllipsisWithTooltip,{title:e.label||e.value,as:i.Typography,variant:"caption",color:a?"text.disabled":"text.primary",sx:{marginTop:"1px",lineHeight:"2"},maxWidth:"50%"}),e.secondaryText&&t.createElement(n.EllipsisWithTooltip,{title:e.secondaryText,as:i.Typography,variant:"caption",color:a?"text.disabled":"text.tertiary",sx:{marginTop:"1px",lineHeight:"1"},maxWidth:"50%"})),!!r&&!a&&t.createElement(i.Tooltip,{placement:"top",title:l},t.createElement(i.IconButton,{sx:{mx:1,opacity:"0"},onClick:a=>{a.stopPropagation(),r(e.value)},"aria-label":l},t.createElement(o.EditIcon,{color:"action",fontSize:"tiny"}))))}},"./packages/packages/core/editor-variables/src/components/ui/mismatch-variable-alert.tsx":function(e,a,r){r.r(a),r.d(a,{MismatchVariableAlert:function(){return MismatchVariableAlert}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n");const i={title:(0,o.__)("Variable has changed","elementor"),message:(0,o.__)("This variable is no longer compatible with this property. You can clear it or select a different one.","elementor"),buttons:{clear:(0,o.__)("Clear","elementor"),select:(0,o.__)("Select variable","elementor")}},MismatchVariableAlert=({onClose:e,onClear:a,triggerSelect:r})=>t.createElement(n.ClickAwayListener,{onClickAway:e},t.createElement(n.Alert,{variant:"standard",severity:"warning",onClose:e,action:t.createElement(t.Fragment,null,a&&t.createElement(n.AlertAction,{variant:"contained",onClick:a},i.buttons.clear),r&&t.createElement(n.AlertAction,{variant:"outlined",onClick:r},i.buttons.select)),sx:{maxWidth:300}},t.createElement(n.AlertTitle,null,i.title),t.createElement(n.Typography,{variant:"body2",color:"textPrimary"},i.message)))},"./packages/packages/core/editor-variables/src/components/ui/missing-variable-alert.tsx":function(e,a,r){r.r(a),r.d(a,{MissingVariableAlert:function(){return MissingVariableAlert}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n");const MissingVariableAlert=({onClose:e,onClear:a})=>t.createElement(n.ClickAwayListener,{onClickAway:e},t.createElement(n.Alert,{variant:"standard",severity:"warning",onClose:e,action:t.createElement(t.Fragment,null,a&&t.createElement(n.AlertAction,{variant:"contained",onClick:a},(0,o.__)("Clear","elementor"))),sx:{maxWidth:300}},t.createElement(n.AlertTitle,null,(0,o.__)("This variable is missing","elementor")),t.createElement(n.Typography,{variant:"body2",color:"textPrimary"},(0,o.__)("It may have been deleted. Try clearing this field and select a different value or variable.","elementor"))))},"./packages/packages/core/editor-variables/src/components/ui/no-search-results.tsx":function(e,a,r){r.r(a),r.d(a,{NoSearchResults:function(){return NoSearchResults}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n");const NoSearchResults=({searchValue:e,onClear:a,icon:r})=>t.createElement(n.Stack,{gap:1,alignItems:"center",justifyContent:"center",p:2.5,color:"text.secondary",sx:{pb:3.5,pt:8}},r,t.createElement(n.Typography,{align:"center",variant:"subtitle2"},(0,o.__)("Sorry, nothing matched","elementor"),t.createElement("br",null),"“",e,"”."),t.createElement(n.Typography,{align:"center",variant:"caption",sx:{display:"flex",flexDirection:"column"}},(0,o.__)("Try something else.","elementor"),t.createElement(n.Link,{color:"text.secondary",variant:"caption",component:"button",onClick:a},(0,o.__)("Clear & try again","elementor"))))},"./packages/packages/core/editor-variables/src/components/ui/styled-menu-list.tsx":function(e,a,r){r.r(a),r.d(a,{VariablesStyledMenuList:function(){return n}});var t=r("@elementor/ui");const n=(0,t.styled)(t.MenuList)(({theme:e,disabled:a})=>({"& > li":{height:32,width:"100%",display:"flex",alignItems:"center"},'& > [role="option"]':{...e.typography.caption,lineHeight:"inherit",padding:e.spacing(.5,1,.5,2),...!a&&{"&:hover, &:focus":{backgroundColor:e.palette.action.hover},cursor:"pointer"},'&[aria-selected="true"]':{backgroundColor:e.palette.action.selected},textOverflow:"ellipsis",position:"absolute",top:0,left:0,"&:hover .MuiIconButton-root, .MuiIconButton-root:focus":{opacity:1}},width:"100%",position:"relative"}))},"./packages/packages/core/editor-variables/src/components/ui/tags/assigned-tag.tsx":function(e,a,r){r.r(a),r.d(a,{AssignedTag:function(){return AssignedTag},SIZE:function(){return s}});var t=r("react"),n=r("@elementor/icons"),o=r("@elementor/ui"),i=r("@wordpress/i18n");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const s="tiny",l=(0,i.__)("Unlink variable","elementor"),AssignedTag=({startIcon:e,label:a,onUnlink:r,...i})=>{const c=[];return r&&c.push(t.createElement(o.Tooltip,{key:"unlink",title:l,placement:"bottom"},t.createElement(o.IconButton,{size:s,onClick:r,"aria-label":l},t.createElement(n.DetachIcon,{fontSize:s})))),t.createElement(o.Tooltip,{title:a,placement:"top"},t.createElement(o.UnstableTag,_extends({fullWidth:!0,showActionsOnHover:!0,startIcon:t.createElement(o.Stack,{gap:.5,direction:"row",alignItems:"center"},e),label:t.createElement(o.Box,{sx:{display:"inline-grid",minWidth:0}},t.createElement(o.Typography,{sx:{lineHeight:1.34},variant:"caption",noWrap:!0},a)),actions:c},i)))}},"./packages/packages/core/editor-variables/src/components/ui/tags/warning-variable-tag.tsx":function(e,a,r){r.r(a),r.d(a,{WarningVariableTag:function(){return i}});var t=r("react"),n=r("@elementor/icons"),o=r("@elementor/ui");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const i=t.forwardRef(({label:e,suffix:a,onClick:r,icon:i,...s},l)=>{const c=a?`${e} (${a})`:e;return t.createElement(o.Chip,_extends({ref:l,size:"tiny",color:"warning",shape:"rounded",variant:"standard",onClick:r,icon:t.createElement(n.AlertTriangleFilledIcon,null),label:t.createElement(o.Tooltip,{title:c,placement:"top"},t.createElement(o.Box,{sx:{display:"inline-grid",minWidth:0}},t.createElement(o.Typography,{variant:"caption",noWrap:!0,sx:{lineHeight:1.34}},c))),sx:{height:e=>e.spacing(3.5),borderRadius:e=>e.spacing(1),justifyContent:"flex-start",width:"100%"}},s))});i.displayName="WarningVariableTag"},"./packages/packages/core/editor-variables/src/components/ui/variable-promotion-chip.tsx":function(e,a,r){r.r(a),r.d(a,{VariablePromotionChip:function(){return c}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-ui"),i=r("@elementor/ui"),s=r("@elementor/utils"),l=r("@wordpress/i18n");const c=(0,t.forwardRef)(({variableType:e,upgradeUrl:a,trackingData:r},c)=>{const[p,u]=(0,t.useState)(!1);(0,o.useCanvasClickHandler)(p,()=>u(!1));const d=(0,t.useCallback)(()=>{u(e=>(e||(0,n.trackViewPromotion)(r),!e))},[r]);(0,t.useImperativeHandle)(c,()=>({toggle:d}),[d]);const b=(0,l.sprintf)((0,l.__)("%s variables","elementor"),(0,s.capitalize)(e)),m=(0,l.sprintf)((0,l.__)("Upgrade to continue creating and editing %s variables.","elementor"),e);return t.createElement(o.PromotionPopover,{open:p,title:b,content:m,ctaText:(0,l.__)("Upgrade now","elementor"),ctaUrl:a,onClose:e=>{e.stopPropagation(),u(!1)},onCtaClick:()=>(0,n.trackUpgradePromotionClick)(r)},t.createElement(i.Box,{onClick:e=>{e.stopPropagation(),d()},sx:{cursor:"pointer",display:"inline-flex"}},t.createElement(o.PromotionChip,null)))})},"./packages/packages/core/editor-variables/src/components/ui/variable/assigned-variable.tsx":function(e,a,r){r.r(a),r.d(a,{AssignedVariable:function(){return AssignedVariable}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/icons"),i=r("@elementor/ui"),s=r("./packages/packages/core/editor-variables/src/utils/unlink-variable.ts"),l=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),c=r("./packages/packages/core/editor-variables/src/components/variable-selection-popover.tsx"),p=r("./packages/packages/core/editor-variables/src/components/ui/tags/assigned-tag.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const AssignedVariable=({variable:e,propTypeKey:a})=>{const{startIcon:r,propTypeUtil:u}=(0,l.getVariableType)(a),{setValue:d}=(0,n.useBoundProp)(),b=(0,t.useRef)(null),m=(0,t.useId)(),v=(0,i.usePopupState)({variant:"popover",popupId:`elementor-variables-list-${m}`}),g=(0,s.createUnlinkHandler)(e,a,d),f=r||(()=>null);return t.createElement(i.Box,{ref:b},t.createElement(p.AssignedTag,_extends({label:e.label,startIcon:t.createElement(t.Fragment,null,t.createElement(o.ColorFilterIcon,{fontSize:p.SIZE}),t.createElement(f,{value:e.value})),onUnlink:g},(0,i.bindTrigger)(v))),t.createElement(i.Popover,_extends({disableScrollLock:!0,anchorEl:b.current,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},PaperProps:{sx:{my:1}}},(0,i.bindPopover)(v)),t.createElement(c.VariableSelectionPopover,{selectedVariable:e,closePopover:v.close,propTypeKey:u.key})))}},"./packages/packages/core/editor-variables/src/components/ui/variable/deleted-variable.tsx":function(e,a,r){r.r(a),r.d(a,{DeletedVariable:function(){return DeletedVariable}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/ui"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),l=r("./packages/packages/core/editor-variables/src/hooks/use-permissions.ts"),c=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),p=r("./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts"),u=r("./packages/packages/core/editor-variables/src/utils/unlink-variable.ts"),d=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),b=r("./packages/packages/core/editor-variables/src/components/variable-restore.tsx"),m=r("./packages/packages/core/editor-variables/src/components/ui/deleted-variable-alert.tsx"),v=r("./packages/packages/core/editor-variables/src/components/ui/tags/warning-variable-tag.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const DeletedVariable=({variable:e,propTypeKey:a})=>{const{propTypeUtil:r}=(0,d.getVariableType)(a),g=(0,n.useBoundProp)(),f=(0,l.usePermissions)(),[y,k]=(0,t.useState)(!1),closeInfotip=()=>k(!1),h=(0,t.useRef)(null),E=(0,t.useId)(),_=(0,o.usePopupState)({variant:"popover",popupId:`elementor-variables-restore-${E}`}),x={};f.canUnlink()&&(x.onUnlink=(0,u.createUnlinkHandler)(e,a,g.setValue)),f.canRestore()&&(x.onRestore=()=>{e.key&&(0,c.restoreVariable)(e.key).then(e=>{(0,p.resolveBoundPropAndSetValue)(r.create(e),g),closeInfotip()}).catch(()=>{closeInfotip(),_.setAnchorEl(h.current),_.open()})});return t.createElement(t.Fragment,null,t.createElement(o.Box,{ref:h},y&&t.createElement(o.Backdrop,{open:!0,onClick:closeInfotip,invisible:!0}),t.createElement(o.Infotip,{color:"warning",placement:"right-start",open:y,disableHoverListener:!0,onClose:closeInfotip,content:t.createElement(m.DeletedVariableAlert,{onClose:closeInfotip,onUnlink:x.onUnlink,onRestore:x.onRestore,label:e.label}),slotProps:{popper:{modifiers:[{name:"offset",options:{offset:[0,24]}}]}}},t.createElement(v.WarningVariableTag,{label:e.label,onClick:()=>k(e=>!e),suffix:(0,i.__)("deleted","elementor")})),t.createElement(o.Popover,_extends({disableScrollLock:!0,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},PaperProps:{sx:{my:1}}},(0,o.bindPopover)(_)),t.createElement(s.VariableTypeProvider,{propTypeKey:a},t.createElement(b.VariableRestore,{variableId:e.key??"",onClose:_.close,onSubmit:()=>{_.close()}})))))}},"./packages/packages/core/editor-variables/src/components/ui/variable/mismatch-variable.tsx":function(e,a,r){r.r(a),r.d(a,{MismatchVariable:function(){return MismatchVariable}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/ui"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/components/variable-selection-popover.tsx"),l=r("./packages/packages/core/editor-variables/src/components/ui/mismatch-variable-alert.tsx"),c=r("./packages/packages/core/editor-variables/src/components/ui/tags/warning-variable-tag.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const MismatchVariable=({variable:e})=>{const{setValue:a,value:r}=(0,n.useBoundProp)(),p=(0,t.useRef)(null),u=(0,t.useId)(),d=(0,o.usePopupState)({variant:"popover",popupId:`elementor-variables-list-${u}`}),[b,m]=(0,t.useState)(!1),closeInfotip=()=>m(!1),v=!!r;return t.createElement(o.Box,{ref:p},b&&t.createElement(o.Backdrop,{open:!0,onClick:closeInfotip,invisible:!0}),t.createElement(o.Infotip,{color:"warning",placement:"right-start",open:b,disableHoverListener:!0,onClose:closeInfotip,content:t.createElement(l.MismatchVariableAlert,{onClose:closeInfotip,onClear:v?()=>{closeInfotip(),a(null)}:void 0,triggerSelect:()=>{closeInfotip(),d.setAnchorEl(p.current),d.open()}}),slotProps:{popper:{modifiers:[{name:"offset",options:{offset:[0,24]}}]}}},t.createElement(c.WarningVariableTag,{label:e.label,onClick:()=>m(e=>!e),suffix:(0,i.__)("changed","elementor")})),t.createElement(o.Popover,_extends({disableScrollLock:!0,anchorEl:p.current,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},PaperProps:{sx:{my:1}}},(0,o.bindPopover)(d)),t.createElement(s.VariableSelectionPopover,{selectedVariable:e,closePopover:d.close,propTypeKey:e.type})))}},"./packages/packages/core/editor-variables/src/components/ui/variable/missing-variable.tsx":function(e,a,r){r.r(a),r.d(a,{MissingVariable:function(){return MissingVariable}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/ui"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/components/ui/missing-variable-alert.tsx"),l=r("./packages/packages/core/editor-variables/src/components/ui/tags/warning-variable-tag.tsx");const MissingVariable=()=>{const{setValue:e}=(0,n.useBoundProp)(),[a,r]=(0,t.useState)(!1),closeInfotip=()=>r(!1);return t.createElement(t.Fragment,null,a&&t.createElement(o.Backdrop,{open:!0,onClick:closeInfotip,invisible:!0}),t.createElement(o.Infotip,{color:"warning",placement:"right-start",open:a,disableHoverListener:!0,onClose:closeInfotip,content:t.createElement(s.MissingVariableAlert,{onClose:closeInfotip,onClear:()=>e(null)}),slotProps:{popper:{modifiers:[{name:"offset",options:{offset:[0,24]}}]}}},t.createElement(l.WarningVariableTag,{label:(0,i.__)("Missing variable","elementor"),onClick:()=>r(e=>!e)})))}},"./packages/packages/core/editor-variables/src/components/variable-creation.tsx":function(e,a,r){r.r(a),r.d(a,{VariableCreation:function(){return VariableCreation}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-ui"),i=r("@elementor/icons"),s=r("@elementor/ui"),l=r("@wordpress/i18n"),c=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),p=r("./packages/packages/core/editor-variables/src/hooks/use-initial-value.ts"),u=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),d=r("./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts"),b=r("./packages/packages/core/editor-variables/src/utils/tracking.ts"),m=r("./packages/packages/core/editor-variables/src/utils/validations.ts"),v=r("./packages/packages/core/editor-variables/src/components/fields/label-field.tsx"),g=r("./packages/packages/core/editor-variables/src/components/ui/form-field.tsx");const f="tiny",VariableCreation=({onGoBack:e,onClose:a})=>{const{icon:r,valueField:y,variableType:k,propTypeUtil:h}=(0,c.useVariableType)(),{setVariableValue:E,path:_}=(0,d.useVariableBoundProp)(),{propType:x}=(0,n.useBoundProp)(),V=(0,p.useInitialValue)(),[C,T]=(0,t.useState)(V),[S,w]=(0,t.useState)(""),[P,A]=(0,t.useState)(""),[I,R]=(0,t.useState)(""),[L,z]=(0,t.useState)(h.key),{labelFieldError:O,setLabelFieldError:U}=(0,v.useLabelError)(),closePopover=()=>{T(""),w(""),A(""),R(""),a()},handleCreateAndTrack=()=>{(0,u.createVariable)({value:C,label:S,type:L}).then(e=>{E(e),closePopover()}).catch(e=>{const a=(0,m.mapServerError)(e);if(a&&"label"===a.field)return w(""),void U({value:S,message:a.message});A(m.ERROR_MESSAGES.UNEXPECTED_ERROR)}),(0,b.trackVariableEvent)({varType:k,controlPath:_.join("."),action:"save"})},F=""===S.trim()||("string"==typeof C?""===C.trim():!1===Boolean(C))||!!P,handleKeyDown=e=>{"Enter"!==e.key||F||(e.preventDefault(),handleCreateAndTrack())};return t.createElement(o.SectionPopoverBody,{height:"auto"},t.createElement(o.PopoverHeader,{icon:t.createElement(t.Fragment,null,e&&t.createElement(s.IconButton,{size:f,"aria-label":(0,l.__)("Go Back","elementor"),onClick:e},t.createElement(i.ArrowLeftIcon,{fontSize:f})),t.createElement(r,{fontSize:f})),title:(0,l.__)("Create variable","elementor"),onClose:closePopover}),t.createElement(s.Divider,null),t.createElement(n.PopoverContent,{p:2},t.createElement(g.FormField,{id:"variable-label",label:(0,l.__)("Name","elementor"),errorMsg:O?.message,noticeMsg:(0,m.labelHint)(S)},t.createElement(v.LabelField,{id:"variable-label",value:S,error:O,onChange:e=>{w(e),A("")},onErrorChange:e=>{U({value:"",message:e})},onKeyDown:handleKeyDown,focusOnShow:!0})),y&&t.createElement(g.FormField,{errorMsg:I,label:(0,l.__)("Value","elementor")},t.createElement(s.Typography,{variant:"h5",id:"variable-value-wrapper"},t.createElement(y,{value:C,onPropTypeKeyChange:e=>z(e),onChange:e=>{T(e),A(""),R("")},onValidationChange:R,propType:x,onKeyDown:handleKeyDown}))),P&&t.createElement(s.FormHelperText,{error:!0},P)),t.createElement(s.CardActions,{sx:{pt:.5,pb:1}},t.createElement(s.Button,{id:"create-variable-button",size:"small",variant:"contained",disabled:F,onClick:handleCreateAndTrack},(0,l.__)("Create","elementor"))))}},"./packages/packages/core/editor-variables/src/components/variable-edit.tsx":function(e,a,r){r.r(a),r.d(a,{VariableEdit:function(){return VariableEdit}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-current-user"),i=r("@elementor/editor-ui"),s=r("@elementor/icons"),l=r("@elementor/ui"),c=r("@wordpress/i18n"),p=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),u=r("./packages/packages/core/editor-variables/src/hooks/use-permissions.ts"),d=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),b=r("./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts"),m=r("./packages/packages/core/editor-variables/src/style-variables-repository.ts"),v=r("./packages/packages/core/editor-variables/src/utils/validations.ts"),g=r("./packages/packages/core/editor-variables/src/components/fields/label-field.tsx"),f=r("./packages/packages/core/editor-variables/src/components/ui/delete-confirmation-dialog.tsx"),y=r("./packages/packages/core/editor-variables/src/components/ui/edit-confirmation-dialog.tsx"),k=r("./packages/packages/core/editor-variables/src/components/ui/form-field.tsx");const h="tiny",E=(0,c.__)("Delete variable","elementor"),VariableEdit=({onClose:e,onGoBack:a,onSubmit:r,editId:_})=>{const{icon:x,valueField:V,variableType:C,propTypeUtil:T}=(0,p.useVariableType)(),{setVariableValue:S,variableId:w}=(0,b.useVariableBoundProp)(),{propType:P}=(0,n.useBoundProp)(),[A,I]=(0,o.useSuppressedMessage)(y.EDIT_CONFIRMATION_DIALOG_ID),[R,L]=(0,t.useState)(!1),[z,O]=(0,t.useState)(!1),[U,F]=(0,t.useState)(""),[D,B]=(0,t.useState)(""),{labelFieldError:M,setLabelFieldError:N}=(0,g.useLabelError)(),j=(0,d.useVariable)(_),[G,H]=(0,t.useState)(j?.type??T.key);if(!j)throw new Error(`Global ${C} variable not found`);const q=(0,u.usePermissions)(),[W,$]=(0,t.useState)(()=>j.value),[K,X]=(0,t.useState)(()=>j.label);(0,t.useEffect)(()=>(m.styleVariablesRepository.update({[_]:{...j,value:W}}),()=>{m.styleVariablesRepository.update({[_]:{...j}})}),[_,W,j]);const handleUpdate=()=>{A?handleSaveVariable():O(!0)},handleSaveVariable=()=>{const e=G!==j.type?{value:W,label:K,type:G}:{value:W,label:K};(0,d.updateVariable)(_,e).then(()=>{maybeTriggerBoundPropChange(),r?.()}).catch(e=>{const a=(0,v.mapServerError)(e);if(a&&"label"===a.field)return X(""),void N({value:K,message:a.message});F(v.ERROR_MESSAGES.UNEXPECTED_ERROR)})},maybeTriggerBoundPropChange=()=>{_===w&&S(_)},handleDeleteConfirmation=()=>{L(!0)},J=[];q.canDelete()&&J.push(t.createElement(l.Tooltip,{key:"delete",placement:"top",title:E},t.createElement(l.IconButton,{size:h,onClick:handleDeleteConfirmation,"aria-label":E},t.createElement(s.TrashIcon,{fontSize:h}))));const Y=W===j.value&&K===j.label||""===K.trim()||("string"==typeof W?""===W.trim():!1===Boolean(W))||!!U,handleKeyDown=e=>{"Enter"!==e.key||Y||(e.preventDefault(),handleUpdate())};return t.createElement(t.Fragment,null,t.createElement(i.SectionPopoverBody,{height:"auto"},t.createElement(i.PopoverHeader,{title:(0,c.__)("Edit variable","elementor"),onClose:e,icon:t.createElement(t.Fragment,null,a&&t.createElement(l.IconButton,{size:h,"aria-label":(0,c.__)("Go Back","elementor"),onClick:a},t.createElement(s.ArrowLeftIcon,{fontSize:h})),t.createElement(x,{fontSize:h})),actions:J}),t.createElement(l.Divider,null),t.createElement(n.PopoverContent,{p:2},t.createElement(k.FormField,{id:"variable-label",label:(0,c.__)("Name","elementor"),errorMsg:M?.message,noticeMsg:(0,v.labelHint)(K)},t.createElement(g.LabelField,{id:"variable-label",value:K,error:M,onChange:e=>{X(e),F("")},onErrorChange:e=>{N({value:"",message:e})},onKeyDown:handleKeyDown,focusOnShow:!0})),V&&t.createElement(k.FormField,{errorMsg:D,label:(0,c.__)("Value","elementor")},t.createElement(l.Typography,{variant:"h5"},t.createElement(V,{propTypeKey:j.type,onPropTypeKeyChange:e=>H(e),value:W,onChange:e=>{$(e),F(""),B("")},onKeyDown:handleKeyDown,onValidationChange:B,propType:P}))),U&&t.createElement(l.FormHelperText,{error:!0},U)),t.createElement(l.CardActions,{sx:{pt:.5,pb:1}},t.createElement(l.Button,{size:"small",variant:"contained",disabled:Y,onClick:handleUpdate},(0,c.__)("Save","elementor")))),R&&t.createElement(f.DeleteConfirmationDialog,{open:!0,label:K,onConfirm:()=>{(0,d.deleteVariable)(_).then(()=>{maybeTriggerBoundPropChange(),r?.()})},closeDialog:()=>{L(!1)}}),z&&!A&&t.createElement(y.EditConfirmationDialog,{closeDialog:()=>{O(!1)},onConfirm:handleSaveVariable,onSuppressMessage:I}))}},"./packages/packages/core/editor-variables/src/components/variable-restore.tsx":function(e,a,r){r.r(a),r.d(a,{VariableRestore:function(){return VariableRestore}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-ui"),i=r("@elementor/ui"),s=r("@wordpress/i18n"),l=r("./packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx"),c=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),p=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),u=r("./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts"),d=r("./packages/packages/core/editor-variables/src/utils/validations.ts"),b=r("./packages/packages/core/editor-variables/src/components/fields/label-field.tsx"),m=r("./packages/packages/core/editor-variables/src/components/ui/form-field.tsx");const VariableRestore=({variableId:e,onClose:a,onSubmit:r})=>{const{icon:v,valueField:g,variableType:f,propTypeUtil:y}=(0,c.useVariableType)(),{setVariableValue:k}=(0,u.useVariableBoundProp)(),{propType:h}=(0,n.useBoundProp)(),E=(0,p.useVariable)(e);if(!E)throw new Error(`Global ${f} variable not found`);const[_,x]=(0,t.useState)(""),[V,C]=(0,t.useState)(""),[T,S]=(0,t.useState)(E.label),[w,P]=(0,t.useState)(E.value),[A,I]=(0,t.useState)(E?.type??y.key),{labelFieldError:R,setLabelFieldError:L}=(0,b.useLabelError)({value:E.label,message:d.ERROR_MESSAGES.DUPLICATED_LABEL}),handleRestore=()=>{(A!==E.type?(0,p.restoreVariable)(e,T,w,A):(0,p.restoreVariable)(e,T,w)).then(()=>{k(e),r?.()}).catch(e=>{const a=(0,d.mapServerError)(e);if(a&&"label"===a.field)return S(""),void L({value:T,message:a.message});x(d.ERROR_MESSAGES.UNEXPECTED_ERROR)})},z=w===E.value&&T===E.label||""===T.trim()||("string"==typeof w?""===w.trim():!1===Boolean(w))||!!_,handleKeyDown=e=>{"Enter"!==e.key||z||(e.preventDefault(),handleRestore())};return t.createElement(l.PopoverContentRefContextProvider,null,t.createElement(o.SectionPopoverBody,{height:"auto"},t.createElement(o.PopoverHeader,{icon:t.createElement(v,{fontSize:"tiny"}),title:(0,s.__)("Restore variable","elementor"),onClose:a}),t.createElement(i.Divider,null),t.createElement(n.PopoverContent,{p:2},t.createElement(m.FormField,{id:"variable-label",label:(0,s.__)("Name","elementor"),errorMsg:R?.message,noticeMsg:(0,d.labelHint)(T)},t.createElement(b.LabelField,{id:"variable-label",value:T,error:R,onChange:e=>{S(e),x("")},onErrorChange:e=>{L({value:"",message:e})},onKeyDown:handleKeyDown,focusOnShow:!0})),g&&t.createElement(m.FormField,{errorMsg:V,label:(0,s.__)("Value","elementor")},t.createElement(i.Typography,{variant:"h5"},t.createElement(g,{propTypeKey:A,onPropTypeKeyChange:e=>I(e),value:w,onChange:e=>{P(e),x(""),C("")},onValidationChange:C,propType:h,onKeyDown:handleKeyDown}))),_&&t.createElement(i.FormHelperText,{error:!0},_)),t.createElement(i.CardActions,{sx:{pt:.5,pb:1}},t.createElement(i.Button,{size:"small",variant:"contained",disabled:z,onClick:handleRestore},(0,s.__)("Restore","elementor")))))}},"./packages/packages/core/editor-variables/src/components/variable-selection-popover.tsx":function(e,a,r){r.r(a),r.d(a,{VariableSelectionPopover:function(){return VariableSelectionPopover}});var t=r("react"),n=r("@elementor/editor-v1-adapters"),o=r("./packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx"),i=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),s=r("./packages/packages/core/editor-variables/src/hooks/use-permissions.ts"),l=r("./packages/packages/core/editor-variables/src/hooks/use-quota-permissions.ts"),c=r("./packages/packages/core/editor-variables/src/components/variable-creation.tsx"),p=r("./packages/packages/core/editor-variables/src/components/variable-edit.tsx"),u=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx"),d=r("./packages/packages/core/editor-variables/src/components/variables-selection.tsx");const b="list",m="add",v="edit",VariableSelectionPopover=({closePopover:e,propTypeKey:a,selectedVariable:r})=>{const[g,f]=(0,t.useState)(b),[y,k]=(0,t.useState)(""),{open:h}=(0,u.usePanelActions)(),E=(0,n.isExperimentActive)("e_variables_manager")?()=>{(0,n.isExperimentActive)("e_editor_design_system_panel")?window.dispatchEvent(new CustomEvent("elementor/toggle-design-system",{detail:{tab:"variables"}})):h()}:void 0;return t.createElement(i.VariableTypeProvider,{propTypeKey:a},t.createElement(o.PopoverContentRefContextProvider,null,function RenderView(e){const a=(0,s.usePermissions)(),r=(0,l.useQuotaPermissions)(e.propTypeKey),n={onClose:()=>{e.closePopover()},onGoBack:()=>{e.setCurrentView(b)}};a.canAdd()&&(n.onAdd=()=>{e.setCurrentView(m)});a.canEdit()&&(n.onEdit=a=>{e.setEditId(a),e.setCurrentView(v)});a.canManageSettings()&&e.onSettings&&(n.onSettings=()=>{e.closePopover(),e.onSettings?.()});const handleSubmitOnEdit=()=>{e?.selectedVariable?.key===e.editId?n.onClose():n.onGoBack?.()};if(b===e.currentView)return t.createElement(d.VariablesSelection,{closePopover:n.onClose,onAdd:n.onAdd,onEdit:n.onEdit,onSettings:n.onSettings,disabled:!r.canAdd()});if(m===e.currentView)return t.createElement(c.VariableCreation,{onGoBack:n.onGoBack,onClose:n.onClose});if(v===e.currentView)return t.createElement(p.VariableEdit,{editId:e.editId,onGoBack:n.onGoBack,onClose:n.onClose,onSubmit:handleSubmitOnEdit});return null}({propTypeKey:a,currentView:g,selectedVariable:r,editId:y,setEditId:k,setCurrentView:f,closePopover:e,onSettings:E})))}},"./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-auto-edit.ts":function(e,a,r){r.r(a),r.d(a,{useAutoEdit:function(){return useAutoEdit}});var t=r("react");const useAutoEdit=()=>{const[e,a]=(0,t.useState)(void 0);return{autoEditVariableId:e,startAutoEdit:(0,t.useCallback)(e=>{a(e)},[]),handleAutoEditComplete:(0,t.useCallback)(()=>{setTimeout(()=>{a(void 0)},100)},[])}}},"./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-error-navigation.ts":function(e,a,r){r.r(a),r.d(a,{useErrorNavigation:function(){return useErrorNavigation}});var t=r("react");const useErrorNavigation=()=>{const e=(0,t.useRef)(0);return{createNavigationCallback:(0,t.useCallback)((a,r,t)=>()=>{if(!a?.length)return;const n=e.current,o=a[n];if(o){r(o);const i=n+1;i>=a.length?(t(),e.current=0):e.current=i}},[]),resetNavigation:(0,t.useCallback)(()=>{e.current=0},[])}}},"./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-variables-manager-state.ts":function(e,a,r){r.r(a),r.d(a,{useVariablesManagerState:function(){return useVariablesManagerState}});var t=r("react"),n=r("./packages/packages/core/editor-variables/src/batch-operations.ts"),o=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),i=r("./packages/packages/core/editor-variables/src/service.ts"),s=r("./packages/packages/core/editor-variables/src/storage.ts"),l=r("./packages/packages/core/editor-variables/src/utils/duplicate-label.ts"),c=r("./packages/packages/core/editor-variables/src/utils/filter-by-search.ts"),p=r("./packages/packages/core/editor-variables/src/utils/variables-to-list.ts"),u=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const useVariablesManagerState=()=>{const[e,a]=(0,t.useState)(()=>(0,o.getVariables)(!1)),[r,d]=(0,t.useState)([]),[b,m]=(0,t.useState)(!1),[v,g]=(0,t.useState)(!1),[f,y]=(0,t.useState)(!1),[k,h]=(0,t.useState)("");(0,t.useEffect)(()=>{const handleStorageUpdated=()=>{a((0,o.getVariables)(!1)),d([]),g(!1)};return window.addEventListener(s.STORAGE_UPDATED_EVENT,handleStorageUpdated),()=>{window.removeEventListener(s.STORAGE_UPDATED_EVENT,handleStorageUpdated)}},[]);const E=(0,t.useCallback)(r=>{Object.entries(r).some(([a,r])=>{const t=e[a];return!t||(t.label!==r.label||t.value!==r.value||t.order!==r.order||t.type!==r.type||(t.sync_to_v3??!1)!==(r.sync_to_v3??!1))})&&(a({...e,...r}),g(!0))},[e]),_=(0,t.useCallback)((e,r,t)=>{const o=(0,n.generateTempId)(),i={id:o,label:r.trim(),value:t.trim(),type:e};return a(e=>({...e,[o]:i})),g(!0),o},[]),x=(0,t.useCallback)(e=>{const r=(0,n.generateTempId)();return a(a=>{const t=a[e];if(!t||t.deleted)return a;const n=Object.values(a).filter(e=>!e.deleted).map(e=>e.label);return{...a,[r]:{label:(0,l.generateDuplicateLabel)(t.label,n),value:t.value,type:t.type}}}),g(!0),r},[]),V=(0,t.useCallback)(e=>{d(a=>[...a,e]),a(a=>({...a,[e]:{...a[e],deleted:!0}})),g(!0)},[]),C=(0,t.useCallback)(e=>{a(a=>({...a,[e]:{...a[e],sync_to_v3:!0}})),g(!0)},[]),T=(0,t.useCallback)(e=>{a(a=>({...a,[e]:{...a[e],sync_to_v3:!1}})),g(!0)},[]),S=(0,t.useCallback)(async()=>{const t=(0,o.getVariables)(!1);y(!0);const n=await i.service.batchSave(t,e,r);if(n.success){await i.service.load();const e=i.service.variables();a(e),d([]),g(!1)}return{success:n.success}},[e,r]);return{variables:(0,t.useCallback)(()=>{const a=(0,p.variablesToList)(e).filter(e=>!e.deleted),r=(0,p.applySelectionFilters)(a,(0,u.getVariableTypes)()),t=(0,c.filterBySearch)(r,k);return Object.fromEntries(t.map(({key:e,...a})=>[e,a]))},[e,k])(),deletedVariables:r,isDirty:v,isSaveDisabled:b,handleOnChange:E,createVariable:_,duplicateVariable:x,handleDeleteVariable:V,handleStartSync:C,handleStopSync:T,handleSave:S,isSaving:f,handleSearch:e=>{h(e)},searchValue:k,setIsSaving:y,setIsSaveDisabled:m}}},"./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-edit-menu.tsx":function(e,a,r){r.r(a),r.d(a,{VariableEditMenu:function(){return VariableEditMenu}});var t=r("react"),n=r("@elementor/icons"),o=r("@elementor/ui");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const VariableEditMenu=({menuActions:e,disabled:a,itemId:r})=>{const i=(0,o.usePopupState)({variant:"popover"}),s=(0,o.bindTrigger)(i);return t.createElement(t.Fragment,null,t.createElement(o.IconButton,_extends({},s,{disabled:a,size:"tiny",onClick:e=>{e.stopPropagation(),s.onClick?.(e)}}),t.createElement(n.DotsVerticalIcon,{fontSize:"tiny"})),t.createElement(o.Menu,_extends({disablePortal:!0,MenuListProps:{dense:!0},PaperProps:{elevation:6}},(0,o.bindMenu)(i),{anchorEl:i.anchorEl,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},open:i.isOpen,onClose:i.close}),e.map(e=>t.createElement(o.MenuItem,{key:e.name,onClick:a=>{a.stopPropagation(),e.onClick?.(r),i.close()},sx:{color:e.color,gap:1}},e.icon&&(0,t.createElement)(e.icon,{fontSize:"inherit"})," ",e.name))))}},"./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-cell.tsx":function(e,a,r){r.r(a),r.d(a,{VariableTableCell:function(){return VariableTableCell}});var t=r("react"),n=r("@elementor/ui");const VariableTableCell=({children:e,isHeader:a,width:r,maxWidth:o,align:i,noPadding:s,sx:l})=>{const c={maxWidth:o??150,cursor:"initial",typography:"caption",...a&&{color:"text.primary",fontWeight:"bold"},...a&&!s&&{padding:"10px 16px"},...r&&{width:r},...l};return t.createElement(n.TableCell,{size:"small",padding:s?"none":void 0,align:i,sx:c},e)}},"./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-row.tsx":function(e,a,r){r.r(a),r.d(a,{VariableRow:function(){return VariableRow}});var t=r("react"),n=r("@elementor/editor-ui"),o=r("@elementor/icons"),i=r("@elementor/ui"),s=r("./packages/packages/core/editor-variables/src/hooks/use-quota-permissions.ts"),l=r("./packages/packages/core/editor-variables/src/components/fields/label-field.tsx"),c=r("./packages/packages/core/editor-variables/src/components/ui/variable-promotion-chip.tsx"),p=r("./packages/packages/core/editor-variables/src/components/variables-manager/variable-editable-cell.tsx"),u=r("./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-edit-menu.tsx"),d=r("./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-cell.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const b={target_name:"variables_manager",target_location:"variables_manager"},VariableRow=e=>{const{row:a,variables:r,handleOnChange:m,autoEditVariableId:v,onAutoEditComplete:g,onFieldError:f,menuActions:y,handleRowRef:k,itemProps:h,showDropIndication:E,triggerProps:_,itemStyle:x,triggerStyle:V,isDragged:C,dropPosition:T,setTriggerRef:S,isSorting:w}=e,P=(0,t.useRef)(null),A=!(0,s.useQuotaPermissions)(a.type).canEdit(),I=E&&"before"===T,R=E&&"after"===T;return t.createElement(i.TableRow,_extends({},h,{ref:h.ref,selected:C,sx:{...A&&{"& td, & th":{color:"text.disabled"}},...I&&{"& td, & th":{borderTop:"2px solid",borderTopColor:"primary.main"}},...R&&{"& td, & th":{borderBottom:"2px solid",borderBottomColor:"primary.main"}},"&:hover, &:focus-within":{backgroundColor:"action.hover",'& [role="toolbar"], & [draggable]':{opacity:1}},'& [role="toolbar"], & [draggable]':{opacity:0}},style:{...x,...V},onClick:()=>{A&&P.current?.toggle()}}),t.createElement(d.VariableTableCell,{noPadding:!0,width:10,maxWidth:10},t.createElement(i.IconButton,_extends({size:"small",ref:S},_,{disabled:w,draggable:!0}),t.createElement(o.GripVerticalIcon,{fontSize:"inherit"}))),t.createElement(d.VariableTableCell,null,t.createElement(p.VariableEditableCell,{initialValue:a.name,onChange:e=>{e===a.name||A||m({...r,[a.id]:{...r[a.id],label:e}})},prefixElement:(0,t.createElement)(a.icon,{fontSize:"inherit",color:A?"disabled":"inherit"}),editableElement:({value:e,onChange:n,onValidationChange:o,error:i})=>t.createElement(l.LabelField,{id:"variable-label-"+a.id,size:"tiny",value:e,onChange:n,onErrorChange:e=>{o?.(e),f?.(!!e)},error:i,focusOnShow:!0,selectOnShow:v===a.id,showWarningInfotip:!0,variables:r}),autoEdit:v===a.id&&!A,onRowRef:k(a.id),onAutoEditComplete:v===a.id?g:void 0,fieldType:"label",disabled:A},t.createElement(n.EllipsisWithTooltip,{title:a.name,sx:{border:"4px solid transparent"}},a.name))),t.createElement(d.VariableTableCell,null,t.createElement(p.VariableEditableCell,{initialValue:a.value,onChange:e=>{e===a.value||A||m({...r,[a.id]:{...r[a.id],value:e}})},editableElement:({value:e,onChange:n,onValidationChange:o,error:i})=>a.valueField?.({value:e,onChange:n,onPropTypeKeyChange:e=>{A||e===a.type||m({...r,[a.id]:{...r[a.id],type:e}})},propTypeKey:a.type,onValidationChange:e=>{o?.(e),f?.(!!e)},error:i})??t.createElement(t.Fragment,null),onRowRef:k(a.id),gap:.25,fieldType:"value",disabled:A},a.startIcon&&a.startIcon({value:a.value}),t.createElement(n.EllipsisWithTooltip,{title:a.value,sx:{border:"4px solid transparent",lineHeight:"1",pt:.25}},a.value))),t.createElement(d.VariableTableCell,{align:"right",noPadding:!0,width:16,maxWidth:16,sx:{paddingInlineEnd:1}},t.createElement(i.Stack,{role:"toolbar",direction:"row",justifyContent:"flex-end",alignItems:"center"},A&&t.createElement(c.VariablePromotionChip,{variableType:a.variableType,upgradeUrl:`https://go.elementor.com/renew-license-manager-${a.variableType}-variable`,ref:P,trackingData:b}),t.createElement(u.VariableEditMenu,{menuActions:y(a.id),disabled:w,itemId:a.id}))))}},"./packages/packages/core/editor-variables/src/components/variables-manager/variable-editable-cell.tsx":function(e,a,r){r.r(a),r.d(a,{VariableEditableCell:function(){return i}});var t=r("react"),n=r("@elementor/ui"),o=r("./packages/packages/core/editor-variables/src/components/fields/label-field.tsx");const i=t.memo(({initialValue:e,children:a,editableElement:r,onChange:i,prefixElement:s,autoEdit:l=!1,onRowRef:c,onAutoEditComplete:p,gap:u=1,fieldType:d,disabled:b=!1})=>{const[m,v]=(0,t.useState)(e),[g,f]=(0,t.useState)(!1),{labelFieldError:y,setLabelFieldError:k}=(0,o.useLabelError)(),[h,E]=(0,t.useState)(""),_=(0,t.useRef)(null),x=(0,t.useCallback)(()=>{"label"===d&&y?.message||"value"===d&&h||i(m),f(!1)},[m,i,d,y,h]);(0,t.useEffect)(()=>{c?.(_?.current)},[c]),(0,t.useEffect)(()=>{!l||g||b||(f(!0),p?.())},[l,g,p,b]);const handleDoubleClick=()=>{b||f(!0)},handleKeyDown=e=>{b||("Enter"===e.key?x():"Escape"===e.key&&f(!1)," "!==e.key||g||(e.preventDefault(),f(!0)))},V=(0,t.useCallback)(e=>{v(e)},[]),C=(0,t.useCallback)(e=>{"label"===d?k({value:m,message:e}):E(e)},[d,m,k,E]);let T;"label"===d?T=y:"value"===d&&(T={value:m,message:h});const S=r({value:m,onChange:V,onValidationChange:C,error:T});return g?t.createElement(n.ClickAwayListener,{onClickAway:x},t.createElement(n.Stack,{ref:_,direction:"row",alignItems:"center",gap:u,onDoubleClick:handleDoubleClick,onKeyDown:handleKeyDown,tabIndex:0,role:"button","aria-label":"Double click or press Space to edit"},s,S)):t.createElement(n.Stack,{ref:_,direction:"row",alignItems:"center",gap:u,onDoubleClick:handleDoubleClick,onKeyDown:handleKeyDown,tabIndex:b?-1:0,role:"button","aria-label":b?"":"Double click or press Space to edit"},s,a)})},"./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-create-menu.tsx":function(e,a,r){r.r(a),r.d(a,{SIZE:function(){return b},VariableManagerCreateMenu:function(){return VariableManagerCreateMenu},getDefaultName:function(){return getDefaultName}});var t=r("react"),n=r("@elementor/icons"),o=r("@elementor/ui"),i=r("@elementor/utils"),s=r("@wordpress/i18n"),l=r("./packages/packages/core/editor-variables/src/hooks/use-quota-permissions.ts"),c=r("./packages/packages/core/editor-variables/src/utils/tracking.ts"),p=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),u=r("./packages/packages/core/editor-variables/src/components/ui/variable-promotion-chip.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const d={target_name:"variables_manager",target_location:"variables_manager",location_l1:"create variable menu"},b="tiny",VariableManagerCreateMenu=({variables:e,onCreate:a,menuState:r,outlinedTrigger:i=!1})=>{const l=(0,t.useRef)(null),c=(0,p.getVariableTypes)(),u=(0,t.useMemo)(()=>Object.entries(c).filter(([,e])=>!!e.defaultValue).map(([e,a])=>({key:e,propTypeKey:a.propTypeUtil.key,variableType:a.variableType,defaultValue:a.defaultValue||"",icon:a.icon})),[c]);return t.createElement(t.Fragment,null,t.createElement(o.IconButton,_extends({},(0,o.bindTrigger)(r),{ref:l,size:b,variant:i?"outlined":void 0,"aria-label":(0,s.__)("Add variable","elementor")}),t.createElement(n.PlusIcon,{fontSize:b})),t.createElement(o.Menu,_extends({disablePortal:!0,MenuListProps:{dense:!0},PaperProps:{elevation:6}},(0,o.bindMenu)(r),{anchorEl:l.current,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},"data-testid":"variable-manager-create-menu"}),u.map(n=>t.createElement(MenuOption,{key:n.key,config:n,variables:e,onCreate:a,onClose:r.close}))))},MenuOption=({config:e,variables:a,onCreate:r,onClose:n})=>{const s=(0,t.useRef)(null),p=(0,l.useQuotaPermissions)(e.propTypeKey),m=(0,i.capitalize)(e.variableType),v=!p.canAdd();return t.createElement(o.MenuItem,{onClick:()=>{if(v)return void s.current?.toggle();const t=getDefaultName(a,e.variableType);r(e.key,t,e.defaultValue),(0,c.trackVariablesManagerEvent)({action:"add",varType:e.variableType}),n()},sx:{gap:1.5,cursor:"pointer"}},(0,t.createElement)(e.icon,{fontSize:b,color:v?"disabled":"action"}),t.createElement(o.Typography,{variant:"caption",color:v?"text.disabled":"text.primary"},m),v&&t.createElement(u.VariablePromotionChip,{variableType:e.variableType,upgradeUrl:`https://go.elementor.com/go-pro-manager-${e.variableType}-variable/`,ref:s,trackingData:d}))},getDefaultName=(e,a)=>{const r=new RegExp(`^${a}-(\\d+)$`,"i"),t=new Set;Object.values(e).forEach(e=>{const a=e.label.match(r);a&&t.add(parseInt(a[1],10))});let n=1;for(;t.has(n);)n++;return`${a}-${n}`}},"./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx":function(e,a,r){r.r(a),r.d(a,{VariablesManagerPanel:function(){return VariablesManagerPanel},VariablesManagerPanelEmbedded:function(){return VariablesManagerPanelEmbedded},panel:function(){return V},usePanelActions:function(){return C}});var t=r("react"),n=r("@elementor/editor-current-user"),o=r("@elementor/editor-panels"),i=r("@elementor/editor-ui"),s=r("@elementor/editor-v1-adapters"),l=r("@elementor/icons"),c=r("@elementor/ui"),p=r("@wordpress/i18n"),u=r("./packages/packages/core/editor-variables/src/utils/tracking.ts"),d=r("./packages/packages/core/editor-variables/src/utils/validations.ts"),b=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),m=r("./packages/packages/core/editor-variables/src/components/ui/delete-confirmation-dialog.tsx"),v=r("./packages/packages/core/editor-variables/src/components/ui/empty-state.tsx"),g=r("./packages/packages/core/editor-variables/src/components/ui/no-search-results.tsx"),f=r("./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-auto-edit.ts"),y=r("./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-error-navigation.ts"),k=r("./packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-variables-manager-state.ts"),h=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-create-menu.tsx"),E=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-table.tsx");const _="variables-manager",x="stop-sync-variable",{panel:V,usePanelActions:C}=(0,o.__createPanel)({id:_,component:VariablesManagerPanel,allowedEditModes:["edit",_],onOpen:()=>{(0,s.changeEditMode)(_)},onClose:async()=>{(0,s.changeEditMode)("edit")},isOpenPreviousElement:!0});function VariablesManagerPanelEmbedded({onRequestClose:e,onExposeCloseAttempt:a}){return t.createElement(VariablesManagerPanelRoot,{embedded:!0,onRequestClose:e,onExposeCloseAttempt:a})}function VariablesManagerPanel(){return t.createElement(VariablesManagerPanelRoot,null)}function VariablesManagerPanelRoot({embedded:e=!1,onRequestClose:a,onExposeCloseAttempt:r}={}){const{close:s}=C(),_=(0,t.useMemo)(()=>e?a??(async()=>{}):s,[e,a,s]),{open:V,close:T,isOpen:S}=(0,i.useDialog)(),[w]=(0,n.useSuppressedMessage)(x),P=(0,c.usePopupState)({variant:"popover"}),{variables:A,isDirty:I,searchValue:R,isSaveDisabled:L,handleOnChange:z,createVariable:O,duplicateVariable:U,handleDeleteVariable:F,handleStartSync:D,handleStopSync:B,handleSave:M,isSaving:N,handleSearch:j,setIsSaving:G,setIsSaveDisabled:H}=(0,k.useVariablesManagerState)(),{autoEditVariableId:q,startAutoEdit:W,handleAutoEditComplete:$}=(0,f.useAutoEdit)(),{createNavigationCallback:K,resetNavigation:X}=(0,y.useErrorNavigation)(),[J,Y]=(0,t.useState)(null),[Q,Z]=(0,t.useState)(null),[ee,ae]=(0,t.useState)(null);usePreventUnload(I);const re=(0,t.useCallback)(()=>{I?V():_()},[I,V,_]);(0,t.useEffect)(()=>{if(e&&r)return r(()=>re()),()=>r(null)},[e,r,re]);const te=(0,t.useCallback)((e,a,r)=>{const t=O(e,a,r);t&&W(t)},[O,W]),handleSaveClick=async()=>{try{ae(null),X();const e=await M();return(0,u.trackVariablesManagerEvent)({action:"saveChanges"}),e}catch(e){const a=(0,d.mapServerError)(e),r=a?.action?.data?.duplicatedIds;return a&&"label"===a.field&&(r&&a.action&&(a.action.callback=K(r,W,()=>{H(!1)})),ae(a),H(!0),X()),{success:!1,error:a}}finally{G(!1)}},ne=(0,t.useCallback)(e=>{F(e),Y(null)},[F]),oe=(0,t.useCallback)(e=>{B(e);const a=A[e];a&&(0,u.trackVariableSyncToV3)({variableLabel:a.label,action:"unsync"})},[B,A]),ie=(0,t.useCallback)(e=>{D(e);const a=A[e];a&&(0,u.trackVariableSyncToV3)({variableLabel:a.label,action:"sync"})},[D,A]),se=(0,t.useCallback)(e=>{w?oe(e):Z(e)},[w,oe]),le=(0,t.useCallback)(e=>{const a=A[e];if(!a)return[];return[...(0,b.getMenuActionsForVariable)(a.type,{variable:a,variableId:e,handlers:{onStartSync:ie,onStopSync:se}}),{name:(0,p.__)("Duplicate","elementor"),icon:l.CopyIcon,color:"text.primary",onClick:e=>{const r=U(e);W(r);const t=(0,b.getVariableType)(a.type);(0,u.trackVariablesManagerEvent)({action:"duplicate",varType:t?.variableType})}},{name:(0,p.__)("Delete","elementor"),icon:l.TrashIcon,color:"error.main",onClick:e=>{const a=A[e];if(a){Y({id:e,label:a.label});const r=(0,b.getVariableType)(a.type);(0,u.trackVariablesManagerEvent)({action:"delete",varType:r?.variableType})}}}]},[A,ie,se,U,W]),ce=Object.keys(A).length>0,pe=e?{flex:1,minWidth:0,px:0,py:0,display:"flex",alignItems:"center",alignSelf:"stretch"}:{display:"flex",flex:1},ue=t.createElement(i.SearchField,{placeholder:(0,p.__)("Search","elementor"),value:R,onSearch:j,sx:pe}),de=t.createElement(t.Fragment,null,ce&&t.createElement(E.VariablesManagerTable,{menuActions:le,variables:A,onChange:z,autoEditVariableId:q,onAutoEditComplete:$,onFieldError:H}),!ce&&R&&t.createElement(g.NoSearchResults,{searchValue:R,onClear:()=>j(""),icon:t.createElement(l.ColorFilterIcon,{fontSize:"large"})}),!ce&&!R&&t.createElement(v.EmptyState,{title:(0,p.__)("Create your first variable","elementor"),message:(0,p.__)("Variables are saved attributes that you can apply anywhere on your site.","elementor"),icon:t.createElement(l.ColorFilterIcon,{fontSize:"large"}),onAdd:P.open})),be=t.createElement(o.PanelFooter,null,t.createElement(c.Infotip,{placement:"right",open:!!ee,content:ee?t.createElement(c.Alert,{severity:ee.severity??"error",action:ee.action?.label?t.createElement(c.AlertAction,{onClick:ee.action.callback},ee.action.label):void 0,onClose:ee.action?.label?void 0:()=>{ae(null),H(!1)},icon:ee.IconComponent?t.createElement(ee.IconComponent,null):t.createElement(l.AlertTriangleFilledIcon,null)},t.createElement(c.AlertTitle,null,ee.message),ee.action?.message):null,arrow:!1,slotProps:{popper:{modifiers:[{name:"offset",options:{offset:[-10,10]}}]}}},t.createElement(c.Button,{fullWidth:!0,size:"small",color:"global",variant:"contained",disabled:L||!I||N,onClick:handleSaveClick,loading:N},(0,p.__)("Save changes","elementor")))),me=t.createElement(t.Fragment,null,J&&t.createElement(m.DeleteConfirmationDialog,{open:!0,label:J.label,onConfirm:()=>ne(J.id),closeDialog:()=>Y(null)}),Q&&t.createElement(StopSyncConfirmationDialog,{open:!0,onClose:()=>Z(null),onConfirm:()=>{oe(Q),Z(null)}}),S&&t.createElement(i.SaveChangesDialog,null,t.createElement(i.SaveChangesDialog.Title,{onClose:T},(0,p.__)("You have unsaved changes","elementor")),t.createElement(i.SaveChangesDialog.Content,null,t.createElement(i.SaveChangesDialog.ContentText,null,(0,p.__)("To avoid losing your updates, save your changes before leaving.","elementor"))),t.createElement(i.SaveChangesDialog.Actions,{actions:{discard:{label:(0,p.__)("Discard","elementor"),action:()=>{T(),_()}},confirm:{label:(0,p.__)("Save","elementor"),action:async()=>{const e=await handleSaveClick();T(),e?.success&&_()}}}}))),ve=e?t.createElement(c.Stack,{direction:"column",sx:{height:"100%",width:"100%",flex:1,minHeight:0,overflow:"hidden"}},t.createElement(c.Stack,{direction:"row",alignItems:"center",spacing:1,width:"100%",sx:{flexShrink:0,px:2,pb:1}},ue,t.createElement(c.Box,{sx:{display:"flex",flexShrink:0,alignItems:"center"}},t.createElement(h.VariableManagerCreateMenu,{outlinedTrigger:!0,onCreate:te,variables:A,menuState:P}))),t.createElement(c.Divider,{sx:{width:"100%"}}),t.createElement(o.PanelBody,{sx:{display:"flex",flexDirection:"column",flex:1,minHeight:0}},de),be):t.createElement(o.Panel,null,t.createElement(o.PanelHeader,{sx:{height:"unset"}},t.createElement(c.Stack,{width:"100%",direction:"column",alignItems:"center"},t.createElement(c.Stack,{p:1,pl:2,width:"100%",direction:"row",alignItems:"center"},t.createElement(c.Stack,{width:"100%",direction:"row",gap:1},t.createElement(o.PanelHeaderTitle,{sx:{display:"flex",alignItems:"center",gap:.5}},t.createElement(l.ColorFilterIcon,{fontSize:"inherit"}),(0,p.__)("Variables Manager","elementor"))),t.createElement(c.Stack,{direction:"row",gap:.5,alignItems:"center"},t.createElement(h.VariableManagerCreateMenu,{onCreate:te,variables:A,menuState:P}),t.createElement(c.CloseButton,{"aria-label":"Close",slotProps:{icon:{fontSize:h.SIZE}},onClick:()=>{re()}}))),t.createElement(c.Stack,{width:"100%",direction:"row",gap:1},ue),t.createElement(c.Divider,{sx:{width:"100%"}}))),t.createElement(o.PanelBody,{sx:{display:"flex",flexDirection:"column",height:"100%"}},de),be),ge=t.createElement(t.Fragment,null,ve,me);return e?ge:t.createElement(i.ThemeProvider,null,ge)}const usePreventUnload=e=>{(0,t.useEffect)(()=>{const handleBeforeUnload=a=>{e&&a.preventDefault()};return window.addEventListener("beforeunload",handleBeforeUnload),()=>{window.removeEventListener("beforeunload",handleBeforeUnload)}},[e])},StopSyncConfirmationDialog=({open:e,onClose:a,onConfirm:r})=>{const[,o]=(0,n.useSuppressedMessage)(x);return t.createElement(i.ConfirmationDialog,{open:e,onClose:a},t.createElement(i.ConfirmationDialog.Title,{icon:l.ColorFilterIcon,iconColor:"primary"},(0,p.__)("Stop syncing variable color","elementor")),t.createElement(i.ConfirmationDialog.Content,null,t.createElement(i.ConfirmationDialog.ContentText,null,(0,p.__)("This will disconnect the variable color from Global Colors. Existing uses on your site will automatically switch to a default color.","elementor"))),t.createElement(i.ConfirmationDialog.Actions,{onClose:a,onConfirm:r,cancelLabel:(0,p.__)("Cancel","elementor"),confirmLabel:(0,p.__)("Got it","elementor"),color:"primary",onSuppressMessage:o,suppressLabel:(0,p.__)("Don't show again","elementor")}))}},"./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-table.tsx":function(e,a,r){r.r(a),r.d(a,{VariablesManagerTable:function(){return VariablesManagerTable}});var t=r("react"),n=r("@elementor/ui"),o=r("@wordpress/i18n"),i=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),s=r("./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-cell.tsx"),l=r("./packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-row.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const VariablesManagerTable=({menuActions:e,variables:a,onChange:r,autoEditVariableId:c,onAutoEditComplete:p,onFieldError:u})=>{const d=(0,t.useRef)(null),b=(0,t.useRef)(new Map);(0,t.useEffect)(()=>{if(c&&d.current){const e=b.current.get(c);e&&setTimeout(()=>{e.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"})},100)}},[c]);const handleRowRef=e=>a=>{a?b.current.set(e,a):b.current.delete(e)},m=Object.keys(a).sort(function sortVariablesOrder(e){return(a,r)=>(e[a]?.order??Number.MAX_SAFE_INTEGER)-(e[r]?.order??Number.MAX_SAFE_INTEGER)}(a)),v=m.map(e=>{const r=a[e],t=(0,i.getVariableType)(r.type);return t?{id:e,type:r.type,name:r.label,value:r.value,...t}:null}).filter(Boolean),g={minWidth:250,tableLayout:"fixed"};return t.createElement(n.TableContainer,{ref:d,sx:{overflow:"initial"}},t.createElement(n.Table,{sx:g,"aria-label":"Variables manager list with drag and drop reordering",stickyHeader:!0},t.createElement(n.TableHead,null,t.createElement(n.TableRow,null,t.createElement(s.VariableTableCell,{isHeader:!0,noPadding:!0,width:10,maxWidth:10}),t.createElement(s.VariableTableCell,{isHeader:!0},(0,o.__)("Name","elementor")),t.createElement(s.VariableTableCell,{isHeader:!0},(0,o.__)("Value","elementor")),t.createElement(s.VariableTableCell,{isHeader:!0,noPadding:!0,width:16,maxWidth:16}))),t.createElement(n.TableBody,null,t.createElement(n.UnstableSortableProvider,{value:m,onChange:e=>{const t={...a};e.forEach((e,a)=>{const r=t[e];r&&(t[e]=Object.assign({},r,{order:a+1}))}),r(t)},variant:"static",restrictAxis:!0,dragOverlay:({children:e,...a})=>t.createElement(n.Table,_extends({sx:g},a),t.createElement(n.TableBody,null,e))},v.map(o=>t.createElement(n.UnstableSortableItem,{key:o.id,id:o.id,render:n=>t.createElement(l.VariableRow,_extends({},n,{row:o,variables:a,handleOnChange:r,autoEditVariableId:c,onAutoEditComplete:p,onFieldError:u,menuActions:e,handleRowRef:handleRowRef}))}))))))}},"./packages/packages/core/editor-variables/src/components/variables-repeater-item-slot.tsx":function(e,a,r){r.r(a),r.d(a,{BackgroundRepeaterColorIndicator:function(){return BackgroundRepeaterColorIndicator},BackgroundRepeaterLabel:function(){return BackgroundRepeaterLabel},BoxShadowRepeaterColorIndicator:function(){return BoxShadowRepeaterColorIndicator},BoxShadowRepeaterLabel:function(){return BoxShadowRepeaterLabel},FilterDropShadowIconIndicator:function(){return FilterDropShadowIconIndicator},FilterDropShadowRepeaterLabel:function(){return FilterDropShadowRepeaterLabel},FilterSingleSizeRepeaterLabel:function(){return FilterSingleSizeRepeaterLabel},TransformRepeaterLabel:function(){return TransformRepeaterLabel},TransitionsSizeVariableLabel:function(){return TransitionsSizeVariableLabel}});var t=r("react"),n=r("@elementor/editor-props"),o=r("@elementor/ui"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),l=r("./packages/packages/core/editor-variables/src/utils/size-value.ts"),c=r("./packages/packages/core/editor-variables/src/components/ui/color-indicator.tsx");const useColorVariable=e=>{const a=e?.value?.color?.value;return(0,s.getVariable)(a||"")},BackgroundRepeaterColorIndicator=({value:e})=>{const a=useColorVariable(e);return t.createElement(c.ColorIndicator,{component:"span",size:"inherit",value:a?.value})},BackgroundRepeaterLabel=({value:e})=>{const a=useColorVariable(e);return t.createElement(o.Box,{component:"span"},a?.label)},BoxShadowRepeaterColorIndicator=({value:e})=>{const a=useColorVariable(e);return t.createElement(c.ColorIndicator,{component:"span",size:"inherit",value:a?.value})},FilterDropShadowIconIndicator=({value:e})=>{const{args:a}=n.cssFilterFunctionPropUtil.extract(e)||{},{color:r}=n.dropShadowFilterPropTypeUtil.extract(a)||{},o=(0,s.getVariable)(r?.value||"");return t.createElement(c.ColorIndicator,{component:"span",size:"inherit",value:o?.value})},FilterSingleSizeRepeaterLabel=({value:e})=>{const a=n.cssFilterFunctionPropUtil.extract(e);if(n.dropShadowFilterPropTypeUtil.isValid(a?.args))return null;const r=a?.args,i=a?.func?.value??"",s=(0,l.sizeValue)(r?.value?.size);return t.createElement(t.Fragment,null,t.createElement(o.Box,{component:"span",style:{textTransform:"capitalize"}},`${i}: `),t.createElement(o.Box,{component:"span"},s))},FilterDropShadowRepeaterLabel=({value:e})=>{const{args:a}=n.cssFilterFunctionPropUtil.extract(e)||{},{xAxis:r,yAxis:s,blur:c}=n.dropShadowFilterPropTypeUtil.extract(a)||{},p=[];for(const e of[r,s,c]){const a=(0,l.sizeValue)(e);a&&p.push(a)}return t.createElement(o.Box,{component:"span"},(0,i.__)("Drop shadow:","elementor")," ",p.join(" "))},BoxShadowRepeaterLabel=({value:e})=>{const{position:a,hOffset:r,vOffset:i,blur:s,spread:c}=n.shadowPropTypeUtil.extract(e)||{},p=[];for(const e of[r,i,s,c]){const a=(0,l.sizeValue)(e);a&&p.push(a)}const u=a?.value||"outset";return t.createElement(o.Box,{component:"span",style:{textTransform:"capitalize"}},u,": ",p.join(" "))},TransformRepeaterLabel=({value:e})=>{const a=[];if(n.moveTransformPropTypeUtil.isValid(e)){a.push((0,i.__)("Move:","elementor"));const{x:r,y:t,z:o}=n.moveTransformPropTypeUtil.extract(e)||{};for(const e of[r,t,o]){const r=(0,l.sizeValue)(e);r&&a.push(r)}}return t.createElement(o.Box,{component:"span"},a.join(" "))},TransitionsSizeVariableLabel=({value:e})=>{let a="";const r=e?.value?.size?.value||"",i=(0,s.getVariable)(r);if(i&&n.selectionSizePropTypeUtil.isValid(e)){const r=e.value?.selection?.value?.key?.value;r&&(a+=`${r}: `),a+=i?.value}return t.createElement(o.Box,{component:"span"},a)}},"./packages/packages/core/editor-variables/src/components/variables-selection.tsx":function(e,a,r){r.r(a),r.d(a,{VariablesSelection:function(){return VariablesSelection}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-ui"),i=r("@elementor/icons"),s=r("@elementor/ui"),l=r("@wordpress/i18n"),c=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),p=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),u=r("./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts"),d=r("./packages/packages/core/editor-variables/src/utils/tracking.ts"),b=r("./packages/packages/core/editor-variables/src/components/ui/empty-state.tsx"),m=r("./packages/packages/core/editor-variables/src/components/ui/menu-item-content.tsx"),v=r("./packages/packages/core/editor-variables/src/components/ui/no-search-results.tsx"),g=r("./packages/packages/core/editor-variables/src/components/ui/styled-menu-list.tsx");function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var r=arguments[a];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},_extends.apply(null,arguments)}const f="tiny",y=(0,l.__)("Create variable","elementor"),k=(0,l.__)("Variables Manager","elementor"),getProUpgradeUrl=e=>`https://go.elementor.com/renew-license-panel-${e}-variable`,VariablesSelection=({closePopover:e,onAdd:a,onEdit:r,onSettings:h,disabled:E=!1})=>{const{icon:_,startIcon:x,variableType:V,propTypeUtil:C,emptyState:T}=(0,c.useVariableType)(),{value:S,setValue:w,path:P}=(0,u.useVariableBoundProp)(),[A,I]=(0,t.useState)(""),{list:R,hasMatches:L,isSourceNotEmpty:z,hasNoCompatibleVariables:O}=(0,p.useFilteredVariables)(A,C.key),onAddAndTrack=()=>{a?.(),(0,d.trackVariableEvent)({varType:V,controlPath:P.join("."),action:"add"})},U=[];if(a&&U.push(t.createElement(s.Tooltip,{key:"add",placement:"top",title:y},t.createElement("span",null,t.createElement(s.IconButton,{id:"add-variable-button",size:f,onClick:onAddAndTrack,"aria-label":y,disabled:E},t.createElement(i.PlusIcon,{fontSize:f}))))),h){const handleOpenManager=()=>{h(),(0,d.trackVariablesManagerEvent)({action:"openManager",varType:V,controlPath:P.join(".")})};U.push(t.createElement(s.Tooltip,{key:"settings",placement:"top",title:k},t.createElement(s.IconButton,{id:"variables-manager-button",size:f,onClick:handleOpenManager,"aria-label":k},t.createElement(i.SettingsIcon,{fontSize:f}))))}const F=x||(()=>t.createElement(_,{fontSize:f})),D=R.map(({value:e,label:a,key:n})=>({type:"item",value:n,label:a,icon:t.createElement(F,{value:e}),secondaryText:e,onEdit:r?()=>r?.(n):void 0}));return(0,t.useEffect)(()=>{E&&(0,n.trackViewPromotion)({target_name:"variables_popover",target_location:"widget_panel",location_l1:"variables_list"})},[E]),t.createElement(o.SectionPopoverBody,null,t.createElement(o.PopoverHeader,{title:(0,l.__)("Variables","elementor"),icon:t.createElement(i.ColorFilterIcon,{fontSize:f}),onClose:e,actions:U}),z&&t.createElement(o.SearchField,{value:A,onSearch:e=>{I(e)},placeholder:(0,l.__)("Search","elementor")}),t.createElement(s.Divider,null),z&&L&&t.createElement(t.Fragment,null,t.createElement(o.PopoverMenuList,{items:D,onSelect:E?()=>{}:a=>{w(a),(0,d.trackVariableEvent)({varType:V,controlPath:P.join("."),action:"connect"}),e()},onClose:()=>{},selectedValue:S,"data-testid":`${V}-variables-list`,menuListTemplate:e=>t.createElement(g.VariablesStyledMenuList,_extends({},e,{disabled:E})),menuItemContentTemplate:e=>t.createElement(m.MenuItemContent,{item:e,disabled:E})}),E&&t.createElement(o.PromotionAlert,{message:(0,l.sprintf)((0,l.__)("Upgrade to continue creating and editing %s variables.","elementor"),V),upgradeUrl:getProUpgradeUrl(V),onCtaClick:()=>(0,n.trackUpgradePromotionClick)({target_name:"variables_popover",location_l1:"variables_list"})})),!L&&z&&t.createElement(v.NoSearchResults,{searchValue:A,onClear:()=>{I("")},icon:t.createElement(_,{fontSize:"large"})}),E&&!z&&t.createElement(b.EmptyState,{title:(0,l.sprintf)((0,l.__)("No %s variables yet","elementor"),V),message:(0,l.sprintf)((0,l.__)("Upgrade to create %s variables and maintain consistent element sizing.","elementor"),V),icon:t.createElement(_,{fontSize:"large"})},T),!z&&!O&&!E&&t.createElement(b.EmptyState,{title:(0,l.sprintf)((0,l.__)("Create your first %s variable","elementor"),V),message:(0,l.__)("Variables are saved attributes that you can apply anywhere on your site.","elementor"),icon:t.createElement(_,{fontSize:"large"}),onAdd:a}),O&&!E&&t.createElement(b.EmptyState,{title:(0,l.__)("No compatible variables","elementor"),message:(0,l.__)("Looks like none of your variables work with this control. Create a new variable to use it here.","elementor"),icon:t.createElement(_,{fontSize:"large"}),onAdd:a}))}},"./packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx":function(e,a,r){r.r(a),r.d(a,{PopoverContentRefContextProvider:function(){return PopoverContentRefContextProvider},usePopoverContentRef:function(){return usePopoverContentRef}});var t=r("react"),n=r("@elementor/ui");const o=(0,t.createContext)(null),PopoverContentRefContextProvider=({children:e})=>{const[a,r]=(0,t.useState)(null);return t.createElement(o.Provider,{value:a},t.createElement(n.Box,{ref:r},e))},usePopoverContentRef=()=>(0,t.useContext)(o)},"./packages/packages/core/editor-variables/src/context/variable-type-context.tsx":function(e,a,r){r.r(a),r.d(a,{VariableTypeProvider:function(){return VariableTypeProvider},useVariableType:function(){return useVariableType}});var t=r("react"),n=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const o=(0,t.createContext)(null);function VariableTypeProvider({children:e,propTypeKey:a}){return t.createElement(o.Provider,{value:a},e)}function useVariableType(){const e=(0,t.useContext)(o);if(null===e)throw new Error("useVariableType must be used within a VariableTypeProvider");return(0,n.getVariableType)(e)}},"./packages/packages/core/editor-variables/src/controls/variable-control.tsx":function(e,a,r){r.r(a),r.d(a,{VariableControl:function(){return VariableControl}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("./packages/packages/core/editor-variables/src/components/ui/variable/assigned-variable.tsx"),i=r("./packages/packages/core/editor-variables/src/components/ui/variable/deleted-variable.tsx"),s=r("./packages/packages/core/editor-variables/src/components/ui/variable/mismatch-variable.tsx"),l=r("./packages/packages/core/editor-variables/src/components/ui/variable/missing-variable.tsx"),c=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),p=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const VariableControl=()=>{const e=(0,n.useBoundProp)(),a=e.value??e.placeholder,r=(0,c.useVariable)(a?.value);if(!r)return t.createElement(l.MissingVariable,null);const{$$type:u}=a;if(r?.deleted)return t.createElement(i.DeletedVariable,{variable:r,propTypeKey:u});const{isCompatible:d}=(0,p.getVariableType)(r.type);return d&&!d(e?.propType,r)?t.createElement(s.MismatchVariable,{variable:r}):t.createElement(o.AssignedVariable,{variable:r,propTypeKey:u})}},"./packages/packages/core/editor-variables/src/create-style-variables-repository.ts":function(e,a,r){r.r(a),r.d(a,{createStyleVariablesRepository:function(){return createStyleVariablesRepository}});var t=r("@elementor/editor-v1-adapters"),n=r("./packages/packages/core/editor-variables/src/prop-types/font-variable-prop-type.ts");const createStyleVariablesRepository=()=>{const e={};let a;const shouldUpdate=(a,r)=>!(a in e)||(e[a].label!==r.label||(e[a].value!==r.value||(!(e[a]?.deleted||!r?.deleted)||!(!e[a]?.deleted||r?.deleted)))),fontEnqueue=e=>{if(e)try{(0,t.enqueueFont)(e)}catch{}};return{subscribe:e=>(a=e,()=>{a=()=>{}}),update:r=>{(a=>{let r=!1;for(const[t,o]of Object.entries(a))shouldUpdate(t,o)&&(e[t]=o,o.type===n.fontVariablePropTypeUtil.key&&fontEnqueue(o.value),r=!0);return r})(r)&&"function"==typeof a&&a({...e})}}}},"./packages/packages/core/editor-variables/src/hooks/use-initial-value.ts":function(e,a,r){r.r(a),r.d(a,{useInitialValue:function(){return useInitialValue}});var t=r("@elementor/editor-controls"),n=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),o=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts");const useInitialValue=()=>{const{value:e}=(0,t.useBoundProp)(),a=(0,n.hasVariableType)(e?.$$type)&&Boolean(e?.value),r=(0,o.useVariable)(a?e.value:"");return a?r?r.value:"":e?.value??""}},"./packages/packages/core/editor-variables/src/hooks/use-permissions.ts":function(e,a,r){r.r(a),r.d(a,{usePermissions:function(){return usePermissions}});var t=r("@elementor/editor-current-user");const usePermissions=()=>{const{canUser:e,isAdmin:a}=(0,t.useCurrentUserCapabilities)();return{canAssign:()=>e("edit_posts"),canUnlink:()=>e("edit_posts"),canAdd:()=>a,canDelete:()=>a,canEdit:()=>a,canRestore:()=>a,canManageSettings:()=>a}}},"./packages/packages/core/editor-variables/src/hooks/use-prop-variable-action.tsx":function(e,a,r){r.r(a),r.d(a,{usePropVariableAction:function(){return usePropVariableAction}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/icons"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/components/variable-selection-popover.tsx"),l=r("./packages/packages/core/editor-variables/src/utils/tracking.ts"),c=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const usePropVariableAction=()=>{const{propType:e,path:a}=(0,n.useBoundProp)(),r=resolveVariableFromPropType(e);return{visible:Boolean(r),icon:o.ColorFilterIcon,title:(0,i.__)("Variables","elementor"),content:({close:e})=>r?(trackOpenVariablePopover(a,r.variableType),t.createElement(s.VariableSelectionPopover,{closePopover:e,propTypeKey:r.propTypeUtil.key})):null}},resolveVariableFromPropType=e=>{if("union"===e.kind)for(const a of Object.keys(e.prop_types)){const e=(0,c.getVariableType)(a);if(e)return e}},trackOpenVariablePopover=(e,a)=>{(0,l.trackVariableEvent)({varType:a,controlPath:e.join("."),action:"open"})}},"./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts":function(e,a,r){r.r(a),r.d(a,{createVariable:function(){return createVariable},deleteVariable:function(){return deleteVariable},getVariable:function(){return getVariable},getVariables:function(){return getVariables},hasVariable:function(){return hasVariable},restoreVariable:function(){return restoreVariable},updateVariable:function(){return updateVariable},useFilteredVariables:function(){return useFilteredVariables},useVariable:function(){return useVariable}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx"),i=r("./packages/packages/core/editor-variables/src/service.ts"),s=r("./packages/packages/core/editor-variables/src/utils/filter-by-search.ts"),l=r("./packages/packages/core/editor-variables/src/utils/variables-to-list.ts"),c=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const getVariables=(e=!0)=>{const a=i.service.variables();return e?a:Object.fromEntries(Object.entries(a).filter(([,e])=>!e.deleted))},hasVariable=e=>void 0!==getVariables()[e],useVariable=e=>getVariable(e);function getVariable(e){const a=getVariables();return a?.[e]?{...a[e],key:e}:null}const useFilteredVariables=(e,a)=>{const r=usePropVariables(a),t=useVariableSelectionFilter(r),n=(0,s.filterBySearch)(t,e);return{list:n.sort((e,a)=>(e.order??Number.MAX_SAFE_INTEGER)-(a.order??Number.MAX_SAFE_INTEGER)),hasMatches:n.length>0,isSourceNotEmpty:t.length>0,hasNoCompatibleVariables:r.length>0&&0===t.length}},useVariableSelectionFilter=e=>{const{selectionFilter:a}=(0,o.useVariableType)(),{propType:r}=(0,n.useBoundProp)();return a?a(e,r):e},usePropVariables=e=>(0,t.useMemo)(()=>normalizeVariables(e),[e]),normalizeVariables=e=>{const a=getVariables(!1),r=(e=>{const a=[],r=(0,c.getVariableTypes)(),t=(0,c.getVariableType)(e);return Object.entries(r).forEach(([e,r])=>{t.variableType===r.variableType&&a.push(e)}),a})(e);return(0,l.variablesToList)(a).filter(e=>r.includes(e.type)).map(l.toNormalizedVariable)},extractId=({id:e})=>e,createVariable=e=>i.service.create(e).then(extractId),updateVariable=(e,{value:a,label:r,type:t})=>i.service.update(e,{value:a,label:r,type:t}).then(extractId),deleteVariable=e=>i.service.delete(e).then(extractId),restoreVariable=(e,a,r,t)=>i.service.restore(e,a,r,t).then(extractId)},"./packages/packages/core/editor-variables/src/hooks/use-quota-permissions.ts":function(e,a,r){r.r(a),r.d(a,{useQuotaPermissions:function(){return useQuotaPermissions}});const useQuotaPermissions=e=>{const a={...window.ElementorVariablesQuotaConfig??{},...window.ElementorVariablesQuotaConfigExtended??{}},r=void 0===a[e]&&window.elementorPro,t=a[e]||0,n=r||t>0;return{canAdd:()=>n,canEdit:()=>n}}},"./packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts":function(e,a,r){r.r(a),r.d(a,{resolveBoundPropAndSetValue:function(){return resolveBoundPropAndSetValue},useVariableBoundProp:function(){return useVariableBoundProp}});var t=r("@elementor/editor-controls"),n=r("@elementor/editor-props"),o=r("./packages/packages/core/editor-variables/src/context/variable-type-context.tsx");const useVariableBoundProp=()=>{const{propTypeUtil:e}=(0,o.useVariableType)(),a=(0,t.useBoundProp)(e);return{...a,setVariableValue:e=>resolveBoundPropAndSetValue(e,a),variableId:a.value??a.placeholder}},resolveBoundPropAndSetValue=(e,a)=>{const r=unwrapValue(a.value),t=unwrapValue(a.placeholder),n=unwrapValue(e);return r||t!==n?a.setValue(e):a.setValue(null)},unwrapValue=e=>(0,n.isTransformable)(e)?e.value:e},"./packages/packages/core/editor-variables/src/init.ts":function(e,a,r){r.r(a),r.d(a,{init:function(){return init}});var t=r("@elementor/editor"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-mcp"),i=r("@elementor/editor-panels"),s=r("@elementor/editor-props"),l=r("@elementor/editor-v1-adapters"),c=r("@elementor/menus"),p=r("./packages/packages/core/editor-variables/src/components/global-styles-import-listener.tsx"),u=r("./packages/packages/core/editor-variables/src/components/open-panel-from-event.tsx"),d=r("./packages/packages/core/editor-variables/src/components/open-panel-from-url.tsx"),b=r("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx"),m=r("./packages/packages/core/editor-variables/src/controls/variable-control.tsx"),v=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variable-action.tsx"),g=r("./packages/packages/core/editor-variables/src/mcp/index.ts"),f=r("./packages/packages/core/editor-variables/src/register-variable-types.tsx"),y=r("./packages/packages/core/editor-variables/src/renderers/style-variables-renderer.tsx"),k=r("./packages/packages/core/editor-variables/src/repeater-injections.ts"),h=r("./packages/packages/core/editor-variables/src/service.ts"),E=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");const{registerPopoverAction:_}=c.controlActionsMenu;function init(){(0,f.registerVariableTypes)(),(0,k.registerRepeaterInjections)(),(0,n.registerControlReplacement)({component:m.VariableControl,condition:({value:e,placeholder:a})=>!!hasVariableAssigned(e)||!e&&hasVariableAssigned(a)}),_({id:"variables",priority:40,useProps:v.usePropVariableAction}),h.service.init().then(()=>{const e=(0,o.getMCPByDomain)("variables",{instructions:"Everything related to V4 ( Atomic ) variables.\n# Global variables\n- Create/update/delete global variables\n- Get list of global variables\n- Get details of a global variable\n"});(0,g.initMcp)(e,(0,o.getMCPByDomain)("canvas"))}),(0,t.injectIntoTop)({id:"canvas-style-variables-render",component:y.StyleVariablesRenderer}),(0,t.injectIntoLogic)({id:"variables-import-listener",component:p.GlobalStylesImportListener}),(0,l.isExperimentActive)("e_editor_design_system_panel")||((0,t.injectIntoLogic)({id:"variables-open-panel-from-url",component:d.OpenPanelFromUrl}),(0,t.injectIntoLogic)({id:"variables-open-panel-from-event",component:u.OpenPanelFromEvent}),(0,i.__registerPanel)(b.panel))}function hasVariableAssigned(e){return!!(0,s.isTransformable)(e)&&(0,E.hasVariableType)(e.$$type)}},"./packages/packages/core/editor-variables/src/mcp/index.ts":function(e,a,r){r.r(a),r.d(a,{initMcp:function(){return initMcp}});var t=r("./packages/packages/core/editor-variables/src/mcp/manage-variable-tool.ts"),n=r("./packages/packages/core/editor-variables/src/mcp/variables-resource.ts");function initMcp(e,a){(0,t.initManageVariableTool)(e),(0,n.initVariablesResource)(e,a)}},"./packages/packages/core/editor-variables/src/mcp/manage-variable-tool.ts":function(e,a,r){r.r(a),r.d(a,{initManageVariableTool:function(){return initManageVariableTool}});var t=r("@elementor/schema"),n=r("@elementor/utils"),o=r("./packages/packages/core/editor-variables/src/service.ts"),i=r("./packages/packages/core/editor-variables/src/utils/validations.ts"),s=r("./packages/packages/core/editor-variables/src/mcp/variable-tool-prompt.ts"),l=r("./packages/packages/core/editor-variables/src/mcp/variables-resource.ts");const c="global-color-variable",p="global-font-variable",u="global-size-variable",d="global-custom-size-variable",b=/^(auto|\d+(\.\d+)?(px|rem|em|vh|vw|%|ch|s|ms))$/i,m=/^(#[0-9a-f]{3,8}|rgba?\(|hsl)/i;function validateValueForType(e,a){return e===p&&b.test(a.trim())?`Font variable value must be a font family name (e.g. "Roboto"), not a size value like "${a}". Use "global-size-variable" or "global-custom-size-variable" for spacing/size values.`:e!==c||m.test(a.trim())?e!==u||b.test(a.trim())?null:`Size variable value should include a CSS unit (e.g. "16px") or be "auto", got "${a}".`:`Color variable value should be a CSS color (e.g. "#FF0000"), got "${a}".`}const initManageVariableTool=e=>{const{addTool:a,resource:r}=e;r("manage-global-variable-guide",s.MANAGE_VARIABLES_GUIDE_URI,{title:"Manage Global Variable Guide",description:"Detailed guide for using the manage-global-variable tool",mimeType:"text/plain"},async e=>({contents:[{uri:e.href,mimeType:"text/plain",text:(0,s.generateVariablesPrompt)()}]})),a({name:"manage-global-variable",description:"Manage V4 global variables (color, font, size). Read the guide resource before use.",schema:{action:t.z.enum(["create","update","delete"]).describe("Operation to perform"),id:t.z.string().optional().describe("Variable id — required for update/delete. Get from the global-variables resource."),type:t.z.string().optional().describe('Variable type — required for create. One of: "global-color-variable", "global-font-variable", "global-size-variable", "global-custom-size-variable" (size types require Elementor Pro). NEVER store px/rem values in a font variable.'),label:t.z.string().optional().describe("Variable label (lowercase, dash-separated) — required for create/update."),value:t.z.string().optional().describe('Plain CSS value — required for create/update. Color: hex/rgba/hsl. Font: family name only, never px/rem. Size: value with unit e.g. "16px", or "auto" (Pro). Do NOT pass JSON.')},outputSchema:{status:t.z.enum(["ok"]).describe("Operation status"),message:t.z.string().optional().describe("Error details if status is error")},modelPreferences:{intelligencePriority:.75,speedPriority:.75},requiredResources:[{uri:s.MANAGE_VARIABLES_GUIDE_URI,description:"Full guide for variable types, naming rules, and usage"},{uri:l.GLOBAL_VARIABLES_URI,description:"Current global variables — check before creating to avoid duplicates"}],isDestructive:!0,handler:async e=>{const a=function getServiceActions(e){return{create({type:a,label:r,value:t}){if(!a||!r||!t)throw new Error("Create requires type, label, and value");if((a===u||a===d)&&!(0,n.isProActive)())throw new Error("Creating size variables requires Elementor Pro.");const o=(0,i.validateLabel)(r);if(o)throw new Error(o);const s=validateValueForType(a,t);if(s)throw new Error(s);return e.create({type:a,label:r,value:t})},update({id:a,label:r,value:t}){if(!a||!r||!t)throw new Error("Update requires id, label, and value");const n=(0,i.validateLabel)(r);if(n)throw new Error(n);const o=e.variables()[a];if(o){const e=validateValueForType(o.type,t);if(e)throw new Error(e)}return e.update(a,{label:r,value:t})},delete({id:a}){if(!a)throw new Error("delete requires id");return e.delete(a)}}}(o.service)[e.action];if(a)return await a(e),{status:"ok"};throw new Error(`Unknown action ${e.action}`)}})}},"./packages/packages/core/editor-variables/src/mcp/variable-tool-prompt.ts":function(e,a,r){r.r(a),r.d(a,{MANAGE_VARIABLES_GUIDE_URI:function(){return o},generateVariablesPrompt:function(){return generateVariablesPrompt}});var t=r("@elementor/editor-mcp"),n=r("@elementor/utils");const o="elementor://variables/tools/manage-global-variable-guide",generateVariablesPrompt=()=>{const e=(0,t.toolPrompts)("manage-global-variable"),a=(0,n.isProActive)()?"- **global-size-variable** — A simple CSS length with a unit (Elementor Pro). Use this for fixed spacing, font sizes, or layout values. Example: `16px`, `1.5rem`, `2em`, `10vh`\n- **global-custom-size-variable** — Any CSS size expression that goes beyond a simple number + unit (Elementor Pro). Use this when the value is a CSS function, a keyword, or a combination of units that `global-size-variable` cannot represent. Example: `auto`, `clamp(1rem, 2vw, 2rem)`, `calc(100% - 32px)`, `min(50vw, 600px)`, `300ms`, `2ch`. When in doubt: if the value contains a function call or a keyword, use `global-custom-size-variable`.":"- ~~global-size-variable~~ — requires Elementor Pro (not available on this site)\n- ~~global-custom-size-variable~~ — requires Elementor Pro (not available on this site)";return e.description(`\n# Purpose\nCreate, update, or delete V4 global CSS variables. These are distinct from legacy v3 globals and map 1:1 to \`--css-var: VALUE\`.\n\n# Available Types\n- **global-color-variable** — CSS color value. Example: \`#FF0000\`, \`rgba(255,0,0,1)\`, \`hsl(0,100%,50%)\`\n- **global-font-variable** — Font family name ONLY — NOT a size or px value. Example: \`Roboto\`, \`Open Sans\`. NEVER pass px/rem here.\n${a}\n\n# Naming Rules\n- Labels must be **lowercase**, using only letters (a-z), numbers, digits (0-9), dashes (-), or underscores (_)\n- No spaces, no special characters\n- Example: "Headline Primary" → \`headline-primary\`\n- Labels must be unique — always check [elementor://global-variables] first\n\n# Value Rules\n- Provide a **plain CSS value** only — do NOT pass JSON, legacy-globals object structures, or variable references\n- Values are inserted as-is: \`--css-var: <value>\`\n- NEVER store a px/rem value inside a \`global-font-variable\` — use \`global-size-variable\` (Pro) instead\n\n# Operations\n- **create** — requires \`type\`, \`label\`, \`value\`. Label must be unique.\n- **update** — requires \`id\`, \`label\`, \`value\`. Get \`id\` from [elementor://global-variables]. When renaming: keep existing value. When changing value: keep exact existing label.\n- **delete** — requires \`id\`. DESTRUCTIVE — always confirm with user before executing.\n`),e.parameter("action",'"create", "update", or "delete".'),e.parameter("type","Variable type. Required for create. See Available Types above."),e.parameter("label","Variable name (lowercase, dash-separated). Required for create/update."),e.parameter("value","Plain CSS value matching the variable type. Required for create/update. Do NOT pass JSON."),e.parameter("id","Variable ID. Required for update/delete. Obtain from [elementor://global-variables]."),e.example('\nCreate a brand color:\n{ "action": "create", "type": "global-color-variable", "label": "brand-primary", "value": "#1A73E8" }\n\nCreate a heading font:\n{ "action": "create", "type": "global-font-variable", "label": "font-heading", "value": "Playfair Display" }\n\nCreate a simple spacing size:\n{ "action": "create", "type": "global-size-variable", "label": "spacing-md", "value": "16px" }\n\nCreate a fluid/responsive size using a CSS function (use global-custom-size-variable, NOT global-size-variable):\n{ "action": "create", "type": "global-custom-size-variable", "label": "spacing-fluid", "value": "clamp(1rem, 2vw, 2rem)" }\n\nCreate a size that is a keyword:\n{ "action": "create", "type": "global-custom-size-variable", "label": "width-auto", "value": "auto" }\n\nCreate a size using calc():\n{ "action": "create", "type": "global-custom-size-variable", "label": "sidebar-width", "value": "calc(100% - 32px)" }\n\nUpdate a variable\'s value (keep exact label):\n{ "action": "update", "id": "abc123", "label": "brand-primary", "value": "#0D47A1" }\n\nRename a variable (keep existing value):\n{ "action": "update", "id": "abc123", "label": "brand-secondary", "value": "#1A73E8" }\n\nDelete a variable:\n{ "action": "delete", "id": "abc123" }\n'),e.instruction("Always read [elementor://global-variables] before creating to check existing variables and avoid duplicate labels."),e.prompt()}},"./packages/packages/core/editor-variables/src/mcp/variables-resource.ts":function(e,a,r){r.r(a),r.d(a,{GLOBAL_VARIABLES_URI:function(){return i},initVariablesResource:function(){return initVariablesResource}});var t=r("@elementor/editor-v1-adapters"),n=r("./packages/packages/core/editor-variables/src/service.ts"),o=r("./packages/packages/core/editor-variables/src/storage.ts");const i="elementor://global-variables",initVariablesResource=(e,a)=>{[a,e].forEach(e=>{const{resource:a,sendResourceUpdated:r}=e,notifyGlobalVariablesUpdated=()=>{r({uri:i})};a("global-variables",i,{description:"Global variables available (v4)"},async()=>{const e=await(async()=>{const e={};return Object.entries(n.service.variables()).forEach(([a,r])=>{r.deleted||(e[a]={...r,version:"v4"})}),e})();return{contents:[{uri:i,mimeType:"application/json",text:JSON.stringify(e)}]}}),window.addEventListener(o.STORAGE_UPDATED_EVENT,notifyGlobalVariablesUpdated),(0,t.__privateListenTo)((0,t.commandEndEvent)("document/save/update"),notifyGlobalVariablesUpdated)})}},"./packages/packages/core/editor-variables/src/prop-types/color-variable-prop-type.ts":function(e,a,r){r.r(a),r.d(a,{colorVariablePropTypeUtil:function(){return o}});var t=r("@elementor/editor-props"),n=r("@elementor/schema");const o=(0,t.createPropUtils)("global-color-variable",n.z.string())},"./packages/packages/core/editor-variables/src/prop-types/custom-size-variable-prop-type.ts":function(e,a,r){r.r(a),r.d(a,{customSizeVariablePropTypeUtil:function(){return o}});var t=r("@elementor/editor-props"),n=r("@elementor/schema");const o=(0,t.createPropUtils)("global-custom-size-variable",n.z.string())},"./packages/packages/core/editor-variables/src/prop-types/font-variable-prop-type.ts":function(e,a,r){r.r(a),r.d(a,{fontVariablePropTypeUtil:function(){return o}});var t=r("@elementor/editor-props"),n=r("@elementor/schema");const o=(0,t.createPropUtils)("global-font-variable",n.z.string())},"./packages/packages/core/editor-variables/src/prop-types/index.ts":function(e,a,r){r.r(a),r.d(a,{colorVariablePropTypeUtil:function(){return t.colorVariablePropTypeUtil},customSizeVariablePropTypeUtil:function(){return n.customSizeVariablePropTypeUtil},fontVariablePropTypeUtil:function(){return o.fontVariablePropTypeUtil},sizeVariablePropTypeUtil:function(){return i.sizeVariablePropTypeUtil}});var t=r("./packages/packages/core/editor-variables/src/prop-types/color-variable-prop-type.ts"),n=r("./packages/packages/core/editor-variables/src/prop-types/custom-size-variable-prop-type.ts"),o=r("./packages/packages/core/editor-variables/src/prop-types/font-variable-prop-type.ts"),i=r("./packages/packages/core/editor-variables/src/prop-types/size-variable-prop-type.ts")},"./packages/packages/core/editor-variables/src/prop-types/size-variable-prop-type.ts":function(e,a,r){r.r(a),r.d(a,{sizeVariablePropTypeUtil:function(){return o}});var t=r("@elementor/editor-props"),n=r("@elementor/schema");const o=(0,t.createPropUtils)("global-size-variable",n.z.string())},"./packages/packages/core/editor-variables/src/register-variable-types.tsx":function(e,a,r){r.r(a),r.d(a,{registerVariableTypes:function(){return registerVariableTypes}});var t=r("react"),n=r("@elementor/editor-controls"),o=r("@elementor/editor-props"),i=r("@elementor/editor-ui"),s=r("@elementor/icons"),l=r("@wordpress/i18n"),c=r("./packages/packages/core/editor-variables/src/components/fields/color-field.tsx"),p=r("./packages/packages/core/editor-variables/src/components/fields/font-field.tsx"),u=r("./packages/packages/core/editor-variables/src/components/ui/color-indicator.tsx"),d=r("./packages/packages/core/editor-variables/src/prop-types/color-variable-prop-type.ts"),b=r("./packages/packages/core/editor-variables/src/prop-types/font-variable-prop-type.ts"),m=r("./packages/packages/core/editor-variables/src/prop-types/size-variable-prop-type.ts"),v=r("./packages/packages/core/editor-variables/src/transformers/empty-transformer.tsx"),g=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");function registerVariableTypes(){(0,g.registerVariableType)({key:d.colorVariablePropTypeUtil.key,valueField:c.ColorField,icon:s.BrushIcon,propTypeUtil:d.colorVariablePropTypeUtil,fallbackPropTypeUtil:o.colorPropTypeUtil,variableType:"color",startIcon:({value:e})=>t.createElement(u.ColorIndicator,{size:"inherit",component:"span",value:e}),defaultValue:"#ffffff",menuActionsFactory:({variable:e,variableId:a,handlers:r})=>{const t=[];return e.sync_to_v3?t.push({name:(0,l.__)("Stop syncing to Global Colors","elementor"),icon:s.RefreshOffIcon,color:"text.primary",onClick:()=>r.onStopSync(a)}):t.push({name:(0,l.__)("Sync to Global Colors","elementor"),icon:s.RefreshIcon,color:"text.primary",onClick:()=>r.onStartSync(a)}),t}}),(0,g.registerVariableType)({key:b.fontVariablePropTypeUtil.key,valueField:p.FontField,icon:s.TextIcon,propTypeUtil:b.fontVariablePropTypeUtil,fallbackPropTypeUtil:o.stringPropTypeUtil,variableType:"font",defaultValue:"Roboto"});const e={isActive:!1,icon:s.ExpandDiagonalIcon,propTypeUtil:m.sizeVariablePropTypeUtil,fallbackPropTypeUtil:o.sizePropTypeUtil,styleTransformer:v.EmptyTransformer,variableType:"size",selectionFilter:()=>[],emptyState:t.createElement(i.CtaButton,{size:"small",href:"https://go.elementor.com/go-pro-panel-size-variable/",onClick:()=>(0,n.trackUpgradePromotionClick)({target_name:"variables_popover",location_l1:"variables_list"})})};(0,g.registerVariableType)({...e,key:m.sizeVariablePropTypeUtil.key,defaultValue:"0px"}),(0,g.registerVariableType)({...e,key:"global-custom-size-variable"})}},"./packages/packages/core/editor-variables/src/renderers/style-variables-renderer.tsx":function(e,a,r){r.r(a),r.d(a,{StyleVariablesRenderer:function(){return StyleVariablesRenderer}});var t=r("react"),n=r("@elementor/editor-v1-adapters"),o=r("@elementor/ui"),i=r("./packages/packages/core/editor-variables/src/style-variables-repository.ts");const s=":root";function StyleVariablesRenderer(){const e=function usePortalContainer(){return(0,n.__privateUseListenTo)((0,n.commandEndEvent)("editor/documents/attach-preview"),()=>(0,n.getCanvasIframeDocument)()?.head)}(),a=function useStyleVariables(){const[e,a]=(0,t.useState)({});return(0,t.useEffect)(()=>{const e=i.styleVariablesRepository.subscribe(a);return()=>{e()}},[]),e}(),r=Object.keys(a).length>0;if(!e||!r)return null;const l=function convertToCssVariables(e){return Object.entries(e).map(([e,a])=>function cssVariableDeclaration(e,a){const r=a?.deleted?e:a.label,t=a.value;return`--${r}:${t};`}(e,a)).join("")}(a),c=`${s}{${l}}`;return t.createElement(o.Portal,{container:e},t.createElement("style",{"data-e-style-id":"e-variables",key:c},c))}},"./packages/packages/core/editor-variables/src/repeater-injections.ts":function(e,a,r){r.r(a),r.d(a,{registerRepeaterInjections:function(){return registerRepeaterInjections}});var t=r("@elementor/editor-controls"),n=r("@elementor/editor-props"),o=r("./packages/packages/core/editor-variables/src/components/variables-repeater-item-slot.tsx"),i=r("./packages/packages/core/editor-variables/src/prop-types/index.ts");function registerRepeaterInjections(){!function backgroundOverlayRepeaterInjections(){(0,t.injectIntoRepeaterItemIcon)({id:"background-color-variables-icon",component:o.BackgroundRepeaterColorIndicator,condition:({value:e})=>hasAssignedColorVariable(n.backgroundColorOverlayPropTypeUtil.extract(e)?.color)}),(0,t.injectIntoRepeaterItemLabel)({id:"background-color-variables-label",component:o.BackgroundRepeaterLabel,condition:({value:e})=>hasAssignedColorVariable(n.backgroundColorOverlayPropTypeUtil.extract(e)?.color)})}(),function boxShadowRepeaterInjections(){(0,t.injectIntoRepeaterItemIcon)({id:"box-shadow-color-variables-icon",component:o.BoxShadowRepeaterColorIndicator,condition:({value:e})=>{const{color:a}=n.shadowPropTypeUtil.extract(e)||{};return hasAssignedColorVariable(a)}}),(0,t.injectIntoRepeaterItemLabel)({id:"color-variables-box-shadow-label",component:o.BoxShadowRepeaterLabel,condition:({value:e})=>{const{hOffset:a,vOffset:r,blur:t,spread:o}=n.shadowPropTypeUtil.extract(e)||{};return hasAssignedSizeVariable(a)||hasAssignedSizeVariable(r)||hasAssignedSizeVariable(t)||hasAssignedSizeVariable(o)}})}(),function transitionsRepeaterInjections(){(0,t.injectIntoRepeaterItemLabel)({id:"transition-size-variables-label",component:o.TransitionsSizeVariableLabel,condition:({value:e})=>hasAssignedSizeVariable(n.selectionSizePropTypeUtil.extract(e)?.size)})}(),function transformRepeaterInjections(){(0,t.injectIntoRepeaterItemLabel)({id:"transform-size-variables-label",component:o.TransformRepeaterLabel,condition:({value:e})=>{if(n.moveTransformPropTypeUtil.isValid(e)){const{x:a,y:r,z:t}=n.moveTransformPropTypeUtil.extract(e)||{};return hasAssignedSizeVariable(a)||hasAssignedSizeVariable(r)||hasAssignedSizeVariable(t)}return!1}})}(),function filterRepeaterInjections(){(0,t.injectIntoRepeaterItemIcon)({id:"filters-color-variables-icon",component:o.FilterDropShadowIconIndicator,condition:({value:e})=>{if(!n.cssFilterFunctionPropUtil.isValid(e))return!1;const a=n.cssFilterFunctionPropUtil.extract(e)?.args;return!!n.dropShadowFilterPropTypeUtil.isValid(a)&&hasAssignedColorVariable(n.dropShadowFilterPropTypeUtil.extract(a)?.color)}}),(0,t.injectIntoRepeaterItemLabel)({id:"filters-drop-shadow-size-variables-label",component:o.FilterDropShadowRepeaterLabel,condition:({value:e})=>{if(!n.cssFilterFunctionPropUtil.isValid(e))return!1;const a=n.cssFilterFunctionPropUtil.extract(e)?.args;if(n.dropShadowFilterPropTypeUtil.isValid(a)){const{xAxis:e,yAxis:r,blur:t}=n.dropShadowFilterPropTypeUtil.extract(a)||{};return hasAssignedSizeVariable(e)||hasAssignedSizeVariable(r)||hasAssignedSizeVariable(t)}return!1}}),(0,t.injectIntoRepeaterItemLabel)({id:"filters-size-variables-label",component:o.FilterSingleSizeRepeaterLabel,condition:({value:e})=>{if(!n.cssFilterFunctionPropUtil.isValid(e))return!1;const a=n.cssFilterFunctionPropUtil.extract(e)?.args;return hasAssignedSizeVariable(a?.value?.size)}})}()}function hasAssignedSizeVariable(e){return!!i.sizeVariablePropTypeUtil.isValid(e)||!!i.customSizeVariablePropTypeUtil.isValid(e)}function hasAssignedColorVariable(e){return!!i.colorVariablePropTypeUtil.isValid(e)}},"./packages/packages/core/editor-variables/src/service.ts":function(e,a,r){r.r(a),r.d(a,{service:function(){return c}});var t=r("@wordpress/i18n"),n=r("./packages/packages/core/editor-variables/src/api.ts"),o=r("./packages/packages/core/editor-variables/src/batch-operations.ts"),i=r("./packages/packages/core/editor-variables/src/storage.ts"),s=r("./packages/packages/core/editor-variables/src/style-variables-repository.ts");const l=new i.Storage,c={variables:()=>l.load(),findIdByLabel(e){const a=Object.entries(this.variables()).find(([,a])=>a.label===e);if(!a)throw new Error(`Variable with label ${e} not found`);return a[0]},findVariableByLabel(e){return Object.values(this.variables()).find(a=>a.label===e)||null},getWatermark:()=>l.state.watermark,init:()=>c.load(),load:()=>n.apiClient.list().then(e=>{const{success:a,data:r}=e.data;if(!a)throw new Error("Unexpected response from server");return r}).then(e=>{const{variables:a,watermark:r}=e;return l.fill(a,r),s.styleVariablesRepository.update(a),a}),create:({type:e,label:a,value:r})=>n.apiClient.create(e,a,r).then(e=>{const{success:a,data:r}=e.data;if(!a){const e=r?.message||(0,t.__)("Unexpected response from server","elementor");throw new Error(e)}return r}).then(e=>{const{variable:a,watermark:r}=e;handleWatermark(i.OP_RW,r);const{id:t,...n}=a;return l.add(t,n),s.styleVariablesRepository.update({[t]:n}),{id:t,variable:n}}),update:(e,{label:a,value:r,type:o})=>n.apiClient.update(e,a,r,o).then(e=>{const{success:a,data:r}=e.data;if(!a){const e=r?.message||(0,t.__)("Unexpected response from server","elementor");throw new Error(e)}return r}).then(e=>{const{variable:a,watermark:r}=e;handleWatermark(i.OP_RW,r);const{id:t,...n}=a;return l.update(t,n),s.styleVariablesRepository.update({[t]:n}),{id:t,variable:n}}),delete:e=>n.apiClient.delete(e).then(e=>{const{success:a,data:r}=e.data;if(!a)throw new Error("Unexpected response from server");return r}).then(e=>{const{variable:a,watermark:r}=e;handleWatermark(i.OP_RW,r);const{id:t,...n}=a;return l.update(t,n),s.styleVariablesRepository.update({[t]:n}),{id:t,variable:n}}),restore:(e,a,r,t)=>n.apiClient.restore(e,a,r,t).then(e=>{const{success:a,data:r}=e.data;if(!a)throw new Error("Unexpected response from server");return r}).then(e=>{const{variable:a,watermark:r}=e;handleWatermark(i.OP_RW,r);const{id:t,...n}=a;return l.update(t,n),s.styleVariablesRepository.update({[t]:n}),{id:t,variable:n}}),batchSave:(e,a,r)=>{const t=(0,o.buildOperationsArray)(e,a,r),c={operations:t,watermark:l.state.watermark};return 0===t.length?Promise.resolve({success:!0,watermark:l.state.watermark,operations:0}):n.apiClient.batch(c).then(e=>{const{success:a,data:r}=e.data;if(!a)throw new Error("Unexpected response from server");return r}).then(e=>{const{results:a,watermark:r}=e;return handleWatermark(i.OP_RW,r),a&&a.forEach(e=>{const a=e.id;e.variable&&("create"===e.type?l.add(a,e.variable):l.update(a,e.variable),s.styleVariablesRepository.update({[a]:e.variable}))}),{success:!0,watermark:r,operations:t.length}})}},handleWatermark=(e,a)=>{l.watermarkDiff(e,a)&&setTimeout(()=>c.load(),500),l.watermark(a)}},"./packages/packages/core/editor-variables/src/storage.ts":function(e,a,r){r.r(a),r.d(a,{OP_RW:function(){return i},STORAGE_UPDATED_EVENT:function(){return o},Storage:function(){return Storage}});const t="elementor-global-variables",n="elementor-global-variables-watermark",o="variables:updated",i="RW";class Storage{notifyChange(){window.dispatchEvent(new Event(o))}constructor(){this.state={watermark:-1,variables:{}}}load(){return this.state.watermark=parseInt(localStorage.getItem(n)||"-1"),this.state.variables=JSON.parse(localStorage.getItem(t)||"{}"),this.state.variables}fill(e,a){this.state.variables={},e&&Object.keys(e).length&&(this.state.variables=e),this.state.watermark=a,localStorage.setItem(n,this.state.watermark.toString()),localStorage.setItem(t,JSON.stringify(this.state.variables)),this.notifyChange()}add(e,a){this.load(),this.state.variables[e]=a,localStorage.setItem(t,JSON.stringify(this.state.variables)),this.notifyChange()}update(e,a){this.load(),this.state.variables[e]=a,localStorage.setItem(t,JSON.stringify(this.state.variables)),this.notifyChange()}watermark(e){this.state.watermark=e,localStorage.setItem(n,this.state.watermark.toString())}watermarkDiff(e,a){const r=a-this.state.watermark;return i===e?1!==r:"RO"===e&&0!==r}}},"./packages/packages/core/editor-variables/src/style-variables-repository.ts":function(e,a,r){r.r(a),r.d(a,{styleVariablesRepository:function(){return t}});const t=(0,r("./packages/packages/core/editor-variables/src/create-style-variables-repository.ts").createStyleVariablesRepository)()},"./packages/packages/core/editor-variables/src/transformers/empty-transformer.tsx":function(e,a,r){r.r(a),r.d(a,{EmptyTransformer:function(){return n}});var t=r("@elementor/editor-canvas");const n=(0,t.createTransformer)(e=>null)},"./packages/packages/core/editor-variables/src/transformers/inheritance-transformer.tsx":function(e,a,r){r.r(a),r.d(a,{inheritanceTransformer:function(){return u}});var t=r("react"),n=r("@elementor/editor-canvas"),o=r("@elementor/ui"),i=r("@wordpress/i18n"),s=r("./packages/packages/core/editor-variables/src/components/ui/color-indicator.tsx"),l=r("./packages/packages/core/editor-variables/src/prop-types/color-variable-prop-type.ts"),c=r("./packages/packages/core/editor-variables/src/service.ts"),p=r("./packages/packages/core/editor-variables/src/transformers/utils/resolve-css-variable.ts");const u=(0,n.createTransformer)(e=>{const a=c.service.variables()[e];if(!a)return t.createElement("span",null,(0,i.__)("Missing variable","elementor"));const r=a.type===l.colorVariablePropTypeUtil.key,n=(0,p.resolveCssVariable)(e,a);return t.createElement(o.Stack,{direction:"row",spacing:.5,sx:{paddingInline:"1px"},alignItems:"center"},r&&t.createElement(s.ColorIndicator,{size:"inherit",value:a.value}),t.createElement(o.Typography,{variant:"caption",overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"},n))})},"./packages/packages/core/editor-variables/src/transformers/utils/resolve-css-variable.ts":function(e,a,r){r.r(a),r.d(a,{resolveCssVariable:function(){return resolveCssVariable}});const resolveCssVariable=(e,a)=>{let r=e,t="";if(a&&(t=a.value),a&&!a.deleted&&(r=a.label),!r.trim())return null;const n=`--${r}`;return t.trim()?`var(${n}, ${t})`:`var(${n})`}},"./packages/packages/core/editor-variables/src/transformers/variable-transformer.ts":function(e,a,r){r.r(a),r.d(a,{variableTransformer:function(){return i}});var t=r("@elementor/editor-canvas"),n=r("./packages/packages/core/editor-variables/src/service.ts"),o=r("./packages/packages/core/editor-variables/src/transformers/utils/resolve-css-variable.ts");const i=(0,t.createTransformer)(e=>{const a=n.service.variables()[e]||n.service.findVariableByLabel(e);if(!a)return null;const r=n.service.findIdByLabel(a.label);return(0,o.resolveCssVariable)(r,a)})},"./packages/packages/core/editor-variables/src/utils/duplicate-label.ts":function(e,a,r){r.r(a),r.d(a,{COPY_SUFFIX:function(){return n},generateDuplicateLabel:function(){return generateDuplicateLabel}});var t=r("./packages/packages/core/editor-variables/src/utils/validations.ts");const n="-Copy",trimToFit=(e,a)=>{const r=e+a;return r.length<=t.VARIABLE_LABEL_MAX_LENGTH?r:e.slice(0,t.VARIABLE_LABEL_MAX_LENGTH-a.length)+a},generateDuplicateLabel=(e,a)=>{const r=new Set(a),t=trimToFit(e,n);if(!r.has(t))return t;for(let a=2;a<=r.size+1;a++){const t=trimToFit(e,`${n}-${a}`);if(!r.has(t))return t}return t}},"./packages/packages/core/editor-variables/src/utils/filter-by-search.ts":function(e,a,r){function filterBySearch(e,a){const r=a.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(r))}r.r(a),r.d(a,{filterBySearch:function(){return filterBySearch}})},"./packages/packages/core/editor-variables/src/utils/llm-propvalue-label-resolver.ts":function(e,a,r){r.r(a),r.d(a,{globalVariablesLLMResolvers:function(){return n}});var t=r("./packages/packages/core/editor-variables/src/service.ts");const defaultResolver=e=>a=>{const r=String(a);return{$$type:e,value:t.service.variables()[r]?r:t.service.findIdByLabel(r)}},n={"global-color-variable":defaultResolver("global-color-variable"),"global-font-variable":defaultResolver("global-font-variable"),"global-size-variable":defaultResolver("global-size-variable")}},"./packages/packages/core/editor-variables/src/utils/size-value.ts":function(e,a,r){r.r(a),r.d(a,{sizeValue:function(){return sizeValue}});var t=r("@elementor/editor-props"),n=r("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts"),o=r("./packages/packages/core/editor-variables/src/prop-types/index.ts");const i="px",s="fx";function sizeValue(e){if(o.sizeVariablePropTypeUtil.isValid(e)||o.customSizeVariablePropTypeUtil.isValid(e)){const a=(0,n.getVariable)(e?.value);return a?.value}if(t.sizePropTypeUtil.isValid(e)){const{size:a,unit:r}=e.value;return"custom"!==r?`${a??0}${r??i}`:a||s}return""}},"./packages/packages/core/editor-variables/src/utils/tracking.ts":function(e,a,r){r.r(a),r.d(a,{trackVariableEvent:function(){return trackVariableEvent},trackVariableSyncToV3:function(){return trackVariableSyncToV3},trackVariablesManagerEvent:function(){return trackVariablesManagerEvent}});var t=r("@elementor/events");const trackVariableEvent=({varType:e,controlPath:a,action:r})=>{const{dispatchEvent:n,config:o}=(0,t.getMixpanel)();if(!o?.names?.variables?.[r])return;const i=o.names.variables[r];n?.(i,{location:o?.locations?.variables||"",secondaryLocation:o?.secondaryLocations?.variablesPopover||"",trigger:o?.triggers?.click||"",var_type:e,control_path:a,action_type:i})},trackVariablesManagerEvent=({action:e,varType:a,controlPath:r})=>{const{dispatchEvent:n,config:o}=(0,t.getMixpanel)();if(!o?.names?.variables?.[e])return;const i=o.names.variables[e],s={location:o?.locations?.variablesManager||"",trigger:o?.triggers?.click||"",action_type:i};a&&(s.var_type=a),r&&(s.style_control_path=r),n?.(i,s)},trackVariableSyncToV3=({variableLabel:e,action:a})=>{try{const{dispatchEvent:r,config:n}=(0,t.getMixpanel)();if(!n?.names?.variables?.variableSyncToV3)return;const o=n.names.variables.variableSyncToV3,i="sync"===a;r?.(o,{interaction_type:"click",target_type:e,target_name:i?"sync_to_v3":"unsync_to_v3",interaction_result:i?"var_is_synced_to_V3":"var_is_unsynced_from_V3",target_location:"widget_panel",location_l1:"var_manager",interaction_description:i?`user_synced_${e}_to_v3`:`user_unsync_${e}_from_v3`})}catch{}}},"./packages/packages/core/editor-variables/src/utils/unlink-variable.ts":function(e,a,r){r.r(a),r.d(a,{createUnlinkHandler:function(){return createUnlinkHandler},transformValueBeforeUnlink:function(){return transformValueBeforeUnlink}});var t=r("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts");function transformValueBeforeUnlink(e,a){const{valueTransformer:r}=(0,t.getVariableType)(a);return r?r(e.value,e.type):e.value}function createUnlinkHandler(e,a,r){return()=>{const{fallbackPropTypeUtil:n}=(0,t.getVariableType)(a),o=transformValueBeforeUnlink(e,a);r(n.create(o))}}},"./packages/packages/core/editor-variables/src/utils/validations.ts":function(e,a,r){r.r(a),r.d(a,{ERROR_MESSAGES:function(){return o},VARIABLE_LABEL_MAX_LENGTH:function(){return i},labelHint:function(){return labelHint},mapServerError:function(){return mapServerError},validateLabel:function(){return validateLabel},validateValue:function(){return validateValue}});var t=r("@elementor/icons"),n=r("@wordpress/i18n");const o={MISSING_VARIABLE_NAME:(0,n.__)("Give your variable a name.","elementor"),MISSING_VARIABLE_VALUE:(0,n.__)("Add a value to complete your variable.","elementor"),INVALID_CHARACTERS:(0,n.__)("Use letters, numbers, dashes (-), or underscores (_) for the name.","elementor"),NO_NON_SPECIAL_CHARACTER:(0,n.__)("Names have to include at least one non-special character.","elementor"),VARIABLE_LABEL_MAX_LENGTH:(0,n.__)("Keep names up to 50 characters.","elementor"),DUPLICATED_LABEL:(0,n.__)("This variable name already exists. Please choose a unique name.","elementor"),UNEXPECTED_ERROR:(0,n.__)("There was a glitch. Try saving your variable again.","elementor"),BATCH:{DUPLICATED_LABELS:(e,a)=>(0,n.sprintf)((0,n.__)("We found %1$d duplicated %2$s.","elementor"),e,a),UNEXPECTED_ERROR:(0,n.__)("There was a glitch.","elementor"),DUPLICATED_LABEL_ACTION:(0,n.__)("Take me there","elementor"),DUPLICATED_LABEL_ACTION_MESSAGE:(0,n.__)("Please rename the variables.","elementor"),UNEXPECTED_ERROR_ACTION_MESSAGE:(0,n.__)("Try saving your variables again.","elementor")}},i=50,mapServerError=e=>{if("duplicated_label"===e?.response?.data?.code)return{field:"label",message:o.DUPLICATED_LABEL};if("batch_duplicated_label"===e?.response?.data?.code){const a=e?.response?.data?.data??{},r=Object.keys(a).length,n=1===r?"name":"names",i=Object.keys(a);return{field:"label",message:o.BATCH.DUPLICATED_LABELS(r,n),severity:"error",IconComponent:t.AlertTriangleFilledIcon,action:{label:o.BATCH.DUPLICATED_LABEL_ACTION,message:o.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,data:{duplicatedIds:i}}}}return"batch_operation_failed"===e?.response?.data?.code?{field:"label",message:o.BATCH.UNEXPECTED_ERROR,severity:"secondary",IconComponent:t.InfoCircleFilledIcon,action:{message:o.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE}}:void 0},validateLabel=(e,a)=>{if(!e.trim())return o.MISSING_VARIABLE_NAME;if(!/^[a-zA-Z0-9_-]+$/.test(e))return o.INVALID_CHARACTERS;return/[a-zA-Z0-9]/.test(e)?i<e.length?o.VARIABLE_LABEL_MAX_LENGTH:Object.values(a??{}).some(a=>a.label===e)?o.DUPLICATED_LABEL:"":o.NO_NON_SPECIAL_CHARACTER},labelHint=e=>.8*i-1<e.length?o.VARIABLE_LABEL_MAX_LENGTH:"",validateValue=e=>e.trim()?"":o.MISSING_VARIABLE_VALUE},"./packages/packages/core/editor-variables/src/utils/variables-to-list.ts":function(e,a,r){r.r(a),r.d(a,{applySelectionFilters:function(){return applySelectionFilters},toNormalizedVariable:function(){return toNormalizedVariable},variablesToList:function(){return variablesToList}});const variablesToList=e=>Object.entries(e).map(([e,a])=>({key:e,...a})),toNormalizedVariable=({key:e,label:a,value:r,order:t,sync_to_v3:n})=>({key:e,label:a,value:r,order:t,sync_to_v3:n}),applySelectionFilters=(e,a)=>{const r={};return e.forEach(e=>(r[e.type]??=[]).push(e)),Object.entries(r).flatMap(([e,r])=>{const t=a[e]?.selectionFilter,n=r.map(toNormalizedVariable);return(t?.(n)??n).map(a=>({...a,type:e}))})}},"./packages/packages/core/editor-variables/src/variables-registry/create-variable-type-registry.ts":function(e,a,r){r.r(a),r.d(a,{createVariableTypeRegistry:function(){return createVariableTypeRegistry}});var t=r("@elementor/editor-canvas"),n=r("./packages/packages/core/editor-variables/src/transformers/inheritance-transformer.tsx"),o=r("./packages/packages/core/editor-variables/src/transformers/variable-transformer.ts");function createVariableTypeRegistry(){const e={},registerTransformer=(e,a)=>{t.styleTransformersRegistry.register(e,a??o.variableTransformer)},registerInheritanceTransformer=e=>{t.stylesInheritanceTransformersRegistry.register(e,n.inheritanceTransformer)};return{registerVariableType:({key:a,icon:r,startIcon:t,valueField:n,propTypeUtil:o,variableType:i,defaultValue:s,selectionFilter:l,valueTransformer:c,styleTransformer:p,fallbackPropTypeUtil:u,isCompatible:d,emptyState:b,isActive:m=!0,menuActionsFactory:v})=>{const g=a??o.key;d||(d=(e,a)=>"union"===e.kind&&a.type in e.prop_types),e[g]={icon:r,startIcon:t,valueField:n,propTypeUtil:o,variableType:i,defaultValue:s,selectionFilter:l,valueTransformer:c,fallbackPropTypeUtil:u,isCompatible:d,emptyState:b,isActive:m,menuActionsFactory:v},registerTransformer(o.key,p),registerInheritanceTransformer(o.key)},getVariableType:a=>e[a],getVariableTypes:()=>e,hasVariableType:a=>a in e&&!!e[a].isActive}}},"./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts":function(e,a,r){r.r(a),r.d(a,{getMenuActionsForVariable:function(){return getMenuActionsForVariable},getVariableType:function(){return o},getVariableTypes:function(){return i},hasVariableType:function(){return s},registerVariableType:function(){return n}});var t=r("./packages/packages/core/editor-variables/src/variables-registry/create-variable-type-registry.ts");const{registerVariableType:n,getVariableType:o,getVariableTypes:i,hasVariableType:s}=(0,t.createVariableTypeRegistry)();function getMenuActionsForVariable(e,a){const r=o(e);return r?.menuActionsFactory?r.menuActionsFactory(a):[]}},"@elementor/editor":function(e){e.exports=window.elementorV2.editor},"@elementor/editor-canvas":function(e){e.exports=window.elementorV2.editorCanvas},"@elementor/editor-controls":function(e){e.exports=window.elementorV2.editorControls},"@elementor/editor-current-user":function(e){e.exports=window.elementorV2.editorCurrentUser},"@elementor/editor-mcp":function(e){e.exports=window.elementorV2.editorMcp},"@elementor/editor-panels":function(e){e.exports=window.elementorV2.editorPanels},"@elementor/editor-props":function(e){e.exports=window.elementorV2.editorProps},"@elementor/editor-ui":function(e){e.exports=window.elementorV2.editorUi},"@elementor/editor-v1-adapters":function(e){e.exports=window.elementorV2.editorV1Adapters},"@elementor/events":function(e){e.exports=window.elementorV2.events},"@elementor/http-client":function(e){e.exports=window.elementorV2.httpClient},"@elementor/icons":function(e){e.exports=window.elementorV2.icons},"@elementor/menus":function(e){e.exports=window.elementorV2.menus},"@elementor/schema":function(e){e.exports=window.elementorV2.schema},"@elementor/ui":function(e){e.exports=window.elementorV2.ui},"@elementor/utils":function(e){e.exports=window.elementorV2.utils},"@wordpress/i18n":function(e){e.exports=window.wp.i18n},react:function(e){e.exports=window.React}},a={};function __webpack_require__(r){var t=a[r];if(void 0!==t)return t.exports;var n=a[r]={exports:{}};return e[r](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(a,{a:a}),a},__webpack_require__.d=function(e,a){for(var r in a)__webpack_require__.o(a,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},__webpack_require__.o=function(e,a){return Object.prototype.hasOwnProperty.call(e,a)},__webpack_require__.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};!function(){__webpack_require__.r(r),__webpack_require__.d(r,{GLOBAL_VARIABLES_URI:function(){return t.GLOBAL_VARIABLES_URI},Utils:function(){return c},VariablesManagerPanelEmbedded:function(){return e.VariablesManagerPanelEmbedded},getMenuActionsForVariable:function(){return s.getMenuActionsForVariable},hasVariable:function(){return l.hasVariable},init:function(){return a.init},registerVariableType:function(){return s.registerVariableType},registerVariableTypes:function(){return o.registerVariableTypes},service:function(){return i.service},sizeVariablePropTypeUtil:function(){return n.sizeVariablePropTypeUtil}});var e=__webpack_require__("./packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx"),a=__webpack_require__("./packages/packages/core/editor-variables/src/init.ts"),t=__webpack_require__("./packages/packages/core/editor-variables/src/mcp/variables-resource.ts"),n=__webpack_require__("./packages/packages/core/editor-variables/src/prop-types/size-variable-prop-type.ts"),o=__webpack_require__("./packages/packages/core/editor-variables/src/register-variable-types.tsx"),i=__webpack_require__("./packages/packages/core/editor-variables/src/service.ts"),s=__webpack_require__("./packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts"),l=__webpack_require__("./packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts");const c={globalVariablesLLMResolvers:__webpack_require__("./packages/packages/core/editor-variables/src/utils/llm-propvalue-label-resolver.ts").globalVariablesLLMResolvers}}(),(window.elementorV2=window.elementorV2||{}).editorVariables=r}(),window.elementorV2.editorVariables?.init?.();
1 +(function(react, _elementor_editor_current_user, _elementor_editor_panels, _elementor_editor_ui, _elementor_icons, _elementor_ui, _wordpress_i18n, _elementor_events, _elementor_editor_canvas, _elementor_editor_props, _elementor_schema, _elementor_http_client, _elementor_editor_v1_adapters, _elementor_editor_controls, _elementor_utils, _elementor_editor, _elementor_editor_mcp, _elementor_menus) {
2 +
3 +//#region \0rolldown/runtime.js
4 + var __create = Object.create;
5 + var __defProp$1 = Object.defineProperty;
6 + var __name = (target, value) => __defProp$1(target, "name", {
7 + value,
8 + configurable: true
9 + });
10 + var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11 + var __getOwnPropNames = Object.getOwnPropertyNames;
12 + var __getProtoOf = Object.getPrototypeOf;
13 + var __hasOwnProp = Object.prototype.hasOwnProperty;
14 + var __exportAll = (all, no_symbols) => {
15 + let target = {};
16 + for (var name in all) {
17 + __defProp$1(target, name, {
18 + get: all[name],
19 + enumerable: true
20 + });
21 + }
22 + if (!no_symbols) {
23 + __defProp$1(target, Symbol.toStringTag, { value: "Module" });
24 + }
25 + return target;
26 + };
27 + var __copyProps = (to, from, except, desc) => {
28 + if (from && typeof from === "object" || typeof from === "function") {
29 + for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
30 + key = keys[i];
31 + if (!__hasOwnProp.call(to, key) && key !== except) {
32 + __defProp$1(to, key, {
33 + get: ((k) => from[k]).bind(null, key),
34 + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
35 + });
36 + }
37 + }
38 + }
39 + return to;
40 + };
41 + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
42 + value: mod,
43 + enumerable: true
44 + }) : target, mod));
45 +
46 +//#endregion
47 +react = __toESM(react);
48 +
49 +//#region packages/packages/core/editor-variables/src/utils/tracking.ts
50 + var trackVariableEvent = ({ varType, controlPath, action, executedBy }) => {
51 + const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
52 + if (!config?.names?.variables?.[action]) return;
53 + const name = config.names.variables[action];
54 + let eventData = {
55 + var_type: varType,
56 + action_type: name
57 + };
58 + if (executedBy) eventData.executed_by = executedBy;
59 + const defaultLocationInfo = {
60 + location: config?.locations?.variables || "",
61 + secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
62 + trigger: config?.triggers?.click || ""
63 + };
64 + if (!executedBy || executedBy !== "mcp_tool") eventData = {
65 + ...defaultLocationInfo,
66 + ...eventData
67 + };
68 + if (controlPath) eventData.control_path = controlPath;
69 + dispatchEvent?.(name, eventData);
70 + };
71 + var trackVariablesManagerEvent = ({ action, source, varType, controlPath }) => {
72 + const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
73 + if (!config?.names?.variables?.[action]) return;
74 + const name = config.names.variables[action];
75 + const eventData = {
76 + location: config?.locations?.variablesManager || "",
77 + trigger: config?.triggers?.click || "",
78 + action_type: name
79 + };
80 + if (source) eventData.source = source;
81 + if (varType) eventData.var_type = varType;
82 + if (controlPath) eventData.style_control_path = controlPath;
83 + dispatchEvent?.(name, eventData);
84 + };
85 + var trackVariableSyncToV3 = ({ variableLabel, action }) => {
86 + const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
87 + if (!config?.names?.variables?.variableSyncToV3) return;
88 + const name = config.names.variables.variableSyncToV3;
89 + const isSync = action === "sync";
90 + dispatchEvent?.(name, {
91 + interaction_type: "click",
92 + target_type: variableLabel,
93 + target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
94 + interaction_result: isSync ? "var_is_synced_to_V3" : "var_is_unsynced_from_V3",
95 + target_location: "widget_panel",
96 + location_l1: "var_manager",
97 + interaction_description: isSync ? `user_synced_${variableLabel}_to_v3` : `user_unsync_${variableLabel}_from_v3`
98 + });
99 + };
100 +
101 +//#endregion
102 +//#region packages/packages/core/editor-variables/src/utils/validations.ts
103 + var ERROR_MESSAGES = {
104 + MISSING_VARIABLE_NAME: (0, _wordpress_i18n.__)("Give your variable a name.", "elementor"),
105 + MISSING_VARIABLE_VALUE: (0, _wordpress_i18n.__)("Add a value to complete your variable.", "elementor"),
106 + INVALID_CHARACTERS: (0, _wordpress_i18n.__)("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
107 + NO_NON_SPECIAL_CHARACTER: (0, _wordpress_i18n.__)("Names have to include at least one non-special character.", "elementor"),
108 + VARIABLE_LABEL_MAX_LENGTH: (0, _wordpress_i18n.__)("Keep names up to 50 characters.", "elementor"),
109 + DUPLICATED_LABEL: (0, _wordpress_i18n.__)("This variable name already exists. Please choose a unique name.", "elementor"),
110 + UNEXPECTED_ERROR: (0, _wordpress_i18n.__)("There was a glitch. Try saving your variable again.", "elementor"),
111 + BATCH: {
112 + DUPLICATED_LABELS: (count, name) => (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("We found %1$d duplicated %2$s.", "elementor"), count, name),
113 + UNEXPECTED_ERROR: (0, _wordpress_i18n.__)("There was a glitch.", "elementor"),
114 + DUPLICATED_LABEL_ACTION: (0, _wordpress_i18n.__)("Take me there", "elementor"),
115 + DUPLICATED_LABEL_ACTION_MESSAGE: (0, _wordpress_i18n.__)("Please rename the variables.", "elementor"),
116 + UNEXPECTED_ERROR_ACTION_MESSAGE: (0, _wordpress_i18n.__)("Try saving your variables again.", "elementor")
117 + }
118 + };
119 + var VARIABLE_LABEL_MAX_LENGTH = 50;
120 + var mapServerError = (error) => {
121 + if (error?.response?.data?.code === "duplicated_label") return {
122 + field: "label",
123 + message: ERROR_MESSAGES.DUPLICATED_LABEL
124 + };
125 + if (error?.response?.data?.code === "batch_duplicated_label") {
126 + const errorData = error?.response?.data?.data ?? {};
127 + const count = Object.keys(errorData).length;
128 + const name = count === 1 ? "name" : "names";
129 + const duplicatedIds = Object.keys(errorData);
130 + return {
131 + field: "label",
132 + message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
133 + severity: "error",
134 + IconComponent: _elementor_icons.AlertTriangleFilledIcon,
135 + action: {
136 + label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
137 + message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
138 + data: { duplicatedIds }
139 + }
140 + };
141 + }
142 + if (error?.response?.data?.code === "batch_operation_failed") return {
143 + field: "label",
144 + message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
145 + severity: "secondary",
146 + IconComponent: _elementor_icons.InfoCircleFilledIcon,
147 + action: { message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE }
148 + };
149 + };
150 + var validateLabel = (name, variables) => {
151 + if (!name.trim()) return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
152 + if (!/^[a-zA-Z0-9_-]+$/.test(name)) return ERROR_MESSAGES.INVALID_CHARACTERS;
153 + if (!/[a-zA-Z0-9]/.test(name)) return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
154 + if (50 < name.length) return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
155 + if (Object.values(variables ?? {}).some((variable) => variable.label === name)) return ERROR_MESSAGES.DUPLICATED_LABEL;
156 + return "";
157 + };
158 + var labelHint = (name) => {
159 + if (50 * .8 - 1 < name.length) return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
160 + return "";
161 + };
162 + var validateValue = (value) => {
163 + if (!value.trim()) return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
164 + return "";
165 + };
166 +
167 +//#endregion
168 +//#region packages/packages/core/editor-variables/src/components/ui/color-indicator.tsx
169 + var ColorIndicator = (0, _elementor_ui.styled)(_elementor_ui.UnstableColorIndicator)(({ theme }) => ({
170 + borderRadius: `${theme.shape.borderRadius / 2}px`,
171 + marginRight: theme.spacing(.25)
172 + }));
173 +
174 +//#endregion
175 +//#region packages/packages/core/editor-variables/src/prop-types/color-variable-prop-type.ts
176 + var colorVariablePropTypeUtil = (0, _elementor_editor_props.createPropUtils)("global-color-variable", _elementor_schema.z.string());
177 +
178 +//#endregion
179 +//#region packages/packages/core/editor-variables/src/api.ts
180 + var apiClient = {
181 + list: () => {
182 + return (0, _elementor_http_client.httpService)().get("elementor/v1/variables/list");
183 + },
184 + create: (type, label, value) => {
185 + return (0, _elementor_http_client.httpService)().post("elementor/v1/variables/create", {
186 + type,
187 + label,
188 + value
189 + });
190 + },
191 + update: (id, label, value, type) => {
192 + return (0, _elementor_http_client.httpService)().put("elementor/v1/variables/update", {
193 + id,
194 + label,
195 + value,
196 + type
197 + });
198 + },
199 + delete: (id) => {
200 + return (0, _elementor_http_client.httpService)().post("elementor/v1/variables/delete", { id });
201 + },
202 + restore: (id, label, value, type) => {
203 + const payload = { id };
204 + if (label) payload.label = label;
205 + if (value) payload.value = value;
206 + if (type) payload.type = type;
207 + return (0, _elementor_http_client.httpService)().post("elementor/v1/variables/restore", payload);
208 + },
209 + batch: (payload) => {
210 + return (0, _elementor_http_client.httpService)().post("elementor/v1/variables/batch", payload);
211 + }
212 + };
213 +
214 +//#endregion
215 +//#region packages/packages/core/editor-variables/src/batch-operations.ts
216 + var generateTempId = () => {
217 + return `tmp-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
218 + };
219 + var isTempId = (id) => {
220 + return id.startsWith("tmp-");
221 + };
222 + var buildOperationsArray = (originalVariables, currentVariables, deletedVariables) => {
223 + const operations = [];
224 + Object.entries(currentVariables).forEach(([id, variable]) => {
225 + if (isTempId(id)) operations.push({
226 + type: "create",
227 + variable: {
228 + ...variable,
229 + id
230 + }
231 + });
232 + else if (originalVariables[id]) {
233 + const original = originalVariables[id];
234 + const syncChanged = original.sync_to_v3 !== variable.sync_to_v3;
235 + if (original.deleted && !variable.deleted) operations.push({
236 + type: "restore",
237 + id,
238 + ...original.label !== variable.label && { label: variable.label },
239 + ...original.value !== variable.value && { value: variable.value }
240 + });
241 + else if (!variable.deleted && (original.label !== variable.label || original.value !== variable.value || original.order !== variable.order || original.type !== variable.type || syncChanged)) operations.push({
242 + type: "update",
243 + id,
244 + variable: {
245 + ...original.label !== variable.label && { label: variable.label },
246 + ...original.value !== variable.value && { value: variable.value },
247 + ...original.order !== variable.order && { order: variable.order },
248 + ...original.type !== variable.type && { type: variable.type },
249 + ...syncChanged && { sync_to_v3: variable.sync_to_v3 }
250 + }
251 + });
252 + }
253 + });
254 + deletedVariables.forEach((id) => {
255 + operations.push({
256 + type: "delete",
257 + id
258 + });
259 + });
260 + return operations.filter((op) => {
261 + const id = op.id || op.variable?.id;
262 + return id && !(isTempId(id) && currentVariables[id]?.deleted);
263 + });
264 + };
265 +
266 +//#endregion
267 +//#region packages/packages/core/editor-variables/src/storage.ts
268 + var __defProp = Object.defineProperty;
269 + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
270 + enumerable: true,
271 + configurable: true,
272 + writable: true,
273 + value
274 + }) : obj[key] = value;
275 + var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
276 + var STORAGE_KEY = "elementor-global-variables";
277 + var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
278 + var STORAGE_UPDATED_EVENT = "variables:updated";
279 + var OP_RW = "RW";
280 + var OP_RO = "RO";
281 + var Storage = class {
282 + constructor() {
283 + __publicField(this, "state");
284 + this.state = {
285 + watermark: -1,
286 + variables: {}
287 + };
288 + }
289 + notifyChange() {
290 + window.dispatchEvent(new Event(STORAGE_UPDATED_EVENT));
291 + }
292 + load() {
293 + this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
294 + this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
295 + return this.state.variables;
296 + }
297 + fill(variables, watermark) {
298 + this.state.variables = {};
299 + if (variables && Object.keys(variables).length) this.state.variables = variables;
300 + this.state.watermark = watermark;
301 + localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
302 + localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
303 + this.notifyChange();
304 + }
305 + add(id, variable) {
306 + this.load();
307 + this.state.variables[id] = variable;
308 + localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
309 + this.notifyChange();
310 + }
311 + update(id, variable) {
312 + this.load();
313 + this.state.variables[id] = variable;
314 + localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
315 + this.notifyChange();
316 + }
317 + watermark(watermark) {
318 + this.state.watermark = watermark;
319 + localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
320 + }
321 + watermarkDiff(operation, newWatermark) {
322 + const diff = newWatermark - this.state.watermark;
323 + if ("RW" === operation) return 1 !== diff;
324 + if (OP_RO === operation) return 0 !== diff;
325 + return false;
326 + }
327 + };
328 +
329 +//#endregion
330 +//#region packages/packages/core/editor-variables/src/prop-types/font-variable-prop-type.ts
331 + var fontVariablePropTypeUtil = (0, _elementor_editor_props.createPropUtils)("global-font-variable", _elementor_schema.z.string());
332 +
333 +//#endregion
334 +//#region packages/packages/core/editor-variables/src/create-style-variables-repository.ts
335 + var createStyleVariablesRepository = () => {
336 + const variables = {};
337 + let subscription;
338 + const subscribe = (cb) => {
339 + subscription = cb;
340 + return () => {
341 + subscription = () => {};
342 + };
343 + };
344 + const notify = () => {
345 + if (typeof subscription === "function") subscription({ ...variables });
346 + };
347 + const shouldUpdate = (key, maybeUpdated) => {
348 + if (!(key in variables)) return true;
349 + if (variables[key].label !== maybeUpdated.label) return true;
350 + if (variables[key].value !== maybeUpdated.value) return true;
351 + if (!variables[key]?.deleted && maybeUpdated?.deleted) return true;
352 + if (variables[key]?.deleted && !maybeUpdated?.deleted) return true;
353 + return false;
354 + };
355 + const applyUpdates = (updatedVars) => {
356 + let hasChanges = false;
357 + for (const [key, variable] of Object.entries(updatedVars)) if (shouldUpdate(key, variable)) {
358 + variables[key] = variable;
359 + if (variable.type === fontVariablePropTypeUtil.key) fontEnqueue(variable.value);
360 + hasChanges = true;
361 + }
362 + return hasChanges;
363 + };
364 + const fontEnqueue = (value) => {
365 + if (!value) return;
366 + try {
367 + (0, _elementor_editor_v1_adapters.enqueueFont)(value);
368 + } catch {}
369 + };
370 + const update = (updatedVars) => {
371 + if (applyUpdates(updatedVars)) notify();
372 + };
373 + return {
374 + subscribe,
375 + update
376 + };
377 + };
378 +
379 +//#endregion
380 +//#region packages/packages/core/editor-variables/src/style-variables-repository.ts
381 + var styleVariablesRepository = createStyleVariablesRepository();
382 +
383 +//#endregion
384 +//#region packages/packages/core/editor-variables/src/service.ts
385 + var storage = new Storage();
386 + var service = {
387 + variables: () => {
388 + return storage.load();
389 + },
390 + findIdByLabel(needle) {
391 + const variableId = Object.entries(this.variables()).find(([, variable]) => variable.label === needle);
392 + if (!variableId) throw new Error(`Variable with label ${needle} not found`);
393 + return variableId[0];
394 + },
395 + findVariableByLabel(needle) {
396 + return Object.values(this.variables()).find((variable) => variable.label === needle) || null;
397 + },
398 + getWatermark: () => {
399 + return storage.state.watermark;
400 + },
401 + init: () => {
402 + return service.load();
403 + },
404 + load: () => {
405 + return apiClient.list().then((response) => {
406 + const { success, data: payload } = response.data;
407 + if (!success) throw new Error("Unexpected response from server");
408 + return payload;
409 + }).then((data) => {
410 + const { variables, watermark } = data;
411 + storage.fill(variables, watermark);
412 + styleVariablesRepository.update(variables);
413 + return variables;
414 + });
415 + },
416 + create: ({ type, label, value }, options = {}) => {
417 + return apiClient.create(type, label, value).then((response) => {
418 + const { success, data: payload } = response.data;
419 + if (!success) {
420 + const errorMessage = payload?.message || (0, _wordpress_i18n.__)("Unexpected response from server", "elementor");
421 + throw new Error(errorMessage);
422 + }
423 + return payload;
424 + }).then((data) => {
425 + const { variable, watermark } = data;
426 + handleWatermark("RW", watermark);
427 + const { id: variableId, ...createdVariable } = variable;
428 + storage.add(variableId, createdVariable);
429 + styleVariablesRepository.update({ [variableId]: createdVariable });
430 + trackVariableEvent({
431 + varType: type,
432 + action: "save",
433 + ...options.eventData
434 + });
435 + return {
436 + id: variableId,
437 + variable: createdVariable
438 + };
439 + });
440 + },
441 + update: (id, { label, value, type }, options = {}) => {
442 + return apiClient.update(id, label, value, type).then((response) => {
443 + const { success, data: payload } = response.data;
444 + if (!success) {
445 + const errorMessage = payload?.message || (0, _wordpress_i18n.__)("Unexpected response from server", "elementor");
446 + throw new Error(errorMessage);
447 + }
448 + return payload;
449 + }).then((data) => {
450 + const { variable, watermark } = data;
451 + handleWatermark("RW", watermark);
452 + const { id: variableId, ...updatedVariable } = variable;
453 + storage.update(variableId, updatedVariable);
454 + styleVariablesRepository.update({ [variableId]: updatedVariable });
455 + trackVariableEvent({
456 + varType: updatedVariable.type,
457 + action: "update",
458 + ...options.eventData
459 + });
460 + return {
461 + id: variableId,
462 + variable: updatedVariable
463 + };
464 + });
465 + },
466 + delete: (id) => {
467 + return apiClient.delete(id).then((response) => {
468 + const { success, data: payload } = response.data;
469 + if (!success) throw new Error("Unexpected response from server");
470 + return payload;
471 + }).then((data) => {
472 + const { variable, watermark } = data;
473 + handleWatermark("RW", watermark);
474 + const { id: variableId, ...deletedVariable } = variable;
475 + storage.update(variableId, deletedVariable);
476 + styleVariablesRepository.update({ [variableId]: deletedVariable });
477 + return {
478 + id: variableId,
479 + variable: deletedVariable
480 + };
481 + });
482 + },
483 + restore: (id, label, value, type) => {
484 + return apiClient.restore(id, label, value, type).then((response) => {
485 + const { success, data: payload } = response.data;
486 + if (!success) throw new Error("Unexpected response from server");
487 + return payload;
488 + }).then((data) => {
489 + const { variable, watermark } = data;
490 + handleWatermark("RW", watermark);
491 + const { id: variableId, ...restoredVariable } = variable;
492 + storage.update(variableId, restoredVariable);
493 + styleVariablesRepository.update({ [variableId]: restoredVariable });
494 + return {
495 + id: variableId,
496 + variable: restoredVariable
497 + };
498 + });
499 + },
500 + batchSave: (originalVariables, currentVariables, deletedVariables) => {
501 + const operations = buildOperationsArray(originalVariables, currentVariables, deletedVariables);
502 + const batchPayload = {
503 + operations,
504 + watermark: storage.state.watermark
505 + };
506 + if (operations.length === 0) return Promise.resolve({
507 + success: true,
508 + watermark: storage.state.watermark,
509 + operations: 0
510 + });
511 + return apiClient.batch(batchPayload).then((response) => {
512 + const { success, data: payload } = response.data;
513 + if (!success) throw new Error("Unexpected response from server");
514 + return payload;
515 + }).then((data) => {
516 + const { results, watermark } = data;
517 + handleWatermark("RW", watermark);
518 + if (results) results.forEach((result) => {
519 + const variableId = result.id;
520 + if (result.variable) {
521 + if (result.type === "create") storage.add(variableId, result.variable);
522 + else storage.update(variableId, result.variable);
523 + styleVariablesRepository.update({ [variableId]: result.variable });
524 + }
525 + });
526 + return {
527 + success: true,
528 + watermark,
529 + operations: operations.length
530 + };
531 + });
532 + }
533 + };
534 + var handleWatermark = (operation, newWatermark) => {
535 + if (storage.watermarkDiff(operation, newWatermark)) setTimeout(() => service.load(), 500);
536 + storage.watermark(newWatermark);
537 + };
538 + var applyLocalMutation = (action, variableWithId, watermark) => {
539 + const { id: variableId, ...variable } = variableWithId;
540 + handleWatermark("RW", watermark);
541 + if (action === "create") storage.add(variableId, variable);
542 + else storage.update(variableId, variable);
543 + styleVariablesRepository.update({ [variableId]: variable });
544 + };
545 +
546 +//#endregion
547 +//#region packages/packages/core/editor-variables/src/transformers/utils/resolve-css-variable.ts
548 + var resolveCssVariable = (id, variable) => {
549 + let name = id;
550 + let fallbackValue = "";
551 + if (variable) fallbackValue = variable.value;
552 + if (variable && !variable.deleted) name = variable.label;
553 + if (!name.trim()) return null;
554 + const validCssVariableName = `--${name}`;
555 + if (!fallbackValue.trim()) return `var(${validCssVariableName})`;
556 + return `var(${validCssVariableName}, ${fallbackValue})`;
557 + };
558 +
559 +//#endregion
560 +//#region packages/packages/core/editor-variables/src/transformers/inheritance-transformer.tsx
561 + var inheritanceTransformer = (0, _elementor_editor_canvas.createTransformer)((id) => {
562 + const variable = service.variables()[id];
563 + if (!variable) return /* @__PURE__ */ react.createElement("span", null, (0, _wordpress_i18n.__)("Missing variable", "elementor"));
564 + const showColorIndicator = variable.type === colorVariablePropTypeUtil.key;
565 + const css = resolveCssVariable(id, variable);
566 + return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
567 + direction: "row",
568 + spacing: .5,
569 + sx: { paddingInline: "1px" },
570 + alignItems: "center"
571 + }, showColorIndicator && /* @__PURE__ */ react.createElement(ColorIndicator, {
572 + size: "inherit",
573 + value: variable.value
574 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
575 + variant: "caption",
576 + overflow: "hidden",
577 + whiteSpace: "nowrap",
578 + textOverflow: "ellipsis"
579 + }, css));
580 + });
581 +
582 +//#endregion
583 +//#region packages/packages/core/editor-variables/src/transformers/variable-transformer.ts
584 + var variableTransformer = (0, _elementor_editor_canvas.createTransformer)((idOrLabel, { key }) => {
585 + const targetVariable = service.variables()[idOrLabel] || service.findVariableByLabel(idOrLabel);
586 + if (!targetVariable) return null;
587 + if ((0, _elementor_editor_canvas.isGridTrackProperty)(key)) return (0, _elementor_editor_canvas.formatGridTrackRepeat)(parseInt((targetVariable.value ?? "").trim(), 10));
588 + return resolveCssVariable(service.findIdByLabel(targetVariable.label), targetVariable);
589 + });
590 +
591 +//#endregion
592 +//#region packages/packages/core/editor-variables/src/variables-registry/create-variable-type-registry.ts
593 + function createVariableTypeRegistry() {
594 + const variableTypes = {};
595 + const registerVariableType = ({ key, icon, startIcon, valueField, propTypeUtil, variableType, defaultValue, selectionFilter, valueTransformer, styleTransformer, fallbackPropTypeUtil, isCompatible, emptyState, isActive = true, menuActionsFactory }) => {
596 + const variableTypeKey = key ?? propTypeUtil.key;
597 + if (!isCompatible) isCompatible = (propType, variable) => {
598 + if ("union" === propType.kind) {
599 + if (variable.type in propType.prop_types) return true;
600 + }
601 + return false;
602 + };
603 + variableTypes[variableTypeKey] = {
604 + icon,
605 + startIcon,
606 + valueField,
607 + propTypeUtil,
608 + variableType,
609 + defaultValue,
610 + selectionFilter,
611 + valueTransformer,
612 + fallbackPropTypeUtil,
613 + isCompatible,
614 + emptyState,
615 + isActive,
616 + menuActionsFactory
617 + };
618 + registerTransformer(propTypeUtil.key, styleTransformer);
619 + registerInheritanceTransformer(propTypeUtil.key);
620 + };
621 + const registerTransformer = (key, transformer) => {
622 + _elementor_editor_canvas.styleTransformersRegistry.register(key, transformer ?? variableTransformer);
623 + };
624 + const registerInheritanceTransformer = (key) => {
625 + _elementor_editor_canvas.stylesInheritanceTransformersRegistry.register(key, inheritanceTransformer);
626 + };
627 + const getVariableType = (key) => {
628 + return variableTypes[key];
629 + };
630 + const getVariableTypes = () => {
631 + return variableTypes;
632 + };
633 + const hasVariableType = (key) => {
634 + return key in variableTypes && !!variableTypes[key].isActive;
635 + };
636 + return {
637 + registerVariableType,
638 + getVariableType,
639 + getVariableTypes,
640 + hasVariableType
641 + };
642 + }
643 +
644 +//#endregion
645 +//#region packages/packages/core/editor-variables/src/variables-registry/variable-type-registry.ts
646 + var { registerVariableType, getVariableType, getVariableTypes, hasVariableType } = createVariableTypeRegistry();
647 + function getMenuActionsForVariable(variableType, context) {
648 + const typeOptions = getVariableType(variableType);
649 + if (typeOptions?.menuActionsFactory) return typeOptions.menuActionsFactory(context);
650 + return [];
651 + }
652 +
653 +//#endregion
654 +//#region packages/packages/core/editor-variables/src/components/ui/delete-confirmation-dialog.tsx
655 + var DeleteConfirmationDialog = ({ open, label, closeDialog, onConfirm }) => {
656 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog, {
657 + open,
658 + onClose: closeDialog
659 + }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Title, null, (0, _wordpress_i18n.__)("Delete this variable?", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.ContentText, null, (0, _wordpress_i18n.__)("All elements using", "elementor"), "\xA0", /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
660 + variant: "subtitle2",
661 + component: "span",
662 + sx: { lineBreak: "anywhere" }
663 + }, label), "\xA0", (0, _wordpress_i18n.__)("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Actions, {
664 + onClose: closeDialog,
665 + onConfirm
666 + }));
667 + };
668 +
669 +//#endregion
670 +//#region packages/packages/core/editor-variables/src/hooks/use-permissions.ts
671 + var usePermissions = () => {
672 + const { canUser, isAdmin } = (0, _elementor_editor_current_user.useCurrentUserCapabilities)();
673 + return {
674 + canAssign: () => canUser("edit_posts"),
675 + canUnlink: () => canUser("edit_posts"),
676 + canAdd: () => isAdmin,
677 + canDelete: () => isAdmin,
678 + canEdit: () => isAdmin,
679 + canRestore: () => isAdmin,
680 + canManageSettings: () => isAdmin
681 + };
682 + };
683 +
684 +//#endregion
685 +//#region packages/packages/core/editor-variables/src/components/ui/empty-state.tsx
686 + var EmptyState = ({ icon, title, message, onAdd, children }) => {
687 + const canAdd = usePermissions().canAdd();
688 + const displayTitle = canAdd ? title : (0, _wordpress_i18n.__)("There are no variables", "elementor");
689 + const displayMessage = canAdd ? message : (0, _wordpress_i18n.__)("With your current role, you can only connect and detach variables.", "elementor");
690 + return /* @__PURE__ */ react.createElement(Content, {
691 + title: displayTitle,
692 + message: displayMessage,
693 + icon
694 + }, children || onAdd && /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
695 + variant: "outlined",
696 + color: "secondary",
697 + size: "small",
698 + onClick: onAdd
699 + }, (0, _wordpress_i18n.__)("Create a variable", "elementor")));
700 + };
701 + function Content({ title, message, icon, children }) {
702 + return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
703 + gap: 1,
704 + alignItems: "center",
705 + justifyContent: "flex-start",
706 + height: "100%",
707 + color: "text.secondary",
708 + sx: {
709 + p: 2.5,
710 + pt: 8,
711 + pb: 5.5
712 + }
713 + }, icon, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
714 + align: "center",
715 + variant: "subtitle2"
716 + }, title), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
717 + align: "center",
718 + variant: "caption",
719 + maxWidth: "180px"
720 + }, message), children);
721 + }
722 +
723 +//#endregion
724 +//#region packages/packages/core/editor-variables/src/components/ui/no-search-results.tsx
725 + var NoSearchResults = ({ searchValue, onClear, icon }) => {
726 + return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
727 + gap: 1,
728 + alignItems: "center",
729 + justifyContent: "center",
730 + p: 2.5,
731 + color: "text.secondary",
732 + sx: {
733 + pb: 3.5,
734 + pt: 8
735 + }
736 + }, icon, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
737 + align: "center",
738 + variant: "subtitle2"
739 + }, (0, _wordpress_i18n.__)("Sorry, nothing matched", "elementor"), /* @__PURE__ */ react.createElement("br", null), "“", searchValue, "”."), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
740 + align: "center",
741 + variant: "caption",
742 + sx: {
743 + display: "flex",
744 + flexDirection: "column"
745 + }
746 + }, (0, _wordpress_i18n.__)("Try something else.", "elementor"), /* @__PURE__ */ react.createElement(_elementor_ui.Link, {
747 + color: "text.secondary",
748 + variant: "caption",
749 + component: "button",
750 + onClick: onClear
751 + }, (0, _wordpress_i18n.__)("Clear & try again", "elementor"))));
752 + };
753 +
754 +//#endregion
755 +//#region packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-auto-edit.ts
756 + var useAutoEdit = () => {
757 + const [autoEditVariableId, setAutoEditVariableId] = (0, react.useState)(void 0);
758 + return {
759 + autoEditVariableId,
760 + startAutoEdit: (0, react.useCallback)((variableId) => {
761 + setAutoEditVariableId(variableId);
762 + }, []),
763 + handleAutoEditComplete: (0, react.useCallback)(() => {
764 + setTimeout(() => {
765 + setAutoEditVariableId(void 0);
766 + }, 100);
767 + }, [])
768 + };
769 + };
770 +
771 +//#endregion
772 +//#region packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-error-navigation.ts
773 + var useErrorNavigation = () => {
774 + const currentIndexRef = (0, react.useRef)(0);
775 + return {
776 + createNavigationCallback: (0, react.useCallback)((ids, onNavigate, onComplete) => {
777 + return () => {
778 + if (!ids?.length) return;
779 + const currentIndex = currentIndexRef.current;
780 + const currentId = ids[currentIndex];
781 + if (currentId) {
782 + onNavigate(currentId);
783 + const nextIndex = currentIndex + 1;
784 + if (nextIndex >= ids.length) {
785 + onComplete();
786 + currentIndexRef.current = 0;
787 + } else currentIndexRef.current = nextIndex;
788 + }
789 + };
790 + }, []),
791 + resetNavigation: (0, react.useCallback)(() => {
792 + currentIndexRef.current = 0;
793 + }, [])
794 + };
795 + };
796 +
797 +//#endregion
798 +//#region packages/packages/core/editor-variables/src/context/variable-type-context.tsx
799 + var VariableTypeContext = (0, react.createContext)(null);
800 + function VariableTypeProvider({ children, propTypeKey }) {
801 + return /* @__PURE__ */ react.createElement(VariableTypeContext.Provider, { value: propTypeKey }, children);
802 + }
803 + function useVariableType() {
804 + const context = (0, react.useContext)(VariableTypeContext);
805 + if (context === null) throw new Error("useVariableType must be used within a VariableTypeProvider");
806 + return getVariableType(context);
807 + }
808 +
809 +//#endregion
810 +//#region packages/packages/core/editor-variables/src/utils/filter-by-search.ts
811 + function filterBySearch(variables, searchValue) {
812 + const lowerSearchValue = searchValue.toLowerCase();
813 + return variables.filter((variable) => variable.label.toLowerCase().includes(lowerSearchValue));
814 + }
815 +
816 +//#endregion
817 +//#region packages/packages/core/editor-variables/src/utils/variables-to-list.ts
818 + var variablesToList = (variables) => {
819 + return Object.entries(variables).map(([key, variable]) => ({
820 + key,
821 + ...variable
822 + }));
823 + };
824 + var toNormalizedVariable = ({ key, label, value, order, sync_to_v3: syncToV3 }) => ({
825 + key,
826 + label,
827 + value,
828 + order,
829 + sync_to_v3: syncToV3
830 + });
831 + var applySelectionFilters = (variables, variableTypes) => {
832 + const grouped = {};
833 + variables.forEach((item) => {
834 + var _a;
835 + return (grouped[_a = item.type] ?? (grouped[_a] = [])).push(item);
836 + });
837 + return Object.entries(grouped).flatMap(([type, vars]) => {
838 + const filter = variableTypes[type]?.selectionFilter;
839 + const normalized = vars.map(toNormalizedVariable);
840 + return (filter?.(normalized) ?? normalized).map((v) => ({
841 + ...v,
842 + type
843 + }));
844 + });
845 + };
846 +
847 +//#endregion
848 +//#region packages/packages/core/editor-variables/src/hooks/use-prop-variables.ts
849 + var getVariables = (includeDeleted = true) => {
850 + const variables = service.variables();
851 + if (includeDeleted) return variables;
852 + return Object.fromEntries(Object.entries(variables).filter(([, variable]) => !variable.deleted));
853 + };
854 + var hasVariable = (key) => {
855 + return getVariables()[key] !== void 0;
856 + };
857 + var useVariable = (key) => {
858 + return getVariable(key);
859 + };
860 + function getVariable(key) {
861 + const variables = getVariables();
862 + if (!variables?.[key]) return null;
863 + return {
864 + ...variables[key],
865 + key
866 + };
867 + }
868 + var useFilteredVariables = (searchValue, propTypeKey) => {
869 + const baseVariables = usePropVariables(propTypeKey);
870 + const typeFilteredVariables = useVariableSelectionFilter(baseVariables);
871 + const searchFilteredVariables = filterBySearch(typeFilteredVariables, searchValue);
872 + return {
873 + list: searchFilteredVariables.sort((a, b) => {
874 + return (a.order ?? Number.MAX_SAFE_INTEGER) - (b.order ?? Number.MAX_SAFE_INTEGER);
875 + }),
876 + hasMatches: searchFilteredVariables.length > 0,
877 + isSourceNotEmpty: typeFilteredVariables.length > 0,
878 + hasNoCompatibleVariables: baseVariables.length > 0 && typeFilteredVariables.length === 0
879 + };
880 + };
881 + var useVariableSelectionFilter = (variables) => {
882 + const { selectionFilter } = useVariableType();
883 + const { propType } = (0, _elementor_editor_controls.useBoundProp)();
884 + return selectionFilter ? selectionFilter(variables, propType) : variables;
885 + };
886 + var usePropVariables = (propKey) => {
887 + return (0, react.useMemo)(() => normalizeVariables(propKey), [propKey]);
888 + };
889 + var getMatchingTypes = (propKey) => {
890 + const matchingTypes = [];
891 + const allTypes = getVariableTypes();
892 + const variableType = getVariableType(propKey);
893 + Object.entries(allTypes).forEach(([key, typeOptions]) => {
894 + if (variableType.variableType === typeOptions.variableType) matchingTypes.push(key);
895 + });
896 + return matchingTypes;
897 + };
898 + var normalizeVariables = (propKey) => {
899 + const variables = getVariables(false);
900 + const matchingTypes = getMatchingTypes(propKey);
901 + return variablesToList(variables).filter((variable) => matchingTypes.includes(variable.type)).map(toNormalizedVariable);
902 + };
903 + var extractId = ({ id }) => id;
904 + var createVariable = (newVariable, options) => {
905 + return service.create(newVariable, options).then(extractId);
906 + };
907 + var updateVariable = (updateId, { value, label, type }, options) => {
908 + return service.update(updateId, {
909 + value,
910 + label,
911 + type
912 + }, options).then(extractId);
913 + };
914 + var deleteVariable = (deleteId) => {
915 + return service.delete(deleteId).then(extractId);
916 + };
917 + var restoreVariable = (restoreId, label, value, type) => {
918 + return service.restore(restoreId, label, value, type).then(extractId);
919 + };
920 +
921 +//#endregion
922 +//#region packages/packages/core/editor-variables/src/utils/duplicate-label.ts
923 + var COPY_SUFFIX = "-Copy";
924 + var trimToFit = (base, suffix) => {
925 + const combined = base + suffix;
926 + if (combined.length <= 50) return combined;
927 + return base.slice(0, 50 - suffix.length) + suffix;
928 + };
929 + var generateDuplicateLabel = (originalLabel, existingLabels) => {
930 + const labelsSet = new Set(existingLabels);
931 + const firstCandidate = trimToFit(originalLabel, COPY_SUFFIX);
932 + if (!labelsSet.has(firstCandidate)) return firstCandidate;
933 + for (let i = 2; i <= labelsSet.size + 1; i++) {
934 + const candidate = trimToFit(originalLabel, `${COPY_SUFFIX}-${i}`);
935 + if (!labelsSet.has(candidate)) return candidate;
936 + }
937 + return firstCandidate;
938 + };
939 +
940 +//#endregion
941 +//#region packages/packages/core/editor-variables/src/components/variables-manager/hooks/use-variables-manager-state.ts
942 + var useVariablesManagerState = () => {
943 + const [variables, setVariables] = (0, react.useState)(() => getVariables(false));
944 + const [deletedVariables, setDeletedVariables] = (0, react.useState)([]);
945 + const [isSaveDisabled, setIsSaveDisabled] = (0, react.useState)(false);
946 + const [isDirty, setIsDirty] = (0, react.useState)(false);
947 + const [isSaving, setIsSaving] = (0, react.useState)(false);
948 + const [searchValue, setSearchValue] = (0, react.useState)("");
949 + (0, react.useEffect)(() => {
950 + const handleStorageUpdated = () => {
951 + setVariables(getVariables(false));
952 + setDeletedVariables([]);
953 + setIsDirty(false);
954 + };
955 + window.addEventListener(STORAGE_UPDATED_EVENT, handleStorageUpdated);
956 + return () => {
957 + window.removeEventListener(STORAGE_UPDATED_EVENT, handleStorageUpdated);
958 + };
959 + }, []);
960 + const handleOnChange = (0, react.useCallback)((newVariables) => {
961 + if (Object.entries(newVariables).some(([id, newVar]) => {
962 + const existingVar = variables[id];
963 + if (!existingVar) return true;
964 + return existingVar.label !== newVar.label || existingVar.value !== newVar.value || existingVar.order !== newVar.order || existingVar.type !== newVar.type || (existingVar.sync_to_v3 ?? false) !== (newVar.sync_to_v3 ?? false);
965 + })) {
966 + setVariables({
967 + ...variables,
968 + ...newVariables
969 + });
970 + setIsDirty(true);
971 + }
972 + }, [variables]);
973 + const createVariable = (0, react.useCallback)((type, defaultName, defaultValue) => {
974 + const newId = generateTempId();
975 + const newVariable = {
976 + id: newId,
977 + label: defaultName.trim(),
978 + value: defaultValue.trim(),
979 + type
980 + };
981 + setVariables((prev) => ({
982 + ...prev,
983 + [newId]: newVariable
984 + }));
985 + setIsDirty(true);
986 + return newId;
987 + }, []);
988 + const duplicateVariable = (0, react.useCallback)((sourceId) => {
989 + const newId = generateTempId();
990 + setVariables((prev) => {
991 + const source = prev[sourceId];
992 + if (!source || source.deleted) return prev;
993 + const existingLabels = Object.values(prev).filter((v) => !v.deleted).map((v) => v.label);
994 + return {
995 + ...prev,
996 + [newId]: {
997 + label: generateDuplicateLabel(source.label, existingLabels),
998 + value: source.value,
999 + type: source.type
1000 + }
1001 + };
1002 + });
1003 + setIsDirty(true);
1004 + return newId;
1005 + }, []);
1006 + const handleDeleteVariable = (0, react.useCallback)((itemId) => {
1007 + setDeletedVariables((prev) => [...prev, itemId]);
1008 + setVariables((prev) => ({
1009 + ...prev,
1010 + [itemId]: {
1011 + ...prev[itemId],
1012 + deleted: true
1013 + }
1014 + }));
1015 + setIsDirty(true);
1016 + }, []);
1017 + const handleStartSync = (0, react.useCallback)((itemId) => {
1018 + setVariables((prev) => ({
1019 + ...prev,
1020 + [itemId]: {
1021 + ...prev[itemId],
1022 + sync_to_v3: true
1023 + }
1024 + }));
1025 + setIsDirty(true);
1026 + }, []);
1027 + const handleStopSync = (0, react.useCallback)((itemId) => {
1028 + setVariables((prev) => ({
1029 + ...prev,
1030 + [itemId]: {
1031 + ...prev[itemId],
1032 + sync_to_v3: false
1033 + }
1034 + }));
1035 + setIsDirty(true);
1036 + }, []);
1037 + const handleSearch = (searchTerm) => {
1038 + setSearchValue(searchTerm);
1039 + };
1040 + const handleSave = (0, react.useCallback)(async () => {
1041 + const originalVariables = getVariables(false);
1042 + setIsSaving(true);
1043 + const result = await service.batchSave(originalVariables, variables, deletedVariables);
1044 + if (result.success) {
1045 + await service.load();
1046 + const updatedVariables = service.variables();
1047 + setVariables(updatedVariables);
1048 + setDeletedVariables([]);
1049 + setIsDirty(false);
1050 + }
1051 + return { success: result.success };
1052 + }, [variables, deletedVariables]);
1053 + return {
1054 + variables: (0, react.useCallback)(() => {
1055 + const searchFiltered = filterBySearch(applySelectionFilters(variablesToList(variables).filter((v) => !v.deleted), getVariableTypes()), searchValue);
1056 + return Object.fromEntries(searchFiltered.map(({ key, ...rest }) => [key, rest]));
1057 + }, [variables, searchValue])(),
1058 + deletedVariables,
1059 + isDirty,
1060 + isSaveDisabled,
1061 + handleOnChange,
1062 + createVariable,
1063 + duplicateVariable,
1064 + handleDeleteVariable,
1065 + handleStartSync,
1066 + handleStopSync,
1067 + handleSave,
1068 + isSaving,
1069 + handleSearch,
1070 + searchValue,
1071 + setIsSaving,
1072 + setIsSaveDisabled
1073 + };
1074 + };
1075 +
1076 +//#endregion
1077 +//#region packages/packages/core/editor-variables/src/hooks/use-quota-permissions.ts
1078 + var useQuotaPermissions = (variableType) => {
1079 + const quotaConfig = {
1080 + ...window.ElementorVariablesQuotaConfig ?? {},
1081 + ...window.ElementorVariablesQuotaConfigExtended ?? {}
1082 + };
1083 + const hasLegacySupport = quotaConfig[variableType] === void 0 && window.elementorPro;
1084 + const limit = quotaConfig[variableType] || 0;
1085 + const hasPermission = hasLegacySupport || limit > 0;
1086 + return {
1087 + canAdd: () => hasPermission,
1088 + canEdit: () => hasPermission
1089 + };
1090 + };
1091 +
1092 +//#endregion
1093 +//#region packages/packages/core/editor-variables/src/components/ui/variable-promotion-chip.tsx
1094 + var VariablePromotionChip = (0, react.forwardRef)(({ variableType, upgradeUrl, trackingData }, ref) => {
1095 + const [isOpen, setIsOpen] = (0, react.useState)(false);
1096 + (0, _elementor_editor_ui.useCanvasClickHandler)(isOpen, () => setIsOpen(false));
1097 + const toggle = (0, react.useCallback)(() => {
1098 + setIsOpen((prev) => {
1099 + if (!prev) (0, _elementor_editor_controls.trackViewPromotion)(trackingData);
1100 + return !prev;
1101 + });
1102 + }, [trackingData]);
1103 + (0, react.useImperativeHandle)(ref, () => ({ toggle }), [toggle]);
1104 + const title = (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("%s variables", "elementor"), (0, _elementor_utils.capitalize)(variableType));
1105 + const content = (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("Upgrade to continue creating and editing %s variables.", "elementor"), variableType);
1106 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.PromotionPopover, {
1107 + open: isOpen,
1108 + title,
1109 + content,
1110 + ctaText: (0, _wordpress_i18n.__)("Upgrade now", "elementor"),
1111 + ctaUrl: upgradeUrl,
1112 + onClose: (e) => {
1113 + e.stopPropagation();
1114 + setIsOpen(false);
1115 + },
1116 + onCtaClick: () => (0, _elementor_editor_controls.trackUpgradePromotionClick)(trackingData)
1117 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
1118 + onClick: (e) => {
1119 + e.stopPropagation();
1120 + toggle();
1121 + },
1122 + sx: {
1123 + cursor: "pointer",
1124 + display: "inline-flex"
1125 + }
1126 + }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PromotionChip, null)));
1127 + });
1128 +
1129 +//#endregion
1130 +//#region packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-create-menu.tsx
1131 + var TRACKING_DATA$1 = {
1132 + target_name: "variables_manager",
1133 + target_location: "variables_manager",
1134 + location_l1: "create variable menu"
1135 + };
1136 + var SIZE$6 = "tiny";
1137 + var VariableManagerCreateMenu = ({ variables, onCreate, menuState, outlinedTrigger = false }) => {
1138 + const buttonRef = (0, react.useRef)(null);
1139 + const variableTypes = getVariableTypes();
1140 + const menuOptionConfigs = (0, react.useMemo)(() => Object.entries(variableTypes).filter(([, variable]) => !!variable.defaultValue).map(([key, variable]) => ({
1141 + key,
1142 + propTypeKey: variable.propTypeUtil.key,
1143 + variableType: variable.variableType,
1144 + defaultValue: variable.defaultValue || "",
1145 + icon: variable.icon
1146 + })), [variableTypes]);
1147 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
1148 + ...(0, _elementor_ui.bindTrigger)(menuState),
1149 + ref: buttonRef,
1150 + size: SIZE$6,
1151 + variant: outlinedTrigger ? "outlined" : void 0,
1152 + "aria-label": (0, _wordpress_i18n.__)("Add variable", "elementor")
1153 + }, /* @__PURE__ */ react.createElement(_elementor_icons.PlusIcon, { fontSize: SIZE$6 })), /* @__PURE__ */ react.createElement(_elementor_ui.Menu, {
1154 + disablePortal: true,
1155 + MenuListProps: { dense: true },
1156 + PaperProps: { elevation: 6 },
1157 + ...(0, _elementor_ui.bindMenu)(menuState),
1158 + anchorEl: buttonRef.current,
1159 + anchorOrigin: {
1160 + vertical: "bottom",
1161 + horizontal: "right"
1162 + },
1163 + transformOrigin: {
1164 + vertical: "top",
1165 + horizontal: "right"
1166 + },
1167 + "data-testid": "variable-manager-create-menu"
1168 + }, menuOptionConfigs.map((config) => /* @__PURE__ */ react.createElement(MenuOption, {
1169 + key: config.key,
1170 + config,
1171 + variables,
1172 + onCreate,
1173 + onClose: menuState.close
1174 + }))));
1175 + };
1176 + var MenuOption = ({ config, variables, onCreate, onClose }) => {
1177 + const promotionRef = (0, react.useRef)(null);
1178 + const userQuotaPermissions = useQuotaPermissions(config.propTypeKey);
1179 + const displayName = (0, _elementor_utils.capitalize)(config.variableType);
1180 + const isDisabled = !userQuotaPermissions.canAdd();
1181 + const handleClick = () => {
1182 + if (isDisabled) {
1183 + promotionRef.current?.toggle();
1184 + return;
1185 + }
1186 + const defaultName = getDefaultName(variables, config.variableType);
1187 + onCreate(config.key, defaultName, config.defaultValue);
1188 + trackVariablesManagerEvent({
1189 + action: "add",
1190 + varType: config.variableType
1191 + });
1192 + onClose();
1193 + };
1194 + return /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, {
1195 + onClick: handleClick,
1196 + sx: {
1197 + gap: 1.5,
1198 + cursor: "pointer"
1199 + }
1200 + }, (0, react.createElement)(config.icon, {
1201 + fontSize: SIZE$6,
1202 + color: isDisabled ? "disabled" : "action"
1203 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
1204 + variant: "caption",
1205 + color: isDisabled ? "text.disabled" : "text.primary"
1206 + }, displayName), isDisabled && /* @__PURE__ */ react.createElement(VariablePromotionChip, {
1207 + variableType: config.variableType,
1208 + upgradeUrl: `https://go.elementor.com/go-pro-manager-${config.variableType}-variable/`,
1209 + ref: promotionRef,
1210 + trackingData: TRACKING_DATA$1
1211 + }));
1212 + };
1213 + var getDefaultName = (variables, baseName) => {
1214 + const pattern = new RegExp(`^${baseName}-(\\d+)$`, "i");
1215 + const takenNumbers = /* @__PURE__ */ new Set();
1216 + Object.values(variables).forEach((variable) => {
1217 + const match = variable.label.match(pattern);
1218 + if (match) takenNumbers.add(parseInt(match[1], 10));
1219 + });
1220 + let counter = 1;
1221 + while (takenNumbers.has(counter)) counter++;
1222 + return `${baseName}-${counter}`;
1223 + };
1224 +
1225 +//#endregion
1226 +//#region packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-cell.tsx
1227 + var VariableTableCell = ({ children, isHeader, width, maxWidth, align, noPadding, sx }) => {
1228 + const baseSx = {
1229 + maxWidth: maxWidth ?? 150,
1230 + cursor: "initial",
1231 + typography: "caption",
1232 + ...isHeader && {
1233 + color: "text.primary",
1234 + fontWeight: "bold"
1235 + },
1236 + ...isHeader && !noPadding && { padding: "10px 16px" },
1237 + ...width && { width },
1238 + ...sx
1239 + };
1240 + return /* @__PURE__ */ react.createElement(_elementor_ui.TableCell, {
1241 + size: "small",
1242 + padding: noPadding ? "none" : void 0,
1243 + align,
1244 + sx: baseSx
1245 + }, children);
1246 + };
1247 +
1248 +//#endregion
1249 +//#region packages/packages/core/editor-variables/src/components/fields/label-field.tsx
1250 + function isLabelEqual(a, b) {
1251 + return a.trim().toLowerCase() === b.trim().toLowerCase();
1252 + }
1253 + var useLabelError = (initialError) => {
1254 + const [error, setError] = (0, react.useState)(initialError ?? {
1255 + value: "",
1256 + message: ""
1257 + });
1258 + return {
1259 + labelFieldError: error,
1260 + setLabelFieldError: setError
1261 + };
1262 + };
1263 + var LabelField = ({ value, error, onChange, id, onErrorChange, size = "tiny", focusOnShow = false, selectOnShow = false, showWarningInfotip = false, variables, onKeyDown }) => {
1264 + const [label, setLabel] = (0, react.useState)(value);
1265 + const [errorMessage, setErrorMessage] = (0, react.useState)("");
1266 + const fieldRef = (0, react.useRef)(null);
1267 + const handleChange = (newValue) => {
1268 + setLabel(newValue);
1269 + const errorMsg2 = validateLabel(newValue, variables);
1270 + setErrorMessage(errorMsg2);
1271 + onErrorChange?.(errorMsg2);
1272 + onChange(isLabelEqual(newValue, error?.value ?? "") || errorMsg2 ? "" : newValue);
1273 + };
1274 + let errorMsg = errorMessage;
1275 + if (isLabelEqual(label, error?.value ?? "") && error?.message) errorMsg = error.message;
1276 + const hintMsg = !errorMsg ? labelHint(label) : "";
1277 + const textField = /* @__PURE__ */ react.createElement(_elementor_ui.TextField, {
1278 + ref: fieldRef,
1279 + id,
1280 + size,
1281 + fullWidth: true,
1282 + value: label,
1283 + error: !!errorMsg,
1284 + onChange: (e) => handleChange(e.target.value),
1285 + inputProps: {
1286 + maxLength: 50,
1287 + ...selectOnShow && { onFocus: (e) => e.target.select() },
1288 + "aria-label": "Name",
1289 + onKeyDown
1290 + },
1291 + autoFocus: focusOnShow
1292 + });
1293 + if (showWarningInfotip) {
1294 + const tooltipWidth = Math.max(240, fieldRef.current?.getBoundingClientRect().width ?? 240);
1295 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.WarningInfotip, {
1296 + open: Boolean(errorMsg || hintMsg),
1297 + text: errorMsg || hintMsg,
1298 + placement: "bottom-start",
1299 + width: tooltipWidth,
1300 + offset: [0, -15],
1301 + ...hintMsg && { hasError: false }
1302 + }, textField);
1303 + }
1304 + return textField;
1305 + };
1306 +
1307 +//#endregion
1308 +//#region packages/packages/core/editor-variables/src/components/variables-manager/variable-editable-cell.tsx
1309 + var VariableEditableCell = react.memo(({ initialValue, children, editableElement, onChange, prefixElement, autoEdit = false, onRowRef, onAutoEditComplete, gap = 1, fieldType, disabled = false }) => {
1310 + const [value, setValue] = (0, react.useState)(initialValue);
1311 + const [isEditing, setIsEditing] = (0, react.useState)(false);
1312 + const { labelFieldError, setLabelFieldError } = useLabelError();
1313 + const [valueFieldError, setValueFieldError] = (0, react.useState)("");
1314 + const rowRef = (0, react.useRef)(null);
1315 + const handleSave = (0, react.useCallback)(() => {
1316 + if (!(fieldType === "label" && labelFieldError?.message || fieldType === "value" && valueFieldError)) onChange(value);
1317 + setIsEditing(false);
1318 + }, [
1319 + value,
1320 + onChange,
1321 + fieldType,
1322 + labelFieldError,
1323 + valueFieldError
1324 + ]);
1325 + (0, react.useEffect)(() => {
1326 + onRowRef?.(rowRef?.current);
1327 + }, [onRowRef]);
1328 + (0, react.useEffect)(() => {
1329 + if (autoEdit && !isEditing && !disabled) {
1330 + setIsEditing(true);
1331 + onAutoEditComplete?.();
1332 + }
1333 + }, [
1334 + autoEdit,
1335 + isEditing,
1336 + onAutoEditComplete,
1337 + disabled
1338 + ]);
1339 + const handleDoubleClick = () => {
1340 + if (disabled) return;
1341 + setIsEditing(true);
1342 + };
1343 + const handleKeyDown = (event) => {
1344 + if (disabled) return;
1345 + if (event.key === "Enter") handleSave();
1346 + else if (event.key === "Escape") setIsEditing(false);
1347 + if (event.key === " " && !isEditing) {
1348 + event.preventDefault();
1349 + setIsEditing(true);
1350 + }
1351 + };
1352 + const handleChange = (0, react.useCallback)((newValue) => {
1353 + setValue(newValue);
1354 + }, []);
1355 + const handleValidationChange = (0, react.useCallback)((errorMsg) => {
1356 + if (fieldType === "label") setLabelFieldError({
1357 + value,
1358 + message: errorMsg
1359 + });
1360 + else setValueFieldError(errorMsg);
1361 + }, [
1362 + fieldType,
1363 + value,
1364 + setLabelFieldError,
1365 + setValueFieldError
1366 + ]);
1367 + let currentError;
1368 + if (fieldType === "label") currentError = labelFieldError;
1369 + else if (fieldType === "value") currentError = {
1370 + value,
1371 + message: valueFieldError
1372 + };
1373 + const editableContent = editableElement({
1374 + value,
1375 + onChange: handleChange,
1376 + onValidationChange: handleValidationChange,
1377 + error: currentError
1378 + });
1379 + if (isEditing) return /* @__PURE__ */ react.createElement(_elementor_ui.ClickAwayListener, { onClickAway: handleSave }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1380 + ref: rowRef,
1381 + direction: "row",
1382 + alignItems: "center",
1383 + gap,
1384 + onDoubleClick: handleDoubleClick,
1385 + onKeyDown: handleKeyDown,
1386 + tabIndex: 0,
1387 + role: "button",
1388 + "aria-label": "Double click or press Space to edit"
1389 + }, prefixElement, editableContent));
1390 + return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1391 + ref: rowRef,
1392 + direction: "row",
1393 + alignItems: "center",
1394 + gap,
1395 + onDoubleClick: handleDoubleClick,
1396 + onKeyDown: handleKeyDown,
1397 + tabIndex: disabled ? -1 : 0,
1398 + role: "button",
1399 + "aria-label": disabled ? "" : "Double click or press Space to edit"
1400 + }, prefixElement, children);
1401 + });
1402 +
1403 +//#endregion
1404 +//#region packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-edit-menu.tsx
1405 + var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
1406 + const menuState = (0, _elementor_ui.usePopupState)({ variant: "popover" });
1407 + const triggerProps = (0, _elementor_ui.bindTrigger)(menuState);
1408 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
1409 + ...triggerProps,
1410 + disabled,
1411 + size: "tiny",
1412 + onClick: (e) => {
1413 + e.stopPropagation();
1414 + triggerProps.onClick?.(e);
1415 + }
1416 + }, /* @__PURE__ */ react.createElement(_elementor_icons.DotsVerticalIcon, { fontSize: "tiny" })), /* @__PURE__ */ react.createElement(_elementor_ui.Menu, {
1417 + disablePortal: true,
1418 + MenuListProps: { dense: true },
1419 + PaperProps: { elevation: 6 },
1420 + ...(0, _elementor_ui.bindMenu)(menuState),
1421 + anchorEl: menuState.anchorEl,
1422 + anchorOrigin: {
1423 + vertical: "bottom",
1424 + horizontal: "right"
1425 + },
1426 + transformOrigin: {
1427 + vertical: "top",
1428 + horizontal: "right"
1429 + },
1430 + open: menuState.isOpen,
1431 + onClose: menuState.close
1432 + }, menuActions.map((action) => /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, {
1433 + key: action.name,
1434 + onClick: (e) => {
1435 + e.stopPropagation();
1436 + action.onClick?.(itemId);
1437 + menuState.close();
1438 + },
1439 + sx: {
1440 + color: action.color,
1441 + gap: 1
1442 + }
1443 + }, action.icon && (0, react.createElement)(action.icon, { fontSize: "inherit" }), " ", action.name))));
1444 + };
1445 +
1446 +//#endregion
1447 +//#region packages/packages/core/editor-variables/src/components/variables-manager/ui/variable-table-row.tsx
1448 + var TRACKING_DATA = {
1449 + target_name: "variables_manager",
1450 + target_location: "variables_manager"
1451 + };
1452 + var VariableRow = (props) => {
1453 + const { row, variables, handleOnChange, autoEditVariableId, onAutoEditComplete, onFieldError, menuActions, handleRowRef, itemProps, showDropIndication, triggerProps, itemStyle, triggerStyle, isDragged, dropPosition, setTriggerRef, isSorting } = props;
1454 + const promotionRef = (0, react.useRef)(null);
1455 + const isDisabled = !useQuotaPermissions(row.type).canEdit();
1456 + const showIndicationBefore = showDropIndication && dropPosition === "before";
1457 + const showIndicationAfter = showDropIndication && dropPosition === "after";
1458 + return /* @__PURE__ */ react.createElement(_elementor_ui.TableRow, {
1459 + ...itemProps,
1460 + ref: itemProps.ref,
1461 + selected: isDragged,
1462 + sx: {
1463 + ...isDisabled && { "& td, & th": { color: "text.disabled" } },
1464 + ...showIndicationBefore && { "& td, & th": {
1465 + borderTop: "2px solid",
1466 + borderTopColor: "primary.main"
1467 + } },
1468 + ...showIndicationAfter && { "& td, & th": {
1469 + borderBottom: "2px solid",
1470 + borderBottomColor: "primary.main"
1471 + } },
1472 + "&:hover, &:focus-within": {
1473 + backgroundColor: "action.hover",
1474 + "& [role=\"toolbar\"], & [draggable]": { opacity: 1 }
1475 + },
1476 + "& [role=\"toolbar\"], & [draggable]": { opacity: 0 }
1477 + },
1478 + style: {
1479 + ...itemStyle,
1480 + ...triggerStyle
1481 + },
1482 + onClick: () => {
1483 + if (isDisabled) promotionRef.current?.toggle();
1484 + }
1485 + }, /* @__PURE__ */ react.createElement(VariableTableCell, {
1486 + noPadding: true,
1487 + width: 10,
1488 + maxWidth: 10
1489 + }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
1490 + size: "small",
1491 + ref: setTriggerRef,
1492 + ...triggerProps,
1493 + disabled: isSorting,
1494 + draggable: true
1495 + }, /* @__PURE__ */ react.createElement(_elementor_icons.GripVerticalIcon, { fontSize: "inherit" }))), /* @__PURE__ */ react.createElement(VariableTableCell, null, /* @__PURE__ */ react.createElement(VariableEditableCell, {
1496 + initialValue: row.name,
1497 + onChange: (value) => {
1498 + if (value !== row.name && !isDisabled) handleOnChange({
1499 + ...variables,
1500 + [row.id]: {
1501 + ...variables[row.id],
1502 + label: value
1503 + }
1504 + });
1505 + },
1506 + prefixElement: (0, react.createElement)(row.icon, {
1507 + fontSize: "inherit",
1508 + color: isDisabled ? "disabled" : "inherit"
1509 + }),
1510 + editableElement: ({ value, onChange, onValidationChange, error }) => /* @__PURE__ */ react.createElement(LabelField, {
1511 + id: "variable-label-" + row.id,
1512 + size: "tiny",
1513 + value,
1514 + onChange,
1515 + onErrorChange: (errorMsg) => {
1516 + onValidationChange?.(errorMsg);
1517 + onFieldError?.(!!errorMsg);
1518 + },
1519 + error,
1520 + focusOnShow: true,
1521 + selectOnShow: autoEditVariableId === row.id,
1522 + showWarningInfotip: true,
1523 + variables
1524 + }),
1525 + autoEdit: autoEditVariableId === row.id && !isDisabled,
1526 + onRowRef: handleRowRef(row.id),
1527 + onAutoEditComplete: autoEditVariableId === row.id ? onAutoEditComplete : void 0,
1528 + fieldType: "label",
1529 + disabled: isDisabled
1530 + }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
1531 + title: row.name,
1532 + sx: { border: "4px solid transparent" }
1533 + }, row.name))), /* @__PURE__ */ react.createElement(VariableTableCell, null, /* @__PURE__ */ react.createElement(VariableEditableCell, {
1534 + initialValue: row.value,
1535 + onChange: (value) => {
1536 + if (value !== row.value && !isDisabled) handleOnChange({
1537 + ...variables,
1538 + [row.id]: {
1539 + ...variables[row.id],
1540 + value
1541 + }
1542 + });
1543 + },
1544 + editableElement: ({ value, onChange, onValidationChange, error }) => row.valueField?.({
1545 + value,
1546 + onChange,
1547 + onPropTypeKeyChange: (type) => {
1548 + if (!isDisabled && type !== row.type) handleOnChange({
1549 + ...variables,
1550 + [row.id]: {
1551 + ...variables[row.id],
1552 + type
1553 + }
1554 + });
1555 + },
1556 + propTypeKey: row.type,
1557 + onValidationChange: (errorMsg) => {
1558 + onValidationChange?.(errorMsg);
1559 + onFieldError?.(!!errorMsg);
1560 + },
1561 + error
1562 + }) ?? /* @__PURE__ */ react.createElement(react.Fragment, null),
1563 + onRowRef: handleRowRef(row.id),
1564 + gap: .25,
1565 + fieldType: "value",
1566 + disabled: isDisabled
1567 + }, row.startIcon && row.startIcon({ value: row.value }), /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
1568 + title: row.value,
1569 + sx: {
1570 + border: "4px solid transparent",
1571 + lineHeight: "1",
1572 + pt: .25
1573 + }
1574 + }, row.value))), /* @__PURE__ */ react.createElement(VariableTableCell, {
1575 + align: "right",
1576 + noPadding: true,
1577 + width: 16,
1578 + maxWidth: 16,
1579 + sx: { paddingInlineEnd: 1 }
1580 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1581 + role: "toolbar",
1582 + direction: "row",
1583 + justifyContent: "flex-end",
1584 + alignItems: "center"
1585 + }, isDisabled && /* @__PURE__ */ react.createElement(VariablePromotionChip, {
1586 + variableType: row.variableType,
1587 + upgradeUrl: `https://go.elementor.com/renew-license-manager-${row.variableType}-variable`,
1588 + ref: promotionRef,
1589 + trackingData: TRACKING_DATA
1590 + }), /* @__PURE__ */ react.createElement(VariableEditMenu, {
1591 + menuActions: menuActions(row.id),
1592 + disabled: isSorting,
1593 + itemId: row.id
1594 + }))));
1595 + };
1596 +
1597 +//#endregion
1598 +//#region packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-table.tsx
1599 + var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange, autoEditVariableId, onAutoEditComplete, onFieldError }) => {
1600 + const tableContainerRef = (0, react.useRef)(null);
1601 + const variableRowRefs = (0, react.useRef)(/* @__PURE__ */ new Map());
1602 + (0, react.useEffect)(() => {
1603 + if (autoEditVariableId && tableContainerRef.current) {
1604 + const rowElement = variableRowRefs.current.get(autoEditVariableId);
1605 + if (rowElement) setTimeout(() => {
1606 + rowElement.scrollIntoView({
1607 + behavior: "smooth",
1608 + block: "center",
1609 + inline: "nearest"
1610 + });
1611 + }, 100);
1612 + }
1613 + }, [autoEditVariableId]);
1614 + const handleRowRef = (id) => (ref) => {
1615 + if (ref) variableRowRefs.current.set(id, ref);
1616 + else variableRowRefs.current.delete(id);
1617 + };
1618 + const ids = Object.keys(variables).sort(sortVariablesOrder(variables));
1619 + const rows = ids.map((id) => {
1620 + const variable = variables[id];
1621 + const variableType = getVariableType(variable.type);
1622 + if (!variableType) return null;
1623 + return {
1624 + id,
1625 + type: variable.type,
1626 + name: variable.label,
1627 + value: variable.value,
1628 + ...variableType
1629 + };
1630 + }).filter(Boolean);
1631 + const tableSX = {
1632 + minWidth: 250,
1633 + tableLayout: "fixed"
1634 + };
1635 + const handleReorder = (newIds) => {
1636 + const updatedVariables = { ...variables };
1637 + newIds.forEach((id, index) => {
1638 + const current = updatedVariables[id];
1639 + if (!current) return;
1640 + updatedVariables[id] = Object.assign({}, current, { order: index + 1 });
1641 + });
1642 + handleOnChange(updatedVariables);
1643 + };
1644 + return /* @__PURE__ */ react.createElement(_elementor_ui.TableContainer, {
1645 + ref: tableContainerRef,
1646 + sx: { overflow: "initial" }
1647 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Table, {
1648 + sx: tableSX,
1649 + "aria-label": "Variables manager list with drag and drop reordering",
1650 + stickyHeader: true
1651 + }, /* @__PURE__ */ react.createElement(_elementor_ui.TableHead, null, /* @__PURE__ */ react.createElement(_elementor_ui.TableRow, null, /* @__PURE__ */ react.createElement(VariableTableCell, {
1652 + isHeader: true,
1653 + noPadding: true,
1654 + width: 10,
1655 + maxWidth: 10
1656 + }), /* @__PURE__ */ react.createElement(VariableTableCell, { isHeader: true }, (0, _wordpress_i18n.__)("Name", "elementor")), /* @__PURE__ */ react.createElement(VariableTableCell, { isHeader: true }, (0, _wordpress_i18n.__)("Value", "elementor")), /* @__PURE__ */ react.createElement(VariableTableCell, {
1657 + isHeader: true,
1658 + noPadding: true,
1659 + width: 16,
1660 + maxWidth: 16
1661 + }))), /* @__PURE__ */ react.createElement(_elementor_ui.TableBody, null, /* @__PURE__ */ react.createElement(_elementor_ui.UnstableSortableProvider, {
1662 + value: ids,
1663 + onChange: handleReorder,
1664 + variant: "static",
1665 + restrictAxis: true,
1666 + dragOverlay: ({ children: dragOverlayChildren, ...dragOverlayProps }) => /* @__PURE__ */ react.createElement(_elementor_ui.Table, {
1667 + sx: tableSX,
1668 + ...dragOverlayProps
1669 + }, /* @__PURE__ */ react.createElement(_elementor_ui.TableBody, null, dragOverlayChildren))
1670 + }, rows.map((row) => /* @__PURE__ */ react.createElement(_elementor_ui.UnstableSortableItem, {
1671 + key: row.id,
1672 + id: row.id,
1673 + render: (props) => /* @__PURE__ */ react.createElement(VariableRow, {
1674 + ...props,
1675 + row,
1676 + variables,
1677 + handleOnChange,
1678 + autoEditVariableId,
1679 + onAutoEditComplete,
1680 + onFieldError,
1681 + menuActions,
1682 + handleRowRef
1683 + })
1684 + }))))));
1685 + };
1686 + function sortVariablesOrder(variables) {
1687 + return (a, b) => {
1688 + return (variables[a]?.order ?? Number.MAX_SAFE_INTEGER) - (variables[b]?.order ?? Number.MAX_SAFE_INTEGER);
1689 + };
1690 + }
1691 +
1692 +//#endregion
1693 +//#region packages/packages/core/editor-variables/src/components/variables-manager/variables-manager-panel.tsx
1694 + var STOP_SYNC_MESSAGE_KEY = "stop-sync-variable";
1695 + function VariablesManagerPanelEmbedded({ onRequestClose, onExposeCloseAttempt }) {
1696 + return /* @__PURE__ */ react.createElement(VariablesManagerPanelContent, {
1697 + onRequestClose,
1698 + onExposeCloseAttempt
1699 + });
1700 + }
1701 + function VariablesManagerPanelContent({ onRequestClose, onExposeCloseAttempt }) {
1702 + const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, _elementor_editor_ui.useDialog)();
1703 + const [isStopSyncSuppressed] = (0, _elementor_editor_current_user.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
1704 + const createMenuState = (0, _elementor_ui.usePopupState)({ variant: "popover" });
1705 + const { variables, isDirty, searchValue, isSaveDisabled, handleOnChange, createVariable, duplicateVariable, handleDeleteVariable, handleStartSync: startSyncFromState, handleStopSync: stopSyncFromState, handleSave, isSaving, handleSearch, setIsSaving, setIsSaveDisabled } = useVariablesManagerState();
1706 + const { autoEditVariableId, startAutoEdit, handleAutoEditComplete } = useAutoEdit();
1707 + const { createNavigationCallback, resetNavigation } = useErrorNavigation();
1708 + const [deleteConfirmation, setDeleteConfirmation] = (0, react.useState)(null);
1709 + const [stopSyncConfirmation, setStopSyncConfirmation] = (0, react.useState)(null);
1710 + const [serverError, setServerError] = (0, react.useState)(null);
1711 + usePreventUnload(isDirty);
1712 + const handleClosePanel = (0, react.useCallback)(() => {
1713 + if (isDirty) {
1714 + openSaveChangesDialog();
1715 + return;
1716 + }
1717 + onRequestClose();
1718 + }, [
1719 + isDirty,
1720 + openSaveChangesDialog,
1721 + onRequestClose
1722 + ]);
1723 + (0, react.useEffect)(() => {
1724 + if (!onExposeCloseAttempt) return;
1725 + onExposeCloseAttempt(() => handleClosePanel());
1726 + return () => onExposeCloseAttempt(null);
1727 + }, [onExposeCloseAttempt, handleClosePanel]);
1728 + const handleCreateVariable = (0, react.useCallback)((type, defaultName, defaultValue) => {
1729 + const newId = createVariable(type, defaultName, defaultValue);
1730 + if (newId) startAutoEdit(newId);
1731 + }, [createVariable, startAutoEdit]);
1732 + const handleSaveClick = async () => {
1733 + try {
1734 + setServerError(null);
1735 + resetNavigation();
1736 + const result = await handleSave();
1737 + trackVariablesManagerEvent({ action: "saveChanges" });
1738 + return result;
1739 + } catch (error) {
1740 + const mappedError = mapServerError(error);
1741 + const duplicatedIds = mappedError?.action?.data?.duplicatedIds;
1742 + if (mappedError && "label" === mappedError.field) {
1743 + if (duplicatedIds && mappedError.action) mappedError.action.callback = createNavigationCallback(duplicatedIds, startAutoEdit, () => {
1744 + setIsSaveDisabled(false);
1745 + });
1746 + setServerError(mappedError);
1747 + setIsSaveDisabled(true);
1748 + resetNavigation();
1749 + }
1750 + return {
1751 + success: false,
1752 + error: mappedError
1753 + };
1754 + } finally {
1755 + setIsSaving(false);
1756 + }
1757 + };
1758 + const handleDeleteVariableWithConfirmation = (0, react.useCallback)((itemId) => {
1759 + handleDeleteVariable(itemId);
1760 + setDeleteConfirmation(null);
1761 + }, [handleDeleteVariable]);
1762 + const commitStopSync = (0, react.useCallback)((itemId) => {
1763 + stopSyncFromState(itemId);
1764 + const variable = variables[itemId];
1765 + if (variable) trackVariableSyncToV3({
1766 + variableLabel: variable.label,
1767 + action: "unsync"
1768 + });
1769 + }, [stopSyncFromState, variables]);
1770 + const handleStartSync = (0, react.useCallback)((itemId) => {
1771 + startSyncFromState(itemId);
1772 + const variable = variables[itemId];
1773 + if (variable) trackVariableSyncToV3({
1774 + variableLabel: variable.label,
1775 + action: "sync"
1776 + });
1777 + }, [startSyncFromState, variables]);
1778 + const handleStopSync = (0, react.useCallback)((itemId) => {
1779 + if (!isStopSyncSuppressed) setStopSyncConfirmation(itemId);
1780 + else commitStopSync(itemId);
1781 + }, [isStopSyncSuppressed, commitStopSync]);
1782 + const buildMenuActions = (0, react.useCallback)((variableId) => {
1783 + const variable = variables[variableId];
1784 + if (!variable) return [];
1785 + const typeActions = getMenuActionsForVariable(variable.type, {
1786 + variable,
1787 + variableId,
1788 + handlers: {
1789 + onStartSync: handleStartSync,
1790 + onStopSync: handleStopSync
1791 + }
1792 + });
1793 + const duplicateAction = {
1794 + name: (0, _wordpress_i18n.__)("Duplicate", "elementor"),
1795 + icon: _elementor_icons.CopyIcon,
1796 + color: "text.primary",
1797 + onClick: (itemId) => {
1798 + const newId = duplicateVariable(itemId);
1799 + startAutoEdit(newId);
1800 + trackVariablesManagerEvent({
1801 + action: "duplicate",
1802 + varType: getVariableType(variable.type)?.variableType
1803 + });
1804 + }
1805 + };
1806 + const deleteAction = {
1807 + name: (0, _wordpress_i18n.__)("Delete", "elementor"),
1808 + icon: _elementor_icons.TrashIcon,
1809 + color: "error.main",
1810 + onClick: (itemId) => {
1811 + const v = variables[itemId];
1812 + if (v) {
1813 + setDeleteConfirmation({
1814 + id: itemId,
1815 + label: v.label
1816 + });
1817 + trackVariablesManagerEvent({
1818 + action: "delete",
1819 + varType: getVariableType(v.type)?.variableType
1820 + });
1821 + }
1822 + }
1823 + };
1824 + return [
1825 + ...typeActions,
1826 + duplicateAction,
1827 + deleteAction
1828 + ];
1829 + }, [
1830 + variables,
1831 + handleStartSync,
1832 + handleStopSync,
1833 + duplicateVariable,
1834 + startAutoEdit
1835 + ]);
1836 + const hasVariables = Object.keys(variables).length > 0;
1837 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1838 + direction: "column",
1839 + sx: {
1840 + height: "100%",
1841 + width: "100%",
1842 + flex: 1,
1843 + minHeight: 0,
1844 + overflow: "hidden"
1845 + }
1846 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
1847 + direction: "row",
1848 + alignItems: "center",
1849 + spacing: 1,
1850 + width: "100%",
1851 + sx: {
1852 + flexShrink: 0,
1853 + px: 2,
1854 + pb: 1
1855 + }
1856 + }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SearchField, {
1857 + placeholder: (0, _wordpress_i18n.__)("Search", "elementor"),
1858 + value: searchValue,
1859 + onSearch: handleSearch,
1860 + sx: {
1861 + flex: 1,
1862 + minWidth: 0,
1863 + px: 0,
1864 + py: 0,
1865 + display: "flex",
1866 + alignItems: "center",
1867 + alignSelf: "stretch"
1868 + }
1869 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
1870 + display: "flex",
1871 + flexShrink: 0,
1872 + alignItems: "center"
1873 + } }, /* @__PURE__ */ react.createElement(VariableManagerCreateMenu, {
1874 + outlinedTrigger: true,
1875 + onCreate: handleCreateVariable,
1876 + variables,
1877 + menuState: createMenuState
1878 + }))), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, { sx: { width: "100%" } }), /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelBody, { sx: {
1879 + display: "flex",
1880 + flexDirection: "column",
1881 + flex: 1,
1882 + minHeight: 0
1883 + } }, hasVariables && /* @__PURE__ */ react.createElement(VariablesManagerTable, {
1884 + menuActions: buildMenuActions,
1885 + variables,
1886 + onChange: handleOnChange,
1887 + autoEditVariableId,
1888 + onAutoEditComplete: handleAutoEditComplete,
1889 + onFieldError: setIsSaveDisabled
1890 + }), !hasVariables && searchValue && /* @__PURE__ */ react.createElement(NoSearchResults, {
1891 + searchValue,
1892 + onClear: () => handleSearch(""),
1893 + icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorFilterIcon, { fontSize: "large" })
1894 + }), !hasVariables && !searchValue && /* @__PURE__ */ react.createElement(EmptyState, {
1895 + title: (0, _wordpress_i18n.__)("Create your first variable", "elementor"),
1896 + message: (0, _wordpress_i18n.__)("Variables are saved attributes that you can apply anywhere on your site.", "elementor"),
1897 + icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorFilterIcon, { fontSize: "large" }),
1898 + onAdd: createMenuState.open
1899 + })), /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelFooter, null, /* @__PURE__ */ react.createElement(_elementor_ui.Infotip, {
1900 + placement: "right",
1901 + open: !!serverError,
1902 + content: serverError ? /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
1903 + severity: serverError.severity ?? "error",
1904 + action: serverError.action?.label ? /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, { onClick: serverError.action.callback }, serverError.action.label) : void 0,
1905 + onClose: !serverError.action?.label ? () => {
1906 + setServerError(null);
1907 + setIsSaveDisabled(false);
1908 + } : void 0,
1909 + icon: serverError.IconComponent ? /* @__PURE__ */ react.createElement(serverError.IconComponent, null) : /* @__PURE__ */ react.createElement(_elementor_icons.AlertTriangleFilledIcon, null)
1910 + }, /* @__PURE__ */ react.createElement(_elementor_ui.AlertTitle, null, serverError.message), serverError.action?.message) : null,
1911 + arrow: false,
1912 + slotProps: { popper: { modifiers: [{
1913 + name: "offset",
1914 + options: { offset: [-10, 10] }
1915 + }] } }
1916 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
1917 + fullWidth: true,
1918 + size: "small",
1919 + color: "global",
1920 + variant: "contained",
1921 + disabled: isSaveDisabled || !isDirty || isSaving,
1922 + onClick: handleSaveClick,
1923 + loading: isSaving
1924 + }, (0, _wordpress_i18n.__)("Save changes", "elementor"))))), deleteConfirmation && /* @__PURE__ */ react.createElement(DeleteConfirmationDialog, {
1925 + open: true,
1926 + label: deleteConfirmation.label,
1927 + onConfirm: () => handleDeleteVariableWithConfirmation(deleteConfirmation.id),
1928 + closeDialog: () => setDeleteConfirmation(null)
1929 + }), stopSyncConfirmation && /* @__PURE__ */ react.createElement(StopSyncConfirmationDialog, {
1930 + open: true,
1931 + onClose: () => setStopSyncConfirmation(null),
1932 + onConfirm: () => {
1933 + commitStopSync(stopSyncConfirmation);
1934 + setStopSyncConfirmation(null);
1935 + }
1936 + }), isSaveChangesDialogOpen && /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Title, { onClose: closeSaveChangesDialog }, (0, _wordpress_i18n.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.ContentText, null, (0, _wordpress_i18n.__)("You have unsaved changes in the Variables Manager.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.ContentText, null, (0, _wordpress_i18n.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Actions, { actions: {
1937 + discard: {
1938 + label: (0, _wordpress_i18n.__)("Discard", "elementor"),
1939 + action: () => {
1940 + closeSaveChangesDialog();
1941 + onRequestClose();
1942 + }
1943 + },
1944 + confirm: {
1945 + label: (0, _wordpress_i18n.__)("Save", "elementor"),
1946 + action: async () => {
1947 + const result = await handleSaveClick();
1948 + closeSaveChangesDialog();
1949 + if (result?.success) onRequestClose();
1950 + }
1951 + }
1952 + } })));
1953 + }
1954 + var usePreventUnload = (isDirty) => {
1955 + (0, react.useEffect)(() => {
1956 + const handleBeforeUnload = (event) => {
1957 + if (isDirty) event.preventDefault();
1958 + };
1959 + window.addEventListener("beforeunload", handleBeforeUnload);
1960 + return () => {
1961 + window.removeEventListener("beforeunload", handleBeforeUnload);
1962 + };
1963 + }, [isDirty]);
1964 + };
1965 + var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
1966 + const [, suppressStopSyncMessage] = (0, _elementor_editor_current_user.useSuppressedMessage)(STOP_SYNC_MESSAGE_KEY);
1967 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog, {
1968 + open,
1969 + onClose
1970 + }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Title, {
1971 + icon: _elementor_icons.ColorFilterIcon,
1972 + iconColor: "primary"
1973 + }, (0, _wordpress_i18n.__)("Stop syncing variable color", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.ContentText, null, (0, _wordpress_i18n.__)("This will disconnect the variable color from Global Colors. Existing uses on your site will automatically switch to a default color.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.ConfirmationDialog.Actions, {
1974 + onClose,
1975 + onConfirm,
1976 + cancelLabel: (0, _wordpress_i18n.__)("Cancel", "elementor"),
1977 + confirmLabel: (0, _wordpress_i18n.__)("Got it", "elementor"),
1978 + color: "primary",
1979 + onSuppressMessage: suppressStopSyncMessage,
1980 + suppressLabel: (0, _wordpress_i18n.__)("Don't show again", "elementor")
1981 + }));
1982 + };
1983 +
1984 +//#endregion
1985 +//#region packages/packages/core/editor-variables/src/components/global-styles-import-listener.tsx
1986 + function GlobalStylesImportListener() {
1987 + (0, react.useEffect)(() => {
1988 + const handleGlobalStylesImported = () => {
1989 + service.load();
1990 + };
1991 + window.addEventListener(_elementor_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
1992 + return () => {
1993 + window.removeEventListener(_elementor_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT, handleGlobalStylesImported);
1994 + };
1995 + }, []);
1996 + return null;
1997 + }
1998 +
1999 +//#endregion
2000 +//#region packages/packages/core/editor-variables/src/utils/extract-variables-from-style-value.ts
2001 + var VARIABLE_TYPE_KEYS = [
2002 + "global-color-variable",
2003 + "global-font-variable",
2004 + "global-size-variable",
2005 + "global-custom-size-variable"
2006 + ];
2007 + function tryExtractVariable(value) {
2008 + for (const key of VARIABLE_TYPE_KEYS) {
2009 + const propUtil = (0, _elementor_editor_props.getPropSchemaFromCache)(key);
2010 + if (propUtil?.isValid(value)) return {
2011 + type: key,
2012 + variableId: propUtil.extract(value)
2013 + };
2014 + }
2015 + return null;
2016 + }
2017 + function traverse(value, path, result) {
2018 + const extracted = tryExtractVariable(value);
2019 + if (extracted) {
2020 + result.push({
2021 + ...extracted,
2022 + controlPath: path.join(".")
2023 + });
2024 + return;
2025 + }
2026 + if ((0, _elementor_editor_props.isTransformable)(value)) {
2027 + traverse(value.value, path, result);
2028 + return;
2029 + }
2030 + if (value && typeof value === "object") for (const [key, val] of Object.entries(value)) traverse(val, [...path, key], result);
2031 + }
2032 + function extractVariablesFromStyleValue(styleValue) {
2033 + const result = [];
2034 + traverse(styleValue, [], result);
2035 + return result;
2036 + }
2037 +
2038 +//#endregion
2039 +//#region packages/packages/core/editor-variables/src/components/mcp-variable-connect-listener.tsx
2040 + function McpVariableConnectListener() {
2041 + (0, react.useEffect)(() => {
2042 + const handleMcpStylesApplied = (event) => {
2043 + const { styleValue } = event.detail;
2044 + extractVariablesFromStyleValue(styleValue).forEach(({ type, controlPath }) => {
2045 + trackVariableEvent({
2046 + varType: type,
2047 + controlPath,
2048 + action: "connect",
2049 + executedBy: "mcp_tool"
2050 + });
2051 + });
2052 + };
2053 + window.addEventListener(_elementor_editor_mcp.MCP_STYLES_APPLIED_EVENT, handleMcpStylesApplied);
2054 + return () => {
2055 + window.removeEventListener(_elementor_editor_mcp.MCP_STYLES_APPLIED_EVENT, handleMcpStylesApplied);
2056 + };
2057 + }, []);
2058 + return null;
2059 + }
2060 +
2061 +//#endregion
2062 +//#region packages/packages/core/editor-variables/src/utils/unlink-variable.ts
2063 + function transformValueBeforeUnlink(variable, propTypeKey) {
2064 + const { valueTransformer } = getVariableType(propTypeKey);
2065 + if (valueTransformer) return valueTransformer(variable.value, variable.type);
2066 + return variable.value;
2067 + }
2068 + function createUnlinkHandler(variable, propTypeKey, setValue) {
2069 + return () => {
2070 + const { fallbackPropTypeUtil } = getVariableType(propTypeKey);
2071 + const transformedValue = transformValueBeforeUnlink(variable, propTypeKey);
2072 + setValue(fallbackPropTypeUtil.create(transformedValue));
2073 + };
2074 + }
2075 +
2076 +//#endregion
2077 +//#region packages/packages/core/editor-variables/src/context/variable-selection-popover.context.tsx
2078 + var PopoverContentRefContext = (0, react.createContext)(null);
2079 + var PopoverContentRefContextProvider = ({ children }) => {
2080 + const [anchorRef, setAnchorRef] = (0, react.useState)(null);
2081 + return /* @__PURE__ */ react.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { ref: setAnchorRef }, children));
2082 + };
2083 + var usePopoverContentRef = () => {
2084 + return (0, react.useContext)(PopoverContentRefContext);
2085 + };
2086 +
2087 +//#endregion
2088 +//#region packages/packages/core/editor-variables/src/hooks/use-initial-value.ts
2089 + var useInitialValue = () => {
2090 + const { value: initial } = (0, _elementor_editor_controls.useBoundProp)();
2091 + const hasAssignedVariable = hasVariableType(initial?.$$type) && Boolean(initial?.value);
2092 + const variable = useVariable(hasAssignedVariable ? initial.value : "");
2093 + if (hasAssignedVariable) return variable ? variable.value : "";
2094 + return initial?.value ?? "";
2095 + };
2096 +
2097 +//#endregion
2098 +//#region packages/packages/core/editor-variables/src/hooks/use-variable-bound-prop.ts
2099 + var useVariableBoundProp = () => {
2100 + const { propTypeUtil } = useVariableType();
2101 + const boundProp = (0, _elementor_editor_controls.useBoundProp)(propTypeUtil);
2102 + return {
2103 + ...boundProp,
2104 + setVariableValue: (value) => resolveBoundPropAndSetValue(value, boundProp),
2105 + variableId: boundProp.value ?? boundProp.placeholder
2106 + };
2107 + };
2108 + var resolveBoundPropAndSetValue = (value, boundProp) => {
2109 + const propValue = unwrapValue(boundProp.value);
2110 + const placeholder = unwrapValue(boundProp.placeholder);
2111 + const newValue = unwrapValue(value);
2112 + if (!propValue && placeholder === newValue) return boundProp.setValue(null);
2113 + return boundProp.setValue(value);
2114 + };
2115 + var unwrapValue = (input) => {
2116 + if ((0, _elementor_editor_props.isTransformable)(input)) return input.value;
2117 + return input;
2118 + };
2119 +
2120 +//#endregion
2121 +//#region packages/packages/core/editor-variables/src/components/ui/form-field.tsx
2122 + var FormField = ({ id, label, errorMsg, noticeMsg, children }) => {
2123 + return /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
2124 + container: true,
2125 + gap: .75,
2126 + alignItems: "center"
2127 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
2128 + item: true,
2129 + xs: 12
2130 + }, /* @__PURE__ */ react.createElement(_elementor_ui.FormLabel, {
2131 + htmlFor: id,
2132 + size: "tiny"
2133 + }, label)), /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
2134 + item: true,
2135 + xs: 12
2136 + }, children, errorMsg && /* @__PURE__ */ react.createElement(_elementor_ui.FormHelperText, { error: true }, errorMsg), noticeMsg && /* @__PURE__ */ react.createElement(_elementor_ui.FormHelperText, null, noticeMsg)));
2137 + };
2138 +
2139 +//#endregion
2140 +//#region packages/packages/core/editor-variables/src/components/variable-creation.tsx
2141 + var SIZE$5 = "tiny";
2142 + var VariableCreation = ({ onGoBack, onClose }) => {
2143 + const { icon: VariableIcon, valueField: ValueField, propTypeUtil } = useVariableType();
2144 + const { setVariableValue: setVariable, path } = useVariableBoundProp();
2145 + const { propType } = (0, _elementor_editor_controls.useBoundProp)();
2146 + const [value, setValue] = (0, react.useState)(useInitialValue());
2147 + const [label, setLabel] = (0, react.useState)("");
2148 + const [errorMessage, setErrorMessage] = (0, react.useState)("");
2149 + const [valueFieldError, setValueFieldError] = (0, react.useState)("");
2150 + const [propTypeKey, setPropTypeKey] = (0, react.useState)(propTypeUtil.key);
2151 + const { labelFieldError, setLabelFieldError } = useLabelError();
2152 + const resetFields = () => {
2153 + setValue("");
2154 + setLabel("");
2155 + setErrorMessage("");
2156 + setValueFieldError("");
2157 + };
2158 + const closePopover = () => {
2159 + resetFields();
2160 + onClose();
2161 + };
2162 + const handleCreateAndTrack = () => {
2163 + createVariable({
2164 + value,
2165 + label,
2166 + type: propTypeKey
2167 + }, { eventData: { controlPath: path.join(".") } }).then((key) => {
2168 + setVariable(key);
2169 + closePopover();
2170 + }).catch((error) => {
2171 + const mappedError = mapServerError(error);
2172 + if (mappedError && "label" === mappedError.field) {
2173 + setLabel("");
2174 + setLabelFieldError({
2175 + value: label,
2176 + message: mappedError.message
2177 + });
2178 + return;
2179 + }
2180 + setErrorMessage(ERROR_MESSAGES.UNEXPECTED_ERROR);
2181 + });
2182 + };
2183 + const hasEmptyFields = () => {
2184 + if ("" === label.trim()) return true;
2185 + if ("string" === typeof value) return "" === value.trim();
2186 + return false === Boolean(value);
2187 + };
2188 + const hasErrors = () => {
2189 + return !!errorMessage;
2190 + };
2191 + const isSubmitDisabled = hasEmptyFields() || hasErrors();
2192 + const handleKeyDown = (event) => {
2193 + if (event.key === "Enter" && !isSubmitDisabled) {
2194 + event.preventDefault();
2195 + handleCreateAndTrack();
2196 + }
2197 + };
2198 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.SectionPopoverBody, { height: "auto" }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
2199 + icon: /* @__PURE__ */ react.createElement(react.Fragment, null, onGoBack && /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2200 + size: SIZE$5,
2201 + "aria-label": (0, _wordpress_i18n.__)("Go Back", "elementor"),
2202 + onClick: onGoBack
2203 + }, /* @__PURE__ */ react.createElement(_elementor_icons.ArrowLeftIcon, { fontSize: SIZE$5 })), /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: SIZE$5 })),
2204 + title: (0, _wordpress_i18n.__)("Create variable", "elementor"),
2205 + onClose: closePopover
2206 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverContent, { p: 2 }, /* @__PURE__ */ react.createElement(FormField, {
2207 + id: "variable-label",
2208 + label: (0, _wordpress_i18n.__)("Name", "elementor"),
2209 + errorMsg: labelFieldError?.message,
2210 + noticeMsg: labelHint(label)
2211 + }, /* @__PURE__ */ react.createElement(LabelField, {
2212 + id: "variable-label",
2213 + value: label,
2214 + error: labelFieldError,
2215 + onChange: (newValue) => {
2216 + setLabel(newValue);
2217 + setErrorMessage("");
2218 + },
2219 + onErrorChange: (errorMsg) => {
2220 + setLabelFieldError({
2221 + value: "",
2222 + message: errorMsg
2223 + });
2224 + },
2225 + onKeyDown: handleKeyDown,
2226 + focusOnShow: true
2227 + })), ValueField && /* @__PURE__ */ react.createElement(FormField, {
2228 + errorMsg: valueFieldError,
2229 + label: (0, _wordpress_i18n.__)("Value", "elementor")
2230 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2231 + variant: "h5",
2232 + id: "variable-value-wrapper"
2233 + }, /* @__PURE__ */ react.createElement(ValueField, {
2234 + value,
2235 + onPropTypeKeyChange: (key) => setPropTypeKey(key),
2236 + onChange: (newValue) => {
2237 + setValue(newValue);
2238 + setErrorMessage("");
2239 + setValueFieldError("");
2240 + },
2241 + onValidationChange: setValueFieldError,
2242 + propType,
2243 + onKeyDown: handleKeyDown
2244 + }))), errorMessage && /* @__PURE__ */ react.createElement(_elementor_ui.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ react.createElement(_elementor_ui.CardActions, { sx: {
2245 + pt: .5,
2246 + pb: 1
2247 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2248 + id: "create-variable-button",
2249 + size: "small",
2250 + variant: "contained",
2251 + disabled: isSubmitDisabled,
2252 + onClick: handleCreateAndTrack
2253 + }, (0, _wordpress_i18n.__)("Create", "elementor"))));
2254 + };
2255 +
2256 +//#endregion
2257 +//#region packages/packages/core/editor-variables/src/components/ui/edit-confirmation-dialog.tsx
2258 + var EDIT_CONFIRMATION_DIALOG_ID = "edit-confirmation-dialog";
2259 + var EditConfirmationDialog = ({ closeDialog, onConfirm, onSuppressMessage }) => {
2260 + const [dontShowAgain, setDontShowAgain] = (0, react.useState)(false);
2261 + const handleSave = () => {
2262 + if (dontShowAgain) onSuppressMessage?.();
2263 + onConfirm?.();
2264 + };
2265 + return /* @__PURE__ */ react.createElement(_elementor_ui.Dialog, {
2266 + open: true,
2267 + onClose: closeDialog,
2268 + maxWidth: "xs"
2269 + }, /* @__PURE__ */ react.createElement(_elementor_ui.DialogTitle, {
2270 + display: "flex",
2271 + alignItems: "center",
2272 + gap: 1
2273 + }, /* @__PURE__ */ react.createElement(_elementor_icons.AlertTriangleFilledIcon, { color: "secondary" }), (0, _wordpress_i18n.__)("Changes to variables go live right away.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.DialogContent, null, /* @__PURE__ */ react.createElement(_elementor_ui.DialogContentText, {
2274 + variant: "body2",
2275 + color: "textPrimary"
2276 + }, (0, _wordpress_i18n.__)("Don't worry - all other changes you make will wait until you publish your site.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogActions, { sx: {
2277 + justifyContent: "space-between",
2278 + alignItems: "center"
2279 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.FormControlLabel, {
2280 + control: /* @__PURE__ */ react.createElement(_elementor_ui.Checkbox, {
2281 + checked: dontShowAgain,
2282 + onChange: (event) => setDontShowAgain(event.target.checked),
2283 + size: "small"
2284 + }),
2285 + label: /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "body2" }, (0, _wordpress_i18n.__)("Don't show me again", "elementor"))
2286 + }), /* @__PURE__ */ react.createElement("div", null, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2287 + color: "secondary",
2288 + onClick: closeDialog
2289 + }, (0, _wordpress_i18n.__)("Keep editing", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2290 + variant: "contained",
2291 + color: "secondary",
2292 + onClick: handleSave,
2293 + sx: { ml: 1 }
2294 + }, (0, _wordpress_i18n.__)("Save", "elementor")))));
2295 + };
2296 +
2297 +//#endregion
2298 +//#region packages/packages/core/editor-variables/src/components/variable-edit.tsx
2299 + var SIZE$4 = "tiny";
2300 + var DELETE_LABEL = (0, _wordpress_i18n.__)("Delete variable", "elementor");
2301 + var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2302 + const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
2303 + const { setVariableValue: notifyBoundPropChange, variableId, path } = useVariableBoundProp();
2304 + const { propType } = (0, _elementor_editor_controls.useBoundProp)();
2305 + const [isMessageSuppressed, suppressMessage] = (0, _elementor_editor_current_user.useSuppressedMessage)(EDIT_CONFIRMATION_DIALOG_ID);
2306 + const [deleteConfirmation, setDeleteConfirmation] = (0, react.useState)(false);
2307 + const [editConfirmation, setEditConfirmation] = (0, react.useState)(false);
2308 + const [errorMessage, setErrorMessage] = (0, react.useState)("");
2309 + const [valueFieldError, setValueFieldError] = (0, react.useState)("");
2310 + const { labelFieldError, setLabelFieldError } = useLabelError();
2311 + const variable = useVariable(editId);
2312 + const [propTypeKey, setPropTypeKey] = (0, react.useState)(variable?.type ?? propTypeUtil.key);
2313 + if (!variable) throw new Error(`Global ${variableType} variable not found`);
2314 + const userPermissions = usePermissions();
2315 + const [value, setValue] = (0, react.useState)(() => variable.value);
2316 + const [label, setLabel] = (0, react.useState)(() => variable.label);
2317 + (0, react.useEffect)(() => {
2318 + styleVariablesRepository.update({ [editId]: {
2319 + ...variable,
2320 + value
2321 + } });
2322 + return () => {
2323 + styleVariablesRepository.update({ [editId]: { ...variable } });
2324 + };
2325 + }, [
2326 + editId,
2327 + value,
2328 + variable
2329 + ]);
2330 + const handleUpdate = () => {
2331 + if (isMessageSuppressed) handleSaveVariable();
2332 + else setEditConfirmation(true);
2333 + };
2334 + const handleSaveVariable = () => {
2335 + updateVariable(editId, propTypeKey !== variable.type ? {
2336 + value,
2337 + label,
2338 + type: propTypeKey
2339 + } : {
2340 + value,
2341 + label
2342 + }, { eventData: { controlPath: path.join(".") } }).then(() => {
2343 + maybeTriggerBoundPropChange();
2344 + onSubmit?.();
2345 + }).catch((error) => {
2346 + const mappedError = mapServerError(error);
2347 + if (mappedError && "label" === mappedError.field) {
2348 + setLabel("");
2349 + setLabelFieldError({
2350 + value: label,
2351 + message: mappedError.message
2352 + });
2353 + return;
2354 + }
2355 + setErrorMessage(ERROR_MESSAGES.UNEXPECTED_ERROR);
2356 + });
2357 + };
2358 + const handleDelete = () => {
2359 + deleteVariable(editId).then(() => {
2360 + maybeTriggerBoundPropChange();
2361 + onSubmit?.();
2362 + });
2363 + };
2364 + const maybeTriggerBoundPropChange = () => {
2365 + if (editId === variableId) notifyBoundPropChange(editId);
2366 + };
2367 + const handleDeleteConfirmation = () => {
2368 + setDeleteConfirmation(true);
2369 + };
2370 + const closeDeleteDialog = () => () => {
2371 + setDeleteConfirmation(false);
2372 + };
2373 + const closeEditDialog = () => () => {
2374 + setEditConfirmation(false);
2375 + };
2376 + const actions = [];
2377 + if (userPermissions.canDelete()) actions.push(/* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2378 + key: "delete",
2379 + placement: "top",
2380 + title: DELETE_LABEL
2381 + }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2382 + size: SIZE$4,
2383 + onClick: handleDeleteConfirmation,
2384 + "aria-label": DELETE_LABEL
2385 + }, /* @__PURE__ */ react.createElement(_elementor_icons.TrashIcon, { fontSize: SIZE$4 }))));
2386 + const hasEmptyFields = () => {
2387 + if ("" === label.trim()) return true;
2388 + if ("string" === typeof value) return "" === value.trim();
2389 + return false === Boolean(value);
2390 + };
2391 + const noValueChanged = () => {
2392 + return value === variable.value && label === variable.label;
2393 + };
2394 + const hasErrors = () => {
2395 + return !!errorMessage;
2396 + };
2397 + const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
2398 + const handleKeyDown = (event) => {
2399 + if (event.key === "Enter" && !isSubmitDisabled) {
2400 + event.preventDefault();
2401 + handleUpdate();
2402 + }
2403 + };
2404 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SectionPopoverBody, { height: "auto" }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
2405 + title: (0, _wordpress_i18n.__)("Edit variable", "elementor"),
2406 + onClose,
2407 + icon: /* @__PURE__ */ react.createElement(react.Fragment, null, onGoBack && /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2408 + size: SIZE$4,
2409 + "aria-label": (0, _wordpress_i18n.__)("Go Back", "elementor"),
2410 + onClick: onGoBack
2411 + }, /* @__PURE__ */ react.createElement(_elementor_icons.ArrowLeftIcon, { fontSize: SIZE$4 })), /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: SIZE$4 })),
2412 + actions
2413 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverContent, { p: 2 }, /* @__PURE__ */ react.createElement(FormField, {
2414 + id: "variable-label",
2415 + label: (0, _wordpress_i18n.__)("Name", "elementor"),
2416 + errorMsg: labelFieldError?.message,
2417 + noticeMsg: labelHint(label)
2418 + }, /* @__PURE__ */ react.createElement(LabelField, {
2419 + id: "variable-label",
2420 + value: label,
2421 + error: labelFieldError,
2422 + onChange: (newValue) => {
2423 + setLabel(newValue);
2424 + setErrorMessage("");
2425 + },
2426 + onErrorChange: (errorMsg) => {
2427 + setLabelFieldError({
2428 + value: "",
2429 + message: errorMsg
2430 + });
2431 + },
2432 + onKeyDown: handleKeyDown,
2433 + focusOnShow: true
2434 + })), ValueField && /* @__PURE__ */ react.createElement(FormField, {
2435 + errorMsg: valueFieldError,
2436 + label: (0, _wordpress_i18n.__)("Value", "elementor")
2437 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "h5" }, /* @__PURE__ */ react.createElement(ValueField, {
2438 + propTypeKey: variable.type,
2439 + onPropTypeKeyChange: (key) => setPropTypeKey(key),
2440 + value,
2441 + onChange: (newValue) => {
2442 + setValue(newValue);
2443 + setErrorMessage("");
2444 + setValueFieldError("");
2445 + },
2446 + onKeyDown: handleKeyDown,
2447 + onValidationChange: setValueFieldError,
2448 + propType
2449 + }))), errorMessage && /* @__PURE__ */ react.createElement(_elementor_ui.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ react.createElement(_elementor_ui.CardActions, { sx: {
2450 + pt: .5,
2451 + pb: 1
2452 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2453 + size: "small",
2454 + variant: "contained",
2455 + disabled: isSubmitDisabled,
2456 + onClick: handleUpdate
2457 + }, (0, _wordpress_i18n.__)("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ react.createElement(DeleteConfirmationDialog, {
2458 + open: true,
2459 + label,
2460 + onConfirm: handleDelete,
2461 + closeDialog: closeDeleteDialog()
2462 + }), editConfirmation && !isMessageSuppressed && /* @__PURE__ */ react.createElement(EditConfirmationDialog, {
2463 + closeDialog: closeEditDialog(),
2464 + onConfirm: handleSaveVariable,
2465 + onSuppressMessage: suppressMessage
2466 + }));
2467 + };
2468 +
2469 +//#endregion
2470 +//#region packages/packages/core/editor-variables/src/components/ui/menu-item-content.tsx
2471 + var SIZE$3 = "tiny";
2472 + var EDIT_LABEL = (0, _wordpress_i18n.__)("Edit variable", "elementor");
2473 + var MenuItemContent = ({ item, disabled = false }) => {
2474 + const onEdit = item.onEdit;
2475 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.ListItemIcon, { sx: { color: disabled ? "text.disabled" : "inherit" } }, item.icon), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2476 + flex: 1,
2477 + minWidth: 0,
2478 + display: "flex",
2479 + alignItems: "center",
2480 + gap: 1
2481 + } }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
2482 + title: item.label || item.value,
2483 + as: _elementor_ui.Typography,
2484 + variant: "caption",
2485 + color: disabled ? "text.disabled" : "text.primary",
2486 + sx: {
2487 + marginTop: "1px",
2488 + lineHeight: "2"
2489 + },
2490 + maxWidth: "50%"
2491 + }), item.secondaryText && /* @__PURE__ */ react.createElement(_elementor_editor_ui.EllipsisWithTooltip, {
2492 + title: item.secondaryText,
2493 + as: _elementor_ui.Typography,
2494 + variant: "caption",
2495 + color: disabled ? "text.disabled" : "text.tertiary",
2496 + sx: {
2497 + marginTop: "1px",
2498 + lineHeight: "1"
2499 + },
2500 + maxWidth: "50%"
2501 + })), !!onEdit && !disabled && /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2502 + placement: "top",
2503 + title: EDIT_LABEL
2504 + }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2505 + sx: {
2506 + mx: 1,
2507 + opacity: "0"
2508 + },
2509 + onClick: (e) => {
2510 + e.stopPropagation();
2511 + onEdit(item.value);
2512 + },
2513 + "aria-label": EDIT_LABEL
2514 + }, /* @__PURE__ */ react.createElement(_elementor_icons.EditIcon, {
2515 + color: "action",
2516 + fontSize: SIZE$3
2517 + }))));
2518 + };
2519 +
2520 +//#endregion
2521 +//#region packages/packages/core/editor-variables/src/components/ui/styled-menu-list.tsx
2522 + var VariablesStyledMenuList = (0, _elementor_ui.styled)(_elementor_ui.MenuList)(({ theme, disabled }) => ({
2523 + "& > li": {
2524 + height: 32,
2525 + width: "100%",
2526 + display: "flex",
2527 + alignItems: "center"
2528 + },
2529 + "& > [role=\"option\"]": {
2530 + ...theme.typography.caption,
2531 + lineHeight: "inherit",
2532 + padding: theme.spacing(.5, 1, .5, 2),
2533 + ...!disabled && {
2534 + "&:hover, &:focus": { backgroundColor: theme.palette.action.hover },
2535 + cursor: "pointer"
2536 + },
2537 + "&[aria-selected=\"true\"]": { backgroundColor: theme.palette.action.selected },
2538 + textOverflow: "ellipsis",
2539 + position: "absolute",
2540 + top: 0,
2541 + left: 0,
2542 + "&:hover .MuiIconButton-root, .MuiIconButton-root:focus": { opacity: 1 }
2543 + },
2544 + width: "100%",
2545 + position: "relative"
2546 + }));
2547 +
2548 +//#endregion
2549 +//#region packages/packages/core/editor-variables/src/components/variables-selection.tsx
2550 + var SIZE$2 = "tiny";
2551 + var CREATE_LABEL = (0, _wordpress_i18n.__)("Create variable", "elementor");
2552 + var MANAGER_LABEL = (0, _wordpress_i18n.__)("Variables Manager", "elementor");
2553 + var getProUpgradeUrl = (variableType) => `https://go.elementor.com/renew-license-panel-${variableType}-variable`;
2554 + var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled = false }) => {
2555 + const { icon: VariableIcon, startIcon, variableType, propTypeUtil, emptyState } = useVariableType();
2556 + const { value: variable, setValue: setVariable, path } = useVariableBoundProp();
2557 + const [searchValue, setSearchValue] = (0, react.useState)("");
2558 + const { list: variables, hasMatches: hasSearchResults, isSourceNotEmpty: hasVariables, hasNoCompatibleVariables } = useFilteredVariables(searchValue, propTypeUtil.key);
2559 + const handleSetVariable = (key) => {
2560 + setVariable(key);
2561 + trackVariableEvent({
2562 + varType: variableType,
2563 + controlPath: path.join("."),
2564 + action: "connect"
2565 + });
2566 + closePopover();
2567 + };
2568 + const onAddAndTrack = () => {
2569 + onAdd?.();
2570 + trackVariableEvent({
2571 + varType: variableType,
2572 + controlPath: path.join("."),
2573 + action: "add"
2574 + });
2575 + };
2576 + const actions = [];
2577 + if (onAdd) actions.push(/* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2578 + key: "add",
2579 + placement: "top",
2580 + title: CREATE_LABEL
2581 + }, /* @__PURE__ */ react.createElement("span", null, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2582 + id: "add-variable-button",
2583 + size: SIZE$2,
2584 + onClick: onAddAndTrack,
2585 + "aria-label": CREATE_LABEL,
2586 + disabled
2587 + }, /* @__PURE__ */ react.createElement(_elementor_icons.PlusIcon, { fontSize: SIZE$2 })))));
2588 + if (onSettings) {
2589 + const handleOpenManager = () => {
2590 + onSettings();
2591 + trackVariablesManagerEvent({
2592 + action: "openManager",
2593 + source: "vars-popover",
2594 + varType: variableType,
2595 + controlPath: path.join(".")
2596 + });
2597 + };
2598 + actions.push(/* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2599 + key: "settings",
2600 + placement: "top",
2601 + title: MANAGER_LABEL
2602 + }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2603 + id: "variables-manager-button",
2604 + size: SIZE$2,
2605 + onClick: handleOpenManager,
2606 + "aria-label": MANAGER_LABEL
2607 + }, /* @__PURE__ */ react.createElement(_elementor_icons.SettingsIcon, { fontSize: SIZE$2 }))));
2608 + }
2609 + const StartIcon = startIcon || (() => /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: SIZE$2 }));
2610 + const items = variables.map(({ value, label, key }) => ({
2611 + type: "item",
2612 + value: key,
2613 + label,
2614 + icon: /* @__PURE__ */ react.createElement(StartIcon, { value }),
2615 + secondaryText: value,
2616 + onEdit: onEdit ? () => onEdit?.(key) : void 0
2617 + }));
2618 + const handleSearch = (search) => {
2619 + setSearchValue(search);
2620 + };
2621 + const handleClearSearch = () => {
2622 + setSearchValue("");
2623 + };
2624 + (0, react.useEffect)(() => {
2625 + if (disabled) (0, _elementor_editor_controls.trackViewPromotion)({
2626 + target_name: "variables_popover",
2627 + target_location: "widget_panel",
2628 + location_l1: "variables_list"
2629 + });
2630 + }, [disabled]);
2631 + return /* @__PURE__ */ react.createElement(_elementor_editor_ui.SectionPopoverBody, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
2632 + title: (0, _wordpress_i18n.__)("Variables", "elementor"),
2633 + icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorFilterIcon, { fontSize: SIZE$2 }),
2634 + onClose: closePopover,
2635 + actions
2636 + }), hasVariables && /* @__PURE__ */ react.createElement(_elementor_editor_ui.SearchField, {
2637 + value: searchValue,
2638 + onSearch: handleSearch,
2639 + placeholder: (0, _wordpress_i18n.__)("Search", "elementor")
2640 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), hasVariables && hasSearchResults && /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverMenuList, {
2641 + items,
2642 + onSelect: disabled ? () => {} : handleSetVariable,
2643 + onClose: () => {},
2644 + selectedValue: variable,
2645 + "data-testid": `${variableType}-variables-list`,
2646 + menuListTemplate: (props) => /* @__PURE__ */ react.createElement(VariablesStyledMenuList, {
2647 + ...props,
2648 + disabled
2649 + }),
2650 + menuItemContentTemplate: (item) => /* @__PURE__ */ react.createElement(MenuItemContent, {
2651 + item,
2652 + disabled
2653 + })
2654 + }), disabled && /* @__PURE__ */ react.createElement(_elementor_editor_ui.PromotionAlert, {
2655 + message: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("Upgrade to continue creating and editing %s variables.", "elementor"), variableType),
2656 + upgradeUrl: getProUpgradeUrl(variableType),
2657 + onCtaClick: () => (0, _elementor_editor_controls.trackUpgradePromotionClick)({
2658 + target_name: "variables_popover",
2659 + location_l1: "variables_list"
2660 + })
2661 + })), !hasSearchResults && hasVariables && /* @__PURE__ */ react.createElement(NoSearchResults, {
2662 + searchValue,
2663 + onClear: handleClearSearch,
2664 + icon: /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: "large" })
2665 + }), disabled && !hasVariables && /* @__PURE__ */ react.createElement(EmptyState, {
2666 + title: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("No %s variables yet", "elementor"), variableType),
2667 + message: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("Upgrade to create %s variables and maintain consistent element sizing.", "elementor"), variableType),
2668 + icon: /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: "large" })
2669 + }, emptyState), !hasVariables && !hasNoCompatibleVariables && !disabled && /* @__PURE__ */ react.createElement(EmptyState, {
2670 + title: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("Create your first %s variable", "elementor"), variableType),
2671 + message: (0, _wordpress_i18n.__)("Variables are saved attributes that you can apply anywhere on your site.", "elementor"),
2672 + icon: /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: "large" }),
2673 + onAdd
2674 + }), hasNoCompatibleVariables && !disabled && /* @__PURE__ */ react.createElement(EmptyState, {
2675 + title: (0, _wordpress_i18n.__)("No compatible variables", "elementor"),
2676 + message: (0, _wordpress_i18n.__)("Looks like none of your variables work with this control. Create a new variable to use it here.", "elementor"),
2677 + icon: /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: "large" }),
2678 + onAdd
2679 + }));
2680 + };
2681 +
2682 +//#endregion
2683 +//#region packages/packages/core/editor-variables/src/components/variable-selection-popover.tsx
2684 + var VIEW_LIST = "list";
2685 + var VIEW_ADD = "add";
2686 + var VIEW_EDIT = "edit";
2687 + var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
2688 + const [currentView, setCurrentView] = (0, react.useState)(VIEW_LIST);
2689 + const [editId, setEditId] = (0, react.useState)("");
2690 + const onSettingsAvailable = () => {
2691 + window.dispatchEvent(new CustomEvent("elementor/toggle-design-system", { detail: { tab: "variables" } }));
2692 + };
2693 + return /* @__PURE__ */ react.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ react.createElement(PopoverContentRefContextProvider, null, RenderView({
2694 + propTypeKey,
2695 + currentView,
2696 + selectedVariable,
2697 + editId,
2698 + setEditId,
2699 + setCurrentView,
2700 + closePopover,
2701 + onSettings: onSettingsAvailable
2702 + })));
2703 + };
2704 + function RenderView(props) {
2705 + const userPermissions = usePermissions();
2706 + const userQuotaPermissions = useQuotaPermissions(props.propTypeKey);
2707 + const handlers = {
2708 + onClose: () => {
2709 + props.closePopover();
2710 + },
2711 + onGoBack: () => {
2712 + props.setCurrentView(VIEW_LIST);
2713 + }
2714 + };
2715 + if (userPermissions.canAdd()) handlers.onAdd = () => {
2716 + props.setCurrentView(VIEW_ADD);
2717 + };
2718 + if (userPermissions.canEdit()) handlers.onEdit = (key) => {
2719 + props.setEditId(key);
2720 + props.setCurrentView(VIEW_EDIT);
2721 + };
2722 + if (userPermissions.canManageSettings() && props.onSettings) handlers.onSettings = () => {
2723 + props.closePopover();
2724 + props.onSettings?.();
2725 + };
2726 + const handleSubmitOnEdit = () => {
2727 + if (props?.selectedVariable?.key === props.editId) handlers.onClose();
2728 + else handlers.onGoBack?.();
2729 + };
2730 + if (VIEW_LIST === props.currentView) return /* @__PURE__ */ react.createElement(VariablesSelection, {
2731 + closePopover: handlers.onClose,
2732 + onAdd: handlers.onAdd,
2733 + onEdit: handlers.onEdit,
2734 + onSettings: handlers.onSettings,
2735 + disabled: !userQuotaPermissions.canAdd()
2736 + });
2737 + if (VIEW_ADD === props.currentView) return /* @__PURE__ */ react.createElement(VariableCreation, {
2738 + onGoBack: handlers.onGoBack,
2739 + onClose: handlers.onClose
2740 + });
2741 + if (VIEW_EDIT === props.currentView) return /* @__PURE__ */ react.createElement(VariableEdit, {
2742 + editId: props.editId,
2743 + onGoBack: handlers.onGoBack,
2744 + onClose: handlers.onClose,
2745 + onSubmit: handleSubmitOnEdit
2746 + });
2747 + return null;
2748 + }
2749 +
2750 +//#endregion
2751 +//#region packages/packages/core/editor-variables/src/components/ui/tags/assigned-tag.tsx
2752 + var SIZE$1 = "tiny";
2753 + var UNLINK_LABEL = (0, _wordpress_i18n.__)("Unlink variable", "elementor");
2754 + var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
2755 + const actions = [];
2756 + if (onUnlink) actions.push(/* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2757 + key: "unlink",
2758 + title: UNLINK_LABEL,
2759 + placement: "bottom"
2760 + }, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
2761 + size: SIZE$1,
2762 + onClick: onUnlink,
2763 + "aria-label": UNLINK_LABEL
2764 + }, /* @__PURE__ */ react.createElement(_elementor_icons.DetachIcon, { fontSize: SIZE$1 }))));
2765 + return /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2766 + title: label,
2767 + placement: "top"
2768 + }, /* @__PURE__ */ react.createElement(_elementor_ui.UnstableTag, {
2769 + fullWidth: true,
2770 + showActionsOnHover: true,
2771 + startIcon: /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
2772 + gap: .5,
2773 + direction: "row",
2774 + alignItems: "center"
2775 + }, startIcon),
2776 + label: /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2777 + display: "inline-grid",
2778 + minWidth: 0
2779 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2780 + sx: { lineHeight: 1.34 },
2781 + variant: "caption",
2782 + noWrap: true
2783 + }, label)),
2784 + actions,
2785 + ...props
2786 + }));
2787 + };
2788 +
2789 +//#endregion
2790 +//#region packages/packages/core/editor-variables/src/components/ui/variable/assigned-variable.tsx
2791 + var AssignedVariable = ({ variable, propTypeKey }) => {
2792 + const { startIcon, propTypeUtil } = getVariableType(propTypeKey);
2793 + const { setValue } = (0, _elementor_editor_controls.useBoundProp)();
2794 + const anchorRef = (0, react.useRef)(null);
2795 + const popupState = (0, _elementor_ui.usePopupState)({
2796 + variant: "popover",
2797 + popupId: `elementor-variables-list-${(0, react.useId)()}`
2798 + });
2799 + const unlinkVariable = createUnlinkHandler(variable, propTypeKey, setValue);
2800 + const StartIcon = startIcon || (() => null);
2801 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { ref: anchorRef }, /* @__PURE__ */ react.createElement(AssignedTag, {
2802 + label: variable.label,
2803 + startIcon: /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_icons.ColorFilterIcon, { fontSize: SIZE$1 }), /* @__PURE__ */ react.createElement(StartIcon, { value: variable.value })),
2804 + onUnlink: unlinkVariable,
2805 + ...(0, _elementor_ui.bindTrigger)(popupState)
2806 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
2807 + disableScrollLock: true,
2808 + anchorEl: anchorRef.current,
2809 + anchorOrigin: {
2810 + vertical: "bottom",
2811 + horizontal: "right"
2812 + },
2813 + transformOrigin: {
2814 + vertical: "top",
2815 + horizontal: "right"
2816 + },
2817 + PaperProps: { sx: { my: 1 } },
2818 + ...(0, _elementor_ui.bindPopover)(popupState)
2819 + }, /* @__PURE__ */ react.createElement(VariableSelectionPopover, {
2820 + selectedVariable: variable,
2821 + closePopover: popupState.close,
2822 + propTypeKey: propTypeUtil.key
2823 + })));
2824 + };
2825 +
2826 +//#endregion
2827 +//#region packages/packages/core/editor-variables/src/components/variable-restore.tsx
2828 + var SIZE = "tiny";
2829 + var VariableRestore = ({ variableId, onClose, onSubmit }) => {
2830 + const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
2831 + const { setVariableValue: notifyBoundPropChange } = useVariableBoundProp();
2832 + const { propType } = (0, _elementor_editor_controls.useBoundProp)();
2833 + const variable = useVariable(variableId);
2834 + if (!variable) throw new Error(`Global ${variableType} variable not found`);
2835 + const [errorMessage, setErrorMessage] = (0, react.useState)("");
2836 + const [valueFieldError, setValueFieldError] = (0, react.useState)("");
2837 + const [label, setLabel] = (0, react.useState)(variable.label);
2838 + const [value, setValue] = (0, react.useState)(variable.value);
2839 + const [propTypeKey, setPropTypeKey] = (0, react.useState)(variable?.type ?? propTypeUtil.key);
2840 + const { labelFieldError, setLabelFieldError } = useLabelError({
2841 + value: variable.label,
2842 + message: ERROR_MESSAGES.DUPLICATED_LABEL
2843 + });
2844 + const handleRestore = () => {
2845 + (propTypeKey !== variable.type ? restoreVariable(variableId, label, value, propTypeKey) : restoreVariable(variableId, label, value)).then(() => {
2846 + notifyBoundPropChange(variableId);
2847 + onSubmit?.();
2848 + }).catch((error) => {
2849 + const mappedError = mapServerError(error);
2850 + if (mappedError && "label" === mappedError.field) {
2851 + setLabel("");
2852 + setLabelFieldError({
2853 + value: label,
2854 + message: mappedError.message
2855 + });
2856 + return;
2857 + }
2858 + setErrorMessage(ERROR_MESSAGES.UNEXPECTED_ERROR);
2859 + });
2860 + };
2861 + const hasEmptyFields = () => {
2862 + if ("" === label.trim()) return true;
2863 + if ("string" === typeof value) return "" === value.trim();
2864 + return false === Boolean(value);
2865 + };
2866 + const noValueChanged = () => {
2867 + return value === variable.value && label === variable.label;
2868 + };
2869 + const hasErrors = () => {
2870 + return !!errorMessage;
2871 + };
2872 + const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
2873 + const handleKeyDown = (event) => {
2874 + if (event.key === "Enter" && !isSubmitDisabled) {
2875 + event.preventDefault();
2876 + handleRestore();
2877 + }
2878 + };
2879 + return /* @__PURE__ */ react.createElement(PopoverContentRefContextProvider, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SectionPopoverBody, { height: "auto" }, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PopoverHeader, {
2880 + icon: /* @__PURE__ */ react.createElement(VariableIcon, { fontSize: SIZE }),
2881 + title: (0, _wordpress_i18n.__)("Restore variable", "elementor"),
2882 + onClose
2883 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverContent, { p: 2 }, /* @__PURE__ */ react.createElement(FormField, {
2884 + id: "variable-label",
2885 + label: (0, _wordpress_i18n.__)("Name", "elementor"),
2886 + errorMsg: labelFieldError?.message,
2887 + noticeMsg: labelHint(label)
2888 + }, /* @__PURE__ */ react.createElement(LabelField, {
2889 + id: "variable-label",
2890 + value: label,
2891 + error: labelFieldError,
2892 + onChange: (newValue) => {
2893 + setLabel(newValue);
2894 + setErrorMessage("");
2895 + },
2896 + onErrorChange: (errorMsg) => {
2897 + setLabelFieldError({
2898 + value: "",
2899 + message: errorMsg
2900 + });
2901 + },
2902 + onKeyDown: handleKeyDown,
2903 + focusOnShow: true
2904 + })), ValueField && /* @__PURE__ */ react.createElement(FormField, {
2905 + errorMsg: valueFieldError,
2906 + label: (0, _wordpress_i18n.__)("Value", "elementor")
2907 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "h5" }, /* @__PURE__ */ react.createElement(ValueField, {
2908 + propTypeKey,
2909 + onPropTypeKeyChange: (key) => setPropTypeKey(key),
2910 + value,
2911 + onChange: (newValue) => {
2912 + setValue(newValue);
2913 + setErrorMessage("");
2914 + setValueFieldError("");
2915 + },
2916 + onValidationChange: setValueFieldError,
2917 + propType,
2918 + onKeyDown: handleKeyDown
2919 + }))), errorMessage && /* @__PURE__ */ react.createElement(_elementor_ui.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ react.createElement(_elementor_ui.CardActions, { sx: {
2920 + pt: .5,
2921 + pb: 1
2922 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
2923 + size: "small",
2924 + variant: "contained",
2925 + disabled: isSubmitDisabled,
2926 + onClick: handleRestore
2927 + }, (0, _wordpress_i18n.__)("Restore", "elementor")))));
2928 + };
2929 +
2930 +//#endregion
2931 +//#region packages/packages/core/editor-variables/src/components/ui/deleted-variable-alert.tsx
2932 + var DeletedVariableAlert = ({ onClose, onUnlink, onRestore, label }) => {
2933 + return /* @__PURE__ */ react.createElement(_elementor_ui.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
2934 + variant: "standard",
2935 + severity: "warning",
2936 + onClose,
2937 + action: /* @__PURE__ */ react.createElement(react.Fragment, null, onUnlink && /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, {
2938 + variant: "contained",
2939 + onClick: onUnlink
2940 + }, (0, _wordpress_i18n.__)("Unlink", "elementor")), onRestore && /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, {
2941 + variant: "outlined",
2942 + onClick: onRestore
2943 + }, (0, _wordpress_i18n.__)("Restore", "elementor"))),
2944 + sx: { maxWidth: 300 }
2945 + }, /* @__PURE__ */ react.createElement(_elementor_ui.AlertTitle, null, (0, _wordpress_i18n.__)("Deleted variable", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2946 + variant: "body2",
2947 + color: "textPrimary"
2948 + }, (0, _wordpress_i18n.__)("The variable", "elementor"), "\xA0'", /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2949 + variant: "body2",
2950 + component: "span",
2951 + sx: { lineBreak: "anywhere" }
2952 + }, label), "'\xA0", (0, _wordpress_i18n.__)("has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.", "elementor"))));
2953 + };
2954 +
2955 +//#endregion
2956 +//#region packages/packages/core/editor-variables/src/components/ui/tags/warning-variable-tag.tsx
2957 + var WarningVariableTag = react.forwardRef(({ label, suffix, onClick, icon, ...props }, ref) => {
2958 + const displayText = suffix ? `${label} (${suffix})` : label;
2959 + return /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
2960 + ref,
2961 + size: "tiny",
2962 + color: "warning",
2963 + shape: "rounded",
2964 + variant: "standard",
2965 + onClick,
2966 + icon: /* @__PURE__ */ react.createElement(_elementor_icons.AlertTriangleFilledIcon, null),
2967 + label: /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
2968 + title: displayText,
2969 + placement: "top"
2970 + }, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
2971 + display: "inline-grid",
2972 + minWidth: 0
2973 + } }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
2974 + variant: "caption",
2975 + noWrap: true,
2976 + sx: { lineHeight: 1.34 }
2977 + }, displayText))),
2978 + sx: {
2979 + height: (theme) => theme.spacing(3.5),
2980 + borderRadius: (theme) => theme.spacing(1),
2981 + justifyContent: "flex-start",
2982 + width: "100%"
2983 + },
2984 + ...props
2985 + });
2986 + });
2987 + WarningVariableTag.displayName = "WarningVariableTag";
2988 +
2989 +//#endregion
2990 +//#region packages/packages/core/editor-variables/src/components/ui/variable/deleted-variable.tsx
2991 + var DeletedVariable = ({ variable, propTypeKey }) => {
2992 + const { propTypeUtil } = getVariableType(propTypeKey);
2993 + const boundProp = (0, _elementor_editor_controls.useBoundProp)();
2994 + const userPermissions = usePermissions();
2995 + const [showInfotip, setShowInfotip] = (0, react.useState)(false);
2996 + const toggleInfotip = () => setShowInfotip((prev) => !prev);
2997 + const closeInfotip = () => setShowInfotip(false);
2998 + const deletedChipAnchorRef = (0, react.useRef)(null);
2999 + const popupState = (0, _elementor_ui.usePopupState)({
3000 + variant: "popover",
3001 + popupId: `elementor-variables-restore-${(0, react.useId)()}`
3002 + });
3003 + const handlers = {};
3004 + if (userPermissions.canUnlink()) handlers.onUnlink = createUnlinkHandler(variable, propTypeKey, boundProp.setValue);
3005 + if (userPermissions.canRestore()) handlers.onRestore = () => {
3006 + if (!variable.key) return;
3007 + restoreVariable(variable.key).then((id) => {
3008 + resolveBoundPropAndSetValue(propTypeUtil.create(id), boundProp);
3009 + closeInfotip();
3010 + }).catch(() => {
3011 + closeInfotip();
3012 + popupState.setAnchorEl(deletedChipAnchorRef.current);
3013 + popupState.open();
3014 + });
3015 + };
3016 + const handleRestoreWithOverrides = () => {
3017 + popupState.close();
3018 + };
3019 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { ref: deletedChipAnchorRef }, showInfotip && /* @__PURE__ */ react.createElement(_elementor_ui.Backdrop, {
3020 + open: true,
3021 + onClick: closeInfotip,
3022 + invisible: true
3023 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Infotip, {
3024 + color: "warning",
3025 + placement: "right-start",
3026 + open: showInfotip,
3027 + disableHoverListener: true,
3028 + onClose: closeInfotip,
3029 + content: /* @__PURE__ */ react.createElement(DeletedVariableAlert, {
3030 + onClose: closeInfotip,
3031 + onUnlink: handlers.onUnlink,
3032 + onRestore: handlers.onRestore,
3033 + label: variable.label
3034 + }),
3035 + slotProps: { popper: { modifiers: [{
3036 + name: "offset",
3037 + options: { offset: [0, 24] }
3038 + }] } }
3039 + }, /* @__PURE__ */ react.createElement(WarningVariableTag, {
3040 + label: variable.label,
3041 + onClick: toggleInfotip,
3042 + suffix: (0, _wordpress_i18n.__)("deleted", "elementor")
3043 + })), /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
3044 + disableScrollLock: true,
3045 + anchorOrigin: {
3046 + vertical: "bottom",
3047 + horizontal: "right"
3048 + },
3049 + transformOrigin: {
3050 + vertical: "top",
3051 + horizontal: "right"
3052 + },
3053 + PaperProps: { sx: { my: 1 } },
3054 + ...(0, _elementor_ui.bindPopover)(popupState)
3055 + }, /* @__PURE__ */ react.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ react.createElement(VariableRestore, {
3056 + variableId: variable.key ?? "",
3057 + onClose: popupState.close,
3058 + onSubmit: handleRestoreWithOverrides
3059 + })))));
3060 + };
3061 +
3062 +//#endregion
3063 +//#region packages/packages/core/editor-variables/src/components/ui/mismatch-variable-alert.tsx
3064 + var i18n = {
3065 + title: (0, _wordpress_i18n.__)("Variable has changed", "elementor"),
3066 + message: (0, _wordpress_i18n.__)(`This variable is no longer compatible with this property. You can clear it or select a different one.`, "elementor"),
3067 + buttons: {
3068 + clear: (0, _wordpress_i18n.__)("Clear", "elementor"),
3069 + select: (0, _wordpress_i18n.__)("Select variable", "elementor")
3070 + }
3071 + };
3072 + var MismatchVariableAlert = ({ onClose, onClear, triggerSelect }) => {
3073 + return /* @__PURE__ */ react.createElement(_elementor_ui.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
3074 + variant: "standard",
3075 + severity: "warning",
3076 + onClose,
3077 + action: /* @__PURE__ */ react.createElement(react.Fragment, null, onClear && /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, {
3078 + variant: "contained",
3079 + onClick: onClear
3080 + }, i18n.buttons.clear), triggerSelect && /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, {
3081 + variant: "outlined",
3082 + onClick: triggerSelect
3083 + }, i18n.buttons.select)),
3084 + sx: { maxWidth: 300 }
3085 + }, /* @__PURE__ */ react.createElement(_elementor_ui.AlertTitle, null, i18n.title), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
3086 + variant: "body2",
3087 + color: "textPrimary"
3088 + }, i18n.message)));
3089 + };
3090 +
3091 +//#endregion
3092 +//#region packages/packages/core/editor-variables/src/components/ui/variable/mismatch-variable.tsx
3093 + var MismatchVariable = ({ variable }) => {
3094 + const { setValue, value } = (0, _elementor_editor_controls.useBoundProp)();
3095 + const anchorRef = (0, react.useRef)(null);
3096 + const popupState = (0, _elementor_ui.usePopupState)({
3097 + variant: "popover",
3098 + popupId: `elementor-variables-list-${(0, react.useId)()}`
3099 + });
3100 + const [infotipVisible, setInfotipVisible] = (0, react.useState)(false);
3101 + const toggleInfotip = () => setInfotipVisible((prev) => !prev);
3102 + const closeInfotip = () => setInfotipVisible(false);
3103 + const triggerSelect = () => {
3104 + closeInfotip();
3105 + popupState.setAnchorEl(anchorRef.current);
3106 + popupState.open();
3107 + };
3108 + const clearValue = () => {
3109 + closeInfotip();
3110 + setValue(null);
3111 + };
3112 + const showClearButton = !!value;
3113 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { ref: anchorRef }, infotipVisible && /* @__PURE__ */ react.createElement(_elementor_ui.Backdrop, {
3114 + open: true,
3115 + onClick: closeInfotip,
3116 + invisible: true
3117 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Infotip, {
3118 + color: "warning",
3119 + placement: "right-start",
3120 + open: infotipVisible,
3121 + disableHoverListener: true,
3122 + onClose: closeInfotip,
3123 + content: /* @__PURE__ */ react.createElement(MismatchVariableAlert, {
3124 + onClose: closeInfotip,
3125 + onClear: showClearButton ? clearValue : void 0,
3126 + triggerSelect
3127 + }),
3128 + slotProps: { popper: { modifiers: [{
3129 + name: "offset",
3130 + options: { offset: [0, 24] }
3131 + }] } }
3132 + }, /* @__PURE__ */ react.createElement(WarningVariableTag, {
3133 + label: variable.label,
3134 + onClick: toggleInfotip,
3135 + suffix: (0, _wordpress_i18n.__)("changed", "elementor")
3136 + })), /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
3137 + disableScrollLock: true,
3138 + anchorEl: anchorRef.current,
3139 + anchorOrigin: {
3140 + vertical: "bottom",
3141 + horizontal: "right"
3142 + },
3143 + transformOrigin: {
3144 + vertical: "top",
3145 + horizontal: "right"
3146 + },
3147 + PaperProps: { sx: { my: 1 } },
3148 + ...(0, _elementor_ui.bindPopover)(popupState)
3149 + }, /* @__PURE__ */ react.createElement(VariableSelectionPopover, {
3150 + selectedVariable: variable,
3151 + closePopover: popupState.close,
3152 + propTypeKey: variable.type
3153 + })));
3154 + };
3155 +
3156 +//#endregion
3157 +//#region packages/packages/core/editor-variables/src/components/ui/missing-variable-alert.tsx
3158 + var MissingVariableAlert = ({ onClose, onClear }) => {
3159 + return /* @__PURE__ */ react.createElement(_elementor_ui.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
3160 + variant: "standard",
3161 + severity: "warning",
3162 + onClose,
3163 + action: /* @__PURE__ */ react.createElement(react.Fragment, null, onClear && /* @__PURE__ */ react.createElement(_elementor_ui.AlertAction, {
3164 + variant: "contained",
3165 + onClick: onClear
3166 + }, (0, _wordpress_i18n.__)("Clear", "elementor"))),
3167 + sx: { maxWidth: 300 }
3168 + }, /* @__PURE__ */ react.createElement(_elementor_ui.AlertTitle, null, (0, _wordpress_i18n.__)("This variable is missing", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
3169 + variant: "body2",
3170 + color: "textPrimary"
3171 + }, (0, _wordpress_i18n.__)("It may have been deleted. Try clearing this field and select a different value or variable.", "elementor"))));
3172 + };
3173 +
3174 +//#endregion
3175 +//#region packages/packages/core/editor-variables/src/components/ui/variable/missing-variable.tsx
3176 + var MissingVariable = () => {
3177 + const { setValue } = (0, _elementor_editor_controls.useBoundProp)();
3178 + const [infotipVisible, setInfotipVisible] = (0, react.useState)(false);
3179 + const toggleInfotip = () => setInfotipVisible((prev) => !prev);
3180 + const closeInfotip = () => setInfotipVisible(false);
3181 + const clearValue = () => setValue(null);
3182 + return /* @__PURE__ */ react.createElement(react.Fragment, null, infotipVisible && /* @__PURE__ */ react.createElement(_elementor_ui.Backdrop, {
3183 + open: true,
3184 + onClick: closeInfotip,
3185 + invisible: true
3186 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Infotip, {
3187 + color: "warning",
3188 + placement: "right-start",
3189 + open: infotipVisible,
3190 + disableHoverListener: true,
3191 + onClose: closeInfotip,
3192 + content: /* @__PURE__ */ react.createElement(MissingVariableAlert, {
3193 + onClose: closeInfotip,
3194 + onClear: clearValue
3195 + }),
3196 + slotProps: { popper: { modifiers: [{
3197 + name: "offset",
3198 + options: { offset: [0, 24] }
3199 + }] } }
3200 + }, /* @__PURE__ */ react.createElement(WarningVariableTag, {
3201 + label: (0, _wordpress_i18n.__)("Missing variable", "elementor"),
3202 + onClick: toggleInfotip
3203 + })));
3204 + };
3205 +
3206 +//#endregion
3207 +//#region packages/packages/core/editor-variables/src/controls/variable-control.tsx
3208 + var VariableControl = () => {
3209 + const boundProp = (0, _elementor_editor_controls.useBoundProp)();
3210 + const boundPropValue = boundProp.value ?? boundProp.placeholder;
3211 + const assignedVariable = useVariable(boundPropValue?.value);
3212 + if (!assignedVariable) return /* @__PURE__ */ react.createElement(MissingVariable, null);
3213 + const { $$type: propTypeKey } = boundPropValue;
3214 + if (assignedVariable?.deleted) return /* @__PURE__ */ react.createElement(DeletedVariable, {
3215 + variable: assignedVariable,
3216 + propTypeKey
3217 + });
3218 + const { isCompatible } = getVariableType(assignedVariable.type);
3219 + if (isCompatible && !isCompatible(boundProp?.propType, assignedVariable)) return /* @__PURE__ */ react.createElement(MismatchVariable, { variable: assignedVariable });
3220 + return /* @__PURE__ */ react.createElement(AssignedVariable, {
3221 + variable: assignedVariable,
3222 + propTypeKey
3223 + });
3224 + };
3225 +
3226 +//#endregion
3227 +//#region packages/packages/core/editor-variables/src/hooks/use-prop-variable-action.tsx
3228 + var usePropVariableAction = () => {
3229 + const { propType, path } = (0, _elementor_editor_controls.useBoundProp)();
3230 + const variable = resolveVariableFromPropType(propType);
3231 + return {
3232 + visible: Boolean(variable),
3233 + icon: _elementor_icons.ColorFilterIcon,
3234 + title: (0, _wordpress_i18n.__)("Variables", "elementor"),
3235 + content: ({ close: closePopover }) => {
3236 + if (!variable) return null;
3237 + trackOpenVariablePopover(path, variable.variableType);
3238 + return /* @__PURE__ */ react.createElement(VariableSelectionPopover, {
3239 + closePopover,
3240 + propTypeKey: variable.propTypeUtil.key
3241 + });
3242 + }
3243 + };
3244 + };
3245 + var resolveVariableFromPropType = (propType) => {
3246 + if (propType.kind !== "union") return;
3247 + for (const key of Object.keys(propType.prop_types)) {
3248 + const variable = getVariableType(key);
3249 + if (variable) return variable;
3250 + }
3251 + };
3252 + var trackOpenVariablePopover = (path, variableType) => {
3253 + trackVariableEvent({
3254 + varType: variableType,
3255 + controlPath: path.join("."),
3256 + action: "open"
3257 + });
3258 + };
3259 +
3260 +//#endregion
3261 +//#region packages/packages/core/editor-variables/src/mcp/variable-tool-prompt.ts
3262 + var MANAGE_VARIABLES_GUIDE_URI = "elementor://variables/tools/manage-global-variable-guide";
3263 +
3264 +//#endregion
3265 +//#region packages/packages/core/editor-variables/src/mcp/variables-resource.ts
3266 + var MCP_PROXY_URL$1 = "elementor/v1/mcp-proxy";
3267 + var GLOBAL_VARIABLES_URI = "elementor://global-variables";
3268 + var initVariablesResource = (variablesMcpEntry, canvasMcpEntry) => {
3269 + [canvasMcpEntry, variablesMcpEntry].forEach((entry) => {
3270 + const { resource, sendResourceUpdated } = entry;
3271 + const notifyGlobalVariablesUpdated = () => {
3272 + sendResourceUpdated({ uri: GLOBAL_VARIABLES_URI });
3273 + };
3274 + resource("global-variables", GLOBAL_VARIABLES_URI, { description: "Global variables available (v4)" }, async (uri) => {
3275 + const { data } = await (0, _elementor_http_client.httpService)().get(MCP_PROXY_URL$1, { params: { uri: uri.href } });
3276 + return { contents: [{
3277 + uri: uri.href,
3278 + mimeType: "application/json",
3279 + text: JSON.stringify(data.data ?? {})
3280 + }] };
3281 + });
3282 + window.addEventListener(STORAGE_UPDATED_EVENT, notifyGlobalVariablesUpdated);
3283 + (0, _elementor_editor_v1_adapters.__privateListenTo)((0, _elementor_editor_v1_adapters.commandEndEvent)("document/save/update"), notifyGlobalVariablesUpdated);
3284 + });
3285 + };
3286 +
3287 +//#endregion
3288 +//#region packages/packages/core/editor-variables/src/mcp/manage-variable-tool.ts
3289 + var MCP_PROXY_URL = "elementor/v1/mcp-proxy";
3290 + var TOOL_NAME = "manage-global-variable";
3291 + var VARIABLE_TYPES = {
3292 + COLOR: "global-color-variable",
3293 + FONT: "global-font-variable",
3294 + SIZE: "global-size-variable",
3295 + CUSTOM_SIZE: "global-custom-size-variable"
3296 + };
3297 + var initManageVariableTool = (reg) => {
3298 + const { addTool, resource } = reg;
3299 + const RUNTIME_ALLOWED_VARIABLE_TYPES = (0, _elementor_utils.isProActive)() ? [
3300 + VARIABLE_TYPES.COLOR,
3301 + VARIABLE_TYPES.FONT,
3302 + VARIABLE_TYPES.SIZE,
3303 + VARIABLE_TYPES.CUSTOM_SIZE
3304 + ] : [VARIABLE_TYPES.COLOR, VARIABLE_TYPES.FONT];
3305 + resource("manage-global-variable-guide", MANAGE_VARIABLES_GUIDE_URI, {
3306 + title: "Manage Global Variable Guide",
3307 + description: "Detailed guide for using the manage-global-variable tool",
3308 + mimeType: "text/plain"
3309 + }, async (uri) => {
3310 + const { data } = await (0, _elementor_http_client.httpService)().get(MCP_PROXY_URL, { params: { uri: uri.href } });
3311 + return { contents: [{
3312 + uri: uri.href,
3313 + mimeType: "text/plain",
3314 + text: data.data
3315 + }] };
3316 + });
3317 + addTool({
3318 + name: TOOL_NAME,
3319 + description: "Manage V4 global variables (color, font, size, custom-size). Read the guide resource before use. font = single Google Font family name, no fallback stacks, size = measured unit, custom-size = calculated values",
3320 + schema: {
3321 + action: _elementor_schema.z.enum([
3322 + "create",
3323 + "update",
3324 + "delete"
3325 + ]),
3326 + id: _elementor_schema.z.string().optional().describe("Variable id — required for update/delete. Get from the global-variables resource."),
3327 + type: _elementor_schema.z.enum(RUNTIME_ALLOWED_VARIABLE_TYPES),
3328 + label: _elementor_schema.z.string().describe("Variable label (lowercase, dash-separated) — required for create/update."),
3329 + value: _elementor_schema.z.string().optional().describe("Plain CSS value — required for create/update. Color: hex/rgba/hsl. Font: single Google Font family name only — no fallback stacks, no generic families. Size: value with unit e.g. \"16px\", or \"auto\" (Pro). Do NOT pass JSON.")
3330 + },
3331 + outputSchema: {
3332 + status: _elementor_schema.z.enum(["ok"]).describe("Operation status"),
3333 + message: _elementor_schema.z.string().optional().describe("Error details if status is error")
3334 + },
3335 + requiredResources: [{
3336 + uri: MANAGE_VARIABLES_GUIDE_URI,
3337 + description: "Full guide for variable types, naming rules, and usage"
3338 + }, {
3339 + uri: GLOBAL_VARIABLES_URI,
3340 + description: "Current global variables — check before creating to avoid duplicates"
3341 + }],
3342 + isDestructive: true,
3343 + handler: async (params) => {
3344 + const { data } = await (0, _elementor_http_client.httpService)().post(MCP_PROXY_URL, {
3345 + tool: TOOL_NAME,
3346 + input: params
3347 + });
3348 + const payload = data.data;
3349 + if (payload.variable && typeof payload.watermark === "number") applyLocalMutation(params.action, payload.variable, payload.watermark);
3350 + return { status: "ok" };
3351 + }
3352 + });
3353 + };
3354 +
3355 +//#endregion
3356 +//#region packages/packages/core/editor-variables/src/mcp/index.ts
3357 + function initMcp(reg, canvasMcpEntry) {
3358 + window.addEventListener("elementor/init", () => {
3359 + initManageVariableTool(reg);
3360 + initVariablesResource(reg, canvasMcpEntry);
3361 + }, { once: true });
3362 + }
3363 +
3364 +//#endregion
3365 +//#region packages/packages/core/editor-variables/src/components/fields/color-field.tsx
3366 + var ColorField = ({ value, onChange, onValidationChange }) => {
3367 + const [color, setColor] = (0, react.useState)(value);
3368 + const [errorMessage, setErrorMessage] = (0, react.useState)("");
3369 + const defaultRef = (0, react.useRef)(null);
3370 + const anchorRef = usePopoverContentRef() ?? defaultRef.current;
3371 + const handleChange = (newValue) => {
3372 + setColor(newValue);
3373 + const errorMsg = validateValue(newValue);
3374 + setErrorMessage(errorMsg);
3375 + onValidationChange?.(errorMsg);
3376 + onChange(errorMsg ? "" : newValue);
3377 + };
3378 + return /* @__PURE__ */ react.createElement(_elementor_ui.UnstableColorField, {
3379 + id: "color-variable-field",
3380 + size: "tiny",
3381 + fullWidth: true,
3382 + value: color,
3383 + onChange: handleChange,
3384 + error: errorMessage || void 0,
3385 + slotProps: { colorPicker: {
3386 + anchorEl: anchorRef,
3387 + anchorOrigin: {
3388 + vertical: "top",
3389 + horizontal: "right"
3390 + },
3391 + transformOrigin: {
3392 + vertical: "top",
3393 + horizontal: -10
3394 + },
3395 + slotProps: { colorIndicator: {
3396 + size: "inherit",
3397 + sx: { borderRadius: .5 }
3398 + } }
3399 + } }
3400 + });
3401 + };
3402 +
3403 +//#endregion
3404 +//#region packages/packages/core/editor-variables/src/components/fields/font-field.tsx
3405 + var FontField = ({ value, onChange, onValidationChange }) => {
3406 + const [fontFamily, setFontFamily] = (0, react.useState)(value);
3407 + const defaultRef = (0, react.useRef)(null);
3408 + const anchorRef = usePopoverContentRef() ?? defaultRef.current;
3409 + const fontPopoverState = (0, _elementor_ui.usePopupState)({ variant: "popover" });
3410 + const fontFamilies = (0, _elementor_editor_controls.useFontFamilies)();
3411 + const sectionWidth = (0, _elementor_editor_ui.useSectionWidth)();
3412 + const mapFontSubs = (0, react.useMemo)(() => {
3413 + return fontFamilies.map(({ label, fonts }) => ({
3414 + label,
3415 + items: fonts
3416 + }));
3417 + }, [fontFamilies]);
3418 + const handleChange = (newValue) => {
3419 + setFontFamily(newValue);
3420 + const errorMsg = validateValue(newValue);
3421 + onValidationChange?.(errorMsg);
3422 + onChange(errorMsg ? "" : newValue);
3423 + };
3424 + const handleFontFamilyChange = (newFontFamily) => {
3425 + handleChange(newFontFamily);
3426 + fontPopoverState.close();
3427 + };
3428 + const id = (0, react.useId)();
3429 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.UnstableTag, {
3430 + id,
3431 + variant: "outlined",
3432 + label: fontFamily,
3433 + endIcon: /* @__PURE__ */ react.createElement(_elementor_icons.ChevronDownIcon, { fontSize: "tiny" }),
3434 + ...(0, _elementor_ui.bindTrigger)(fontPopoverState),
3435 + fullWidth: true
3436 + }), /* @__PURE__ */ react.createElement(_elementor_ui.Popover, {
3437 + disablePortal: true,
3438 + disableScrollLock: true,
3439 + anchorEl: anchorRef,
3440 + anchorOrigin: {
3441 + vertical: "top",
3442 + horizontal: "right"
3443 + },
3444 + transformOrigin: {
3445 + vertical: "top",
3446 + horizontal: -28
3447 + },
3448 + ...(0, _elementor_ui.bindPopover)(fontPopoverState)
3449 + }, /* @__PURE__ */ react.createElement(_elementor_editor_controls.ItemSelector, {
3450 + id: "font-family-variables-selector",
3451 + itemsList: mapFontSubs,
3452 + selectedItem: fontFamily,
3453 + onItemChange: handleFontFamilyChange,
3454 + onClose: fontPopoverState.close,
3455 + sectionWidth,
3456 + title: (0, _wordpress_i18n.__)("Font family", "elementor"),
3457 + itemStyle: (item) => ({ fontFamily: item.value }),
3458 + onDebounce: _elementor_editor_controls.enqueueFont,
3459 + icon: _elementor_icons.TextIcon
3460 + })));
3461 + };
3462 +
3463 +//#endregion
3464 +//#region packages/packages/core/editor-variables/src/prop-types/size-variable-prop-type.ts
3465 + var sizeVariablePropTypeUtil = (0, _elementor_editor_props.createPropUtils)("global-size-variable", _elementor_schema.z.string());
3466 +
3467 +//#endregion
3468 +//#region packages/packages/core/editor-variables/src/transformers/empty-transformer.tsx
3469 + var EmptyTransformer = (0, _elementor_editor_canvas.createTransformer)((_value) => {
3470 + return null;
3471 + });
3472 +
3473 +//#endregion
3474 +//#region packages/packages/core/editor-variables/src/register-variable-types.tsx
3475 + function registerVariableTypes() {
3476 + registerVariableType({
3477 + key: colorVariablePropTypeUtil.key,
3478 + valueField: ColorField,
3479 + icon: _elementor_icons.BrushIcon,
3480 + propTypeUtil: colorVariablePropTypeUtil,
3481 + fallbackPropTypeUtil: _elementor_editor_props.colorPropTypeUtil,
3482 + variableType: "color",
3483 + startIcon: ({ value }) => /* @__PURE__ */ react.createElement(ColorIndicator, {
3484 + size: "inherit",
3485 + component: "span",
3486 + value
3487 + }),
3488 + defaultValue: "#ffffff",
3489 + menuActionsFactory: ({ variable, variableId, handlers }) => {
3490 + const actions = [];
3491 + if (variable.sync_to_v3) actions.push({
3492 + name: (0, _wordpress_i18n.__)("Stop syncing to Global Colors", "elementor"),
3493 + icon: _elementor_icons.RefreshOffIcon,
3494 + color: "text.primary",
3495 + onClick: () => handlers.onStopSync(variableId)
3496 + });
3497 + else actions.push({
3498 + name: (0, _wordpress_i18n.__)("Sync to Global Colors", "elementor"),
3499 + icon: _elementor_icons.RefreshIcon,
3500 + color: "text.primary",
3501 + onClick: () => handlers.onStartSync(variableId)
3502 + });
3503 + return actions;
3504 + }
3505 + });
3506 + registerVariableType({
3507 + key: fontVariablePropTypeUtil.key,
3508 + valueField: FontField,
3509 + icon: _elementor_icons.TextIcon,
3510 + propTypeUtil: fontVariablePropTypeUtil,
3511 + fallbackPropTypeUtil: _elementor_editor_props.stringPropTypeUtil,
3512 + variableType: "font",
3513 + defaultValue: "Roboto"
3514 + });
3515 + const sizePromotions = {
3516 + isActive: false,
3517 + icon: _elementor_icons.ExpandDiagonalIcon,
3518 + propTypeUtil: sizeVariablePropTypeUtil,
3519 + fallbackPropTypeUtil: _elementor_editor_props.sizePropTypeUtil,
3520 + styleTransformer: EmptyTransformer,
3521 + variableType: "size",
3522 + selectionFilter: () => [],
3523 + emptyState: /* @__PURE__ */ react.createElement(_elementor_editor_ui.CtaButton, {
3524 + size: "small",
3525 + href: "https://go.elementor.com/go-pro-panel-size-variable/",
3526 + onClick: () => (0, _elementor_editor_controls.trackUpgradePromotionClick)({
3527 + target_name: "variables_popover",
3528 + location_l1: "variables_list"
3529 + })
3530 + })
3531 + };
3532 + registerVariableType({
3533 + ...sizePromotions,
3534 + key: sizeVariablePropTypeUtil.key,
3535 + defaultValue: "0px"
3536 + });
3537 + registerVariableType({
3538 + ...sizePromotions,
3539 + key: "global-custom-size-variable"
3540 + });
3541 + }
3542 +
3543 +//#endregion
3544 +//#region packages/packages/core/editor-variables/src/renderers/style-variables-renderer.tsx
3545 + var VARIABLES_WRAPPER = ":root";
3546 + function StyleVariablesRenderer() {
3547 + const container = usePortalContainer();
3548 + const styleVariables = useStyleVariables();
3549 + const hasVariables = Object.keys(styleVariables).length > 0;
3550 + if (!container || !hasVariables) return null;
3551 + const cssVariables = convertToCssVariables(styleVariables);
3552 + const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
3553 + return /* @__PURE__ */ react.createElement(_elementor_ui.Portal, { container }, /* @__PURE__ */ react.createElement("style", {
3554 + "data-e-style-id": "e-variables",
3555 + key: wrappedCss
3556 + }, wrappedCss));
3557 + }
3558 + function usePortalContainer() {
3559 + return (0, _elementor_editor_v1_adapters.__privateUseListenTo)((0, _elementor_editor_v1_adapters.commandEndEvent)("editor/documents/attach-preview"), () => (0, _elementor_editor_v1_adapters.getCanvasIframeDocument)()?.head);
3560 + }
3561 + function useStyleVariables() {
3562 + const [variables, setVariables] = (0, react.useState)({});
3563 + (0, react.useEffect)(() => {
3564 + const unsubscribe = styleVariablesRepository.subscribe(setVariables);
3565 + return () => {
3566 + unsubscribe();
3567 + };
3568 + }, []);
3569 + return variables;
3570 + }
3571 + function cssVariableDeclaration(key, variable) {
3572 + return `--${variable?.deleted ? key : variable.label}:${variable.value};`;
3573 + }
3574 + function convertToCssVariables(variables) {
3575 + return Object.entries(variables).map(([key, variable]) => cssVariableDeclaration(key, variable)).join("");
3576 + }
3577 +
3578 +//#endregion
3579 +//#region packages/packages/core/editor-variables/src/prop-types/custom-size-variable-prop-type.ts
3580 + var customSizeVariablePropTypeUtil = (0, _elementor_editor_props.createPropUtils)("global-custom-size-variable", _elementor_schema.z.string());
3581 +
3582 +//#endregion
3583 +//#region packages/packages/core/editor-variables/src/utils/size-value.ts
3584 + var DEFAULT_UNIT = "px";
3585 + var CUSTOM_SIZE_LABEL = "fx";
3586 + function sizeValue(value) {
3587 + if (sizeVariablePropTypeUtil.isValid(value) || customSizeVariablePropTypeUtil.isValid(value)) return getVariable(value?.value)?.value;
3588 + if (_elementor_editor_props.sizePropTypeUtil.isValid(value)) {
3589 + const { size, unit } = value.value;
3590 + if ("custom" !== unit) return `${size ?? 0}${unit ?? DEFAULT_UNIT}`;
3591 + if (!size) return CUSTOM_SIZE_LABEL;
3592 + return size;
3593 + }
3594 + return "";
3595 + }
3596 +
3597 +//#endregion
3598 +//#region packages/packages/core/editor-variables/src/components/variables-repeater-item-slot.tsx
3599 + var useColorVariable = (value) => {
3600 + const variableId = value?.value?.color?.value;
3601 + return getVariable(variableId || "");
3602 + };
3603 + var BackgroundRepeaterColorIndicator = ({ value }) => {
3604 + const colorVariable = useColorVariable(value);
3605 + return /* @__PURE__ */ react.createElement(ColorIndicator, {
3606 + component: "span",
3607 + size: "inherit",
3608 + value: colorVariable?.value
3609 + });
3610 + };
3611 + var BackgroundRepeaterLabel = ({ value }) => {
3612 + const colorVariable = useColorVariable(value);
3613 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, colorVariable?.label);
3614 + };
3615 + var BoxShadowRepeaterColorIndicator = ({ value }) => {
3616 + const colorVariable = useColorVariable(value);
3617 + return /* @__PURE__ */ react.createElement(ColorIndicator, {
3618 + component: "span",
3619 + size: "inherit",
3620 + value: colorVariable?.value
3621 + });
3622 + };
3623 + var FilterDropShadowIconIndicator = ({ value }) => {
3624 + const { args } = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value) || {};
3625 + const { color } = _elementor_editor_props.dropShadowFilterPropTypeUtil.extract(args) || {};
3626 + const colorVariable = getVariable(color?.value || "");
3627 + return /* @__PURE__ */ react.createElement(ColorIndicator, {
3628 + component: "span",
3629 + size: "inherit",
3630 + value: colorVariable?.value
3631 + });
3632 + };
3633 + var FilterSingleSizeRepeaterLabel = ({ value }) => {
3634 + const cssFilterFunction = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value);
3635 + if (_elementor_editor_props.dropShadowFilterPropTypeUtil.isValid(cssFilterFunction?.args)) return null;
3636 + const args = cssFilterFunction?.args;
3637 + const func = cssFilterFunction?.func?.value ?? "";
3638 + const rendered = sizeValue(args?.value?.size);
3639 + return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
3640 + component: "span",
3641 + style: { textTransform: "capitalize" }
3642 + }, `${func}: `), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, rendered));
3643 + };
3644 + var FilterDropShadowRepeaterLabel = ({ value }) => {
3645 + const { args } = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value) || {};
3646 + const { xAxis, yAxis, blur } = _elementor_editor_props.dropShadowFilterPropTypeUtil.extract(args) || {};
3647 + const labels = [];
3648 + for (const val of [
3649 + xAxis,
3650 + yAxis,
3651 + blur
3652 + ]) {
3653 + const rendered = sizeValue(val);
3654 + if (rendered) labels.push(rendered);
3655 + }
3656 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, (0, _wordpress_i18n.__)("Drop shadow:", "elementor"), " ", labels.join(" "));
3657 + };
3658 + var BoxShadowRepeaterLabel = ({ value }) => {
3659 + const { position, hOffset, vOffset, blur, spread } = _elementor_editor_props.shadowPropTypeUtil.extract(value) || {};
3660 + const labels = [];
3661 + for (const val of [
3662 + hOffset,
3663 + vOffset,
3664 + blur,
3665 + spread
3666 + ]) {
3667 + const rendered = sizeValue(val);
3668 + if (rendered) labels.push(rendered);
3669 + }
3670 + const positionLabel = position?.value || "outset";
3671 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
3672 + component: "span",
3673 + style: { textTransform: "capitalize" }
3674 + }, positionLabel, ": ", labels.join(" "));
3675 + };
3676 + var TransformRepeaterLabel = ({ value }) => {
3677 + const labels = [];
3678 + if (_elementor_editor_props.moveTransformPropTypeUtil.isValid(value)) {
3679 + labels.push((0, _wordpress_i18n.__)("Move:", "elementor"));
3680 + const { x, y, z } = _elementor_editor_props.moveTransformPropTypeUtil.extract(value) || {};
3681 + for (const val of [
3682 + x,
3683 + y,
3684 + z
3685 + ]) {
3686 + const rendered = sizeValue(val);
3687 + if (rendered) labels.push(rendered);
3688 + }
3689 + }
3690 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, labels.join(" "));
3691 + };
3692 + var TransitionsSizeVariableLabel = ({ value: prop }) => {
3693 + let label = "";
3694 + const variable = getVariable(prop?.value?.size?.value || "");
3695 + if (variable && _elementor_editor_props.selectionSizePropTypeUtil.isValid(prop)) {
3696 + const selection = prop.value?.selection?.value?.key?.value;
3697 + if (selection) label += `${selection}: `;
3698 + label += variable?.value;
3699 + }
3700 + return /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, label);
3701 + };
3702 +
3703 +//#endregion
3704 +//#region packages/packages/core/editor-variables/src/repeater-injections.ts
3705 + function registerRepeaterInjections() {
3706 + backgroundOverlayRepeaterInjections();
3707 + boxShadowRepeaterInjections();
3708 + transitionsRepeaterInjections();
3709 + transformRepeaterInjections();
3710 + filterRepeaterInjections();
3711 + }
3712 + function backgroundOverlayRepeaterInjections() {
3713 + (0, _elementor_editor_controls.injectIntoRepeaterItemIcon)({
3714 + id: "background-color-variables-icon",
3715 + component: BackgroundRepeaterColorIndicator,
3716 + condition: ({ value }) => {
3717 + return hasAssignedColorVariable(_elementor_editor_props.backgroundColorOverlayPropTypeUtil.extract(value)?.color);
3718 + }
3719 + });
3720 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3721 + id: "background-color-variables-label",
3722 + component: BackgroundRepeaterLabel,
3723 + condition: ({ value }) => {
3724 + return hasAssignedColorVariable(_elementor_editor_props.backgroundColorOverlayPropTypeUtil.extract(value)?.color);
3725 + }
3726 + });
3727 + }
3728 + function boxShadowRepeaterInjections() {
3729 + (0, _elementor_editor_controls.injectIntoRepeaterItemIcon)({
3730 + id: "box-shadow-color-variables-icon",
3731 + component: BoxShadowRepeaterColorIndicator,
3732 + condition: ({ value }) => {
3733 + const { color } = _elementor_editor_props.shadowPropTypeUtil.extract(value) || {};
3734 + return hasAssignedColorVariable(color);
3735 + }
3736 + });
3737 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3738 + id: "color-variables-box-shadow-label",
3739 + component: BoxShadowRepeaterLabel,
3740 + condition: ({ value }) => {
3741 + const { hOffset, vOffset, blur, spread } = _elementor_editor_props.shadowPropTypeUtil.extract(value) || {};
3742 + return hasAssignedSizeVariable(hOffset) || hasAssignedSizeVariable(vOffset) || hasAssignedSizeVariable(blur) || hasAssignedSizeVariable(spread);
3743 + }
3744 + });
3745 + }
3746 + function transformRepeaterInjections() {
3747 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3748 + id: "transform-size-variables-label",
3749 + component: TransformRepeaterLabel,
3750 + condition: ({ value }) => {
3751 + if (_elementor_editor_props.moveTransformPropTypeUtil.isValid(value)) {
3752 + const { x: xAxis, y: yAxis, z: zAxis } = _elementor_editor_props.moveTransformPropTypeUtil.extract(value) || {};
3753 + return hasAssignedSizeVariable(xAxis) || hasAssignedSizeVariable(yAxis) || hasAssignedSizeVariable(zAxis);
3754 + }
3755 + return false;
3756 + }
3757 + });
3758 + }
3759 + function transitionsRepeaterInjections() {
3760 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3761 + id: "transition-size-variables-label",
3762 + component: TransitionsSizeVariableLabel,
3763 + condition: ({ value }) => {
3764 + return hasAssignedSizeVariable(_elementor_editor_props.selectionSizePropTypeUtil.extract(value)?.size);
3765 + }
3766 + });
3767 + }
3768 + function filterRepeaterInjections() {
3769 + (0, _elementor_editor_controls.injectIntoRepeaterItemIcon)({
3770 + id: "filters-color-variables-icon",
3771 + component: FilterDropShadowIconIndicator,
3772 + condition: ({ value }) => {
3773 + if (!_elementor_editor_props.cssFilterFunctionPropUtil.isValid(value)) return false;
3774 + const args = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value)?.args;
3775 + if (_elementor_editor_props.dropShadowFilterPropTypeUtil.isValid(args)) return hasAssignedColorVariable(_elementor_editor_props.dropShadowFilterPropTypeUtil.extract(args)?.color);
3776 + return false;
3777 + }
3778 + });
3779 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3780 + id: "filters-drop-shadow-size-variables-label",
3781 + component: FilterDropShadowRepeaterLabel,
3782 + condition: ({ value }) => {
3783 + if (!_elementor_editor_props.cssFilterFunctionPropUtil.isValid(value)) return false;
3784 + const args = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value)?.args;
3785 + if (_elementor_editor_props.dropShadowFilterPropTypeUtil.isValid(args)) {
3786 + const { xAxis, yAxis, blur } = _elementor_editor_props.dropShadowFilterPropTypeUtil.extract(args) || {};
3787 + return hasAssignedSizeVariable(xAxis) || hasAssignedSizeVariable(yAxis) || hasAssignedSizeVariable(blur);
3788 + }
3789 + return false;
3790 + }
3791 + });
3792 + (0, _elementor_editor_controls.injectIntoRepeaterItemLabel)({
3793 + id: "filters-size-variables-label",
3794 + component: FilterSingleSizeRepeaterLabel,
3795 + condition: ({ value }) => {
3796 + if (!_elementor_editor_props.cssFilterFunctionPropUtil.isValid(value)) return false;
3797 + const args = _elementor_editor_props.cssFilterFunctionPropUtil.extract(value)?.args;
3798 + return hasAssignedSizeVariable(args?.value?.size);
3799 + }
3800 + });
3801 + }
3802 + function hasAssignedSizeVariable(value) {
3803 + if (sizeVariablePropTypeUtil.isValid(value)) return true;
3804 + if (customSizeVariablePropTypeUtil.isValid(value)) return true;
3805 + return false;
3806 + }
3807 + function hasAssignedColorVariable(value) {
3808 + return !!colorVariablePropTypeUtil.isValid(value);
3809 + }
3810 +
3811 +//#endregion
3812 +//#region packages/packages/core/editor-variables/src/init.ts
3813 + var { registerPopoverAction } = _elementor_menus.controlActionsMenu;
3814 + function init() {
3815 + registerVariableTypes();
3816 + registerRepeaterInjections();
3817 + (0, _elementor_editor_controls.registerControlReplacement)({
3818 + component: VariableControl,
3819 + condition: ({ value, placeholder }) => {
3820 + if (hasVariableAssigned(value)) return true;
3821 + if (value) return false;
3822 + return hasVariableAssigned(placeholder);
3823 + }
3824 + });
3825 + registerPopoverAction({
3826 + id: "variables",
3827 + priority: 40,
3828 + useProps: usePropVariableAction
3829 + });
3830 + service.init();
3831 + initMcp((0, _elementor_editor_mcp.getMCPByDomain)("variables", { instructions: `Everything related to V4 ( Atomic ) variables.
3832 +# Global variables
3833 +- Create/update/delete global variables
3834 +- Get list of global variables
3835 +- Get details of a global variable
3836 +` }), (0, _elementor_editor_mcp.getMCPByDomain)("canvas"));
3837 + (0, _elementor_editor.injectIntoTop)({
3838 + id: "canvas-style-variables-render",
3839 + component: StyleVariablesRenderer
3840 + });
3841 + (0, _elementor_editor.injectIntoLogic)({
3842 + id: "variables-import-listener",
3843 + component: GlobalStylesImportListener
3844 + });
3845 + (0, _elementor_editor.injectIntoLogic)({
3846 + id: "mcp-variable-connect-listener",
3847 + component: McpVariableConnectListener
3848 + });
3849 + }
3850 + function hasVariableAssigned(value) {
3851 + if ((0, _elementor_editor_props.isTransformable)(value)) return hasVariableType(value.$$type);
3852 + return false;
3853 + }
3854 +
3855 +//#endregion
3856 +//#region packages/packages/core/editor-variables/src/utils/llm-propvalue-label-resolver.ts
3857 + var defaultResolver = (key) => (value) => {
3858 + const idOrLabel = String(value);
3859 + return {
3860 + $$type: key,
3861 + value: service.variables()[idOrLabel] ? idOrLabel : service.findIdByLabel(idOrLabel)
3862 + };
3863 + };
3864 + var globalVariablesLLMResolvers = {
3865 + "global-color-variable": defaultResolver("global-color-variable"),
3866 + "global-font-variable": defaultResolver("global-font-variable"),
3867 + "global-size-variable": defaultResolver("global-size-variable")
3868 + };
3869 +
3870 +//#endregion
3871 +//#region packages/packages/core/editor-variables/src/index.ts
3872 + var src_exports = /* @__PURE__ */ __exportAll({
3873 + GLOBAL_VARIABLES_URI: () => GLOBAL_VARIABLES_URI,
3874 + Utils: () => Utils,
3875 + VariablesManagerPanelEmbedded: () => VariablesManagerPanelEmbedded,
3876 + getMenuActionsForVariable: () => getMenuActionsForVariable,
3877 + hasVariable: () => hasVariable,
3878 + init: () => init,
3879 + registerVariableType: () => registerVariableType,
3880 + registerVariableTypes: () => registerVariableTypes,
3881 + service: () => service,
3882 + sizeVariablePropTypeUtil: () => sizeVariablePropTypeUtil,
3883 + trackVariablesManagerEvent: () => trackVariablesManagerEvent
3884 + });
3885 + var Utils = { globalVariablesLLMResolvers };
3886 +
3887 +//#endregion
3888 +//#region \0elementor-package-library-entry
3889 + (window.elementorV2 = window.elementorV2 || {}).editorVariables = src_exports;
3890 +
3891 +//#endregion
3892 +})(React, elementorV2.editorCurrentUser, elementorV2.editorPanels, elementorV2.editorUi, elementorV2.icons, elementorV2.ui, wp.i18n, elementorV2.events, elementorV2.editorCanvas, elementorV2.editorProps, elementorV2.schema, elementorV2.httpClient, elementorV2.editorV1Adapters, elementorV2.editorControls, elementorV2.utils, elementorV2.editor, elementorV2.editorMcp, elementorV2.menus);
3893 +window.elementorV2.editorVariables?.init?.();
3 3894 //# sourceMappingURL=editor-variables.js.map