@elementor/editor-variables 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/dist/index.js +938 -344
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +950 -335
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +11 -10
  7. package/src/components/color-variable-creation.tsx +39 -16
  8. package/src/components/color-variable-edit.tsx +133 -0
  9. package/src/components/color-variables-selection.tsx +111 -52
  10. package/src/components/font-variable-creation.tsx +30 -16
  11. package/src/components/font-variable-edit.tsx +163 -0
  12. package/src/components/font-variables-selection.tsx +110 -51
  13. package/src/components/{color-indicator.tsx → ui/color-indicator.tsx} +1 -0
  14. package/src/components/ui/menu-item-content.tsx +60 -0
  15. package/src/components/ui/no-search-results.tsx +36 -0
  16. package/src/components/ui/no-variables.tsx +36 -0
  17. package/src/components/ui/styled-menu-list.tsx +31 -0
  18. package/src/components/ui/variable-tag.tsx +43 -0
  19. package/src/components/variable-selection-popover.context.ts +7 -0
  20. package/src/components/variable-selection-popover.tsx +142 -0
  21. package/src/components/variables-repeater-item-slot.tsx +29 -0
  22. package/src/controls/color-variable-control.tsx +66 -0
  23. package/src/controls/font-variable-control.tsx +60 -0
  24. package/src/create-style-variables-repository.ts +3 -2
  25. package/src/hooks/use-prop-color-variable-action.tsx +7 -2
  26. package/src/hooks/use-prop-font-variable-action.tsx +7 -2
  27. package/src/hooks/use-prop-variables.ts +34 -13
  28. package/src/init-color-variables.ts +51 -3
  29. package/src/init-font-variables.ts +2 -2
  30. package/src/service.ts +23 -3
  31. package/src/storage.ts +5 -1
  32. package/src/types.ts +12 -8
  33. package/src/components/styled-menu-item.tsx +0 -10
  34. package/src/components/variables-selection-popover.tsx +0 -119
  35. package/src/controls/color-variables-selection-control.tsx +0 -34
  36. package/src/controls/font-variables-selection-control.tsx +0 -29
package/dist/index.mjs CHANGED
@@ -3,25 +3,12 @@ import { injectIntoTop } from "@elementor/editor";
3
3
 
4
4
  // src/init-color-variables.ts
5
5
  import { styleTransformersRegistry } from "@elementor/editor-canvas";
6
+ import { injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel } from "@elementor/editor-controls";
6
7
  import { controlActionsMenu, registerControlReplacement } from "@elementor/editor-editing-panel";
8
+ import { backgroundColorOverlayPropTypeUtil, shadowPropTypeUtil } from "@elementor/editor-props";
7
9
 
8
- // src/controls/color-variables-selection-control.tsx
9
- import * as React5 from "react";
10
- import { useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
11
- import { colorPropTypeUtil } from "@elementor/editor-props";
12
-
13
- // src/components/color-indicator.tsx
14
- import { styled, UnstableColorIndicator } from "@elementor/ui";
15
- var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
16
- borderRadius: `${theme.shape.borderRadius / 2}px`
17
- }));
18
-
19
- // src/components/color-variables-selection.tsx
10
+ // src/components/variables-repeater-item-slot.tsx
20
11
  import * as React from "react";
21
- import { Fragment } from "react";
22
- import { useBoundProp } from "@elementor/editor-controls";
23
- import { EditIcon } from "@elementor/icons";
24
- import { Box, Divider, ListItemIcon, ListItemText, MenuList } from "@elementor/ui";
25
12
 
26
13
  // src/hooks/use-prop-variables.ts
27
14
  import { useMemo } from "react";
@@ -74,8 +61,11 @@ var Storage = class {
74
61
  return this.state.variables;
75
62
  }
76
63
  fill(variables, watermark) {
64
+ this.state.variables = {};
65
+ if (variables && Object.keys(variables).length) {
66
+ this.state.variables = variables;
67
+ }
77
68
  this.state.watermark = watermark;
78
- this.state.variables = variables;
79
69
  localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
80
70
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
81
71
  }
@@ -105,6 +95,49 @@ var Storage = class {
105
95
  }
106
96
  };
107
97
 
98
+ // src/create-style-variables-repository.ts
99
+ var createStyleVariablesRepository = () => {
100
+ const variables = {};
101
+ let subscription;
102
+ const subscribe = (cb) => {
103
+ subscription = cb;
104
+ return () => {
105
+ subscription = () => {
106
+ };
107
+ };
108
+ };
109
+ const notify = () => {
110
+ if (typeof subscription === "function") {
111
+ subscription({ ...variables });
112
+ }
113
+ };
114
+ const shouldUpdate = (key, newValue) => {
115
+ return !(key in variables) || variables[key] !== newValue;
116
+ };
117
+ const applyUpdates = (updatedVars) => {
118
+ let hasChanges = false;
119
+ for (const [key, { value }] of Object.entries(updatedVars)) {
120
+ if (shouldUpdate(key, value)) {
121
+ variables[key] = value;
122
+ hasChanges = true;
123
+ }
124
+ }
125
+ return hasChanges;
126
+ };
127
+ const update = (updatedVars) => {
128
+ if (applyUpdates(updatedVars)) {
129
+ notify();
130
+ }
131
+ };
132
+ return {
133
+ subscribe,
134
+ update
135
+ };
136
+ };
137
+
138
+ // src/style-variables-repository.ts
139
+ var styleVariablesRepository = createStyleVariablesRepository();
140
+
108
141
  // src/service.ts
109
142
  var storage = new Storage();
110
143
  var service = {
@@ -124,6 +157,7 @@ var service = {
124
157
  }).then((data) => {
125
158
  const { variables, watermark } = data;
126
159
  storage.fill(variables, watermark);
160
+ styleVariablesRepository.update(variables);
127
161
  return variables;
128
162
  });
129
163
  },
@@ -139,6 +173,9 @@ var service = {
139
173
  handleWatermark(OP_RW, watermark);
140
174
  const { id: variableId, ...createdVariable } = variable;
141
175
  storage.add(variableId, createdVariable);
176
+ styleVariablesRepository.update({
177
+ [variableId]: createdVariable
178
+ });
142
179
  return {
143
180
  id: variableId,
144
181
  variable: createdVariable
@@ -157,6 +194,9 @@ var service = {
157
194
  handleWatermark(OP_RW, watermark);
158
195
  const { id: variableId, ...updatedVariable } = variable;
159
196
  storage.update(variableId, updatedVariable);
197
+ styleVariablesRepository.update({
198
+ [variableId]: updatedVariable
199
+ });
160
200
  return {
161
201
  id: variableId,
162
202
  variable: updatedVariable
@@ -175,6 +215,9 @@ var service = {
175
215
  handleWatermark(OP_RW, watermark);
176
216
  const { id: variableId, ...deletedVariable } = variable;
177
217
  storage.update(variableId, deletedVariable);
218
+ styleVariablesRepository.update({
219
+ [variableId]: deletedVariable
220
+ });
178
221
  return {
179
222
  id: variableId,
180
223
  variable: deletedVariable
@@ -193,6 +236,9 @@ var service = {
193
236
  handleWatermark(OP_RW, watermark);
194
237
  const { id: variableId, ...restoredVariable } = variable;
195
238
  storage.update(variableId, restoredVariable);
239
+ styleVariablesRepository.update({
240
+ [variableId]: restoredVariable
241
+ });
196
242
  return {
197
243
  id: variableId,
198
244
  variable: restoredVariable
@@ -207,53 +253,7 @@ var handleWatermark = (operation, newWatermark) => {
207
253
  storage.watermark(newWatermark);
208
254
  };
209
255
 
210
- // src/create-style-variables-repository.ts
211
- var createStyleVariablesRepository = () => {
212
- const variables = {};
213
- let subscription;
214
- const subscribe = (cb) => {
215
- subscription = cb;
216
- return () => {
217
- subscription = () => {
218
- };
219
- };
220
- };
221
- const notify = () => {
222
- if (typeof subscription === "function") {
223
- subscription({ ...variables });
224
- }
225
- };
226
- const shouldUpdate = (key, newValue) => {
227
- return !(key in variables) || variables[key] !== newValue;
228
- };
229
- const applyUpdates = (updatedVars) => {
230
- let hasChanges = false;
231
- for (const [key, { value }] of Object.entries(updatedVars)) {
232
- if (shouldUpdate(key, value)) {
233
- variables[key] = value;
234
- hasChanges = true;
235
- }
236
- }
237
- return hasChanges;
238
- };
239
- const update = (updatedVars) => {
240
- if (applyUpdates(updatedVars)) {
241
- notify();
242
- }
243
- };
244
- return {
245
- subscribe,
246
- update
247
- };
248
- };
249
-
250
- // src/style-variables-repository.ts
251
- var styleVariablesRepository = createStyleVariablesRepository();
252
-
253
256
  // src/hooks/use-prop-variables.ts
254
- var usePropVariables = (propKey) => {
255
- return useMemo(() => normalizeVariables(propKey), [propKey]);
256
- };
257
257
  var useVariable = (key) => {
258
258
  const variables = service.variables();
259
259
  if (!variables?.[key]) {
@@ -264,102 +264,113 @@ var useVariable = (key) => {
264
264
  key
265
265
  };
266
266
  };
267
+ var useFilteredVariables = (searchValue, propTypeKey) => {
268
+ const variables = usePropVariables(propTypeKey);
269
+ const filteredVariables = variables.filter(({ label }) => {
270
+ return label.toLowerCase().includes(searchValue.toLowerCase());
271
+ });
272
+ return {
273
+ list: filteredVariables,
274
+ hasMatches: filteredVariables.length > 0,
275
+ isSourceNotEmpty: variables.length > 0
276
+ };
277
+ };
278
+ var usePropVariables = (propKey) => {
279
+ return useMemo(() => normalizeVariables(propKey), [propKey]);
280
+ };
281
+ var isNotDeleted = ({ deleted }) => !deleted;
267
282
  var normalizeVariables = (propKey) => {
268
283
  const variables = service.variables();
269
- styleVariablesRepository.update(variables);
270
- return Object.entries(variables).filter(([, { type }]) => type === propKey).map(([key, { label, value }]) => ({
284
+ return Object.entries(variables).filter(([, variable]) => variable.type === propKey && isNotDeleted(variable)).map(([key, { label, value }]) => ({
271
285
  key,
272
286
  label,
273
287
  value
274
288
  }));
275
289
  };
276
290
  var createVariable = (newVariable) => {
277
- return service.create(newVariable).then(({ id, variable }) => {
278
- styleVariablesRepository.update({
279
- [id]: variable
280
- });
291
+ return service.create(newVariable).then(({ id }) => {
292
+ return id;
293
+ });
294
+ };
295
+ var updateVariable = (updateId, { value, label }) => {
296
+ return service.update(updateId, { value, label }).then(({ id }) => {
297
+ return id;
298
+ });
299
+ };
300
+ var deleteVariable = (deleteId) => {
301
+ return service.delete(deleteId).then(({ id }) => {
281
302
  return id;
282
303
  });
283
304
  };
284
305
 
285
- // src/prop-types/color-variable-prop-type.ts
286
- import { createPropUtils } from "@elementor/editor-props";
287
- import { z } from "@elementor/schema";
288
- var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
289
-
290
- // src/components/styled-menu-item.tsx
291
- import { MenuItem, styled as styled2 } from "@elementor/ui";
292
- var StyledMenuItem = styled2(MenuItem)(() => ({
293
- pl: 2,
294
- pr: 1,
295
- py: 0.5,
296
- "&:hover .MuiSvgIcon-root": {
297
- opacity: 1
298
- }
306
+ // src/components/ui/color-indicator.tsx
307
+ import { styled, UnstableColorIndicator } from "@elementor/ui";
308
+ var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
309
+ borderRadius: `${theme.shape.borderRadius / 2}px`,
310
+ marginRight: theme.spacing(0.25)
299
311
  }));
300
312
 
301
- // src/components/color-variables-selection.tsx
302
- var ColorVariablesSelection = ({ onSelect }) => {
303
- const { value: variable, setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
304
- const variables = usePropVariables(colorVariablePropTypeUtil.key);
305
- const handleSetColorVariable = (key) => {
306
- setVariable(key);
307
- onSelect?.();
308
- };
309
- return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(MenuList, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
310
- StyledMenuItem,
313
+ // src/components/variables-repeater-item-slot.tsx
314
+ var useColorVariable = (value) => {
315
+ const variableId = value?.value?.color?.value;
316
+ return useVariable(variableId || "");
317
+ };
318
+ var BackgroundRepeaterColorIndicator = ({ value }) => {
319
+ const colorVariable = useColorVariable(value);
320
+ return /* @__PURE__ */ React.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
321
+ };
322
+ var BackgroundRepeaterLabel = ({ value }) => {
323
+ const colorVariable = useColorVariable(value);
324
+ return /* @__PURE__ */ React.createElement("span", null, colorVariable?.label);
325
+ };
326
+ var BoxShadowRepeaterColorIndicator = ({ value }) => {
327
+ const colorVariable = useColorVariable(value);
328
+ return /* @__PURE__ */ React.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
329
+ };
330
+
331
+ // src/controls/color-variable-control.tsx
332
+ import * as React13 from "react";
333
+ import { useId as useId2, useRef as useRef6 } from "react";
334
+ import { useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
335
+ import { colorPropTypeUtil } from "@elementor/editor-props";
336
+ import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
337
+ import { bindPopover as bindPopover3, bindTrigger as bindTrigger3, Box as Box4, Popover as Popover3, usePopupState as usePopupState3 } from "@elementor/ui";
338
+
339
+ // src/components/ui/variable-tag.tsx
340
+ import * as React2 from "react";
341
+ import { DetachIcon } from "@elementor/icons";
342
+ import { Box, IconButton, Stack, Typography, UnstableTag as Tag } from "@elementor/ui";
343
+ import { __ } from "@wordpress/i18n";
344
+ var SIZE = "tiny";
345
+ var VariableTag = ({ startIcon, label, onUnlink, ...props }) => {
346
+ const actions = [];
347
+ if (onUnlink) {
348
+ actions.push(
349
+ /* @__PURE__ */ React2.createElement(IconButton, { key: "unlink", size: SIZE, onClick: onUnlink, "aria-label": __("Unlink", "elementor") }, /* @__PURE__ */ React2.createElement(DetachIcon, { fontSize: SIZE }))
350
+ );
351
+ }
352
+ return /* @__PURE__ */ React2.createElement(
353
+ Tag,
311
354
  {
312
- key,
313
- onClick: () => handleSetColorVariable(key),
314
- selected: key === variable
315
- },
316
- /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(ColorIndicator, { size: "inherit", component: "span", value })),
317
- /* @__PURE__ */ React.createElement(
318
- ListItemText,
319
- {
320
- primary: label,
321
- secondary: value,
322
- primaryTypographyProps: {
323
- variant: "body2",
324
- color: "text.secondary",
325
- style: {
326
- lineHeight: 2,
327
- display: "inline-block",
328
- overflow: "hidden",
329
- textOverflow: "ellipsis",
330
- whiteSpace: "nowrap",
331
- maxWidth: "81px"
332
- }
333
- },
334
- secondaryTypographyProps: {
335
- variant: "caption",
336
- color: "text.tertiary",
337
- style: { marginTop: "1px", lineHeight: "1" }
338
- },
339
- sx: { display: "flex", alignItems: "center", gap: 1 }
340
- }
341
- ),
342
- /* @__PURE__ */ React.createElement(EditIcon, { color: "action", fontSize: "inherit", sx: { mx: 1, opacity: "0" } })
343
- )))));
355
+ fullWidth: true,
356
+ showActionsOnHover: true,
357
+ startIcon: /* @__PURE__ */ React2.createElement(Stack, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
358
+ label: /* @__PURE__ */ React2.createElement(Box, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React2.createElement(Typography, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
359
+ actions,
360
+ ...props
361
+ }
362
+ );
344
363
  };
345
364
 
346
- // src/components/variables-selection-popover.tsx
347
- import * as React4 from "react";
348
- import { useId, useRef as useRef3 } from "react";
349
- import { PopoverHeader as PopoverHeader3 } from "@elementor/editor-ui";
350
- import { ColorFilterIcon, DetachIcon, PlusIcon } from "@elementor/icons";
351
- import {
352
- bindPopover as bindPopover2,
353
- bindTrigger as bindTrigger2,
354
- Box as Box2,
355
- IconButton,
356
- Popover as Popover2,
357
- Stack as Stack3,
358
- Typography,
359
- UnstableTag as Tag,
360
- usePopupState as usePopupState2
361
- } from "@elementor/ui";
362
- import { __ as __3 } from "@wordpress/i18n";
365
+ // src/components/variable-selection-popover.tsx
366
+ import * as React12 from "react";
367
+ import { useRef as useRef5, useState as useState7 } from "react";
368
+ import { Box as Box3 } from "@elementor/ui";
369
+
370
+ // src/prop-types/color-variable-prop-type.ts
371
+ import { createPropUtils } from "@elementor/editor-props";
372
+ import { z } from "@elementor/schema";
373
+ var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
363
374
 
364
375
  // src/prop-types/font-variable-prop-type.ts
365
376
  import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
@@ -367,19 +378,39 @@ import { z as z2 } from "@elementor/schema";
367
378
  var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
368
379
 
369
380
  // src/components/color-variable-creation.tsx
370
- import * as React2 from "react";
381
+ import * as React3 from "react";
371
382
  import { useRef, useState } from "react";
372
- import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
383
+ import { PopoverContent, useBoundProp } from "@elementor/editor-controls";
384
+ import { PopoverScrollableContent } from "@elementor/editor-editing-panel";
373
385
  import { PopoverHeader } from "@elementor/editor-ui";
374
- import { BrushIcon } from "@elementor/icons";
375
- import { Button, CardActions, Divider as Divider2, FormLabel, Grid, Stack, TextField, UnstableColorField } from "@elementor/ui";
376
- import { __ } from "@wordpress/i18n";
377
- var SIZE = "tiny";
378
- var ColorVariableCreation = ({ onClose }) => {
379
- const { setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
386
+ import { ArrowLeftIcon, BrushIcon } from "@elementor/icons";
387
+ import {
388
+ Button,
389
+ CardActions,
390
+ Divider,
391
+ FormLabel,
392
+ Grid,
393
+ IconButton as IconButton2,
394
+ TextField,
395
+ UnstableColorField
396
+ } from "@elementor/ui";
397
+ import { __ as __2 } from "@wordpress/i18n";
398
+
399
+ // src/components/variable-selection-popover.context.ts
400
+ import { createContext, useContext } from "react";
401
+ var PopoverContentRefContext = createContext(null);
402
+ var usePopoverContentRef = () => {
403
+ return useContext(PopoverContentRefContext);
404
+ };
405
+
406
+ // src/components/color-variable-creation.tsx
407
+ var SIZE2 = "tiny";
408
+ var ColorVariableCreation = ({ onGoBack, onClose }) => {
409
+ const { setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
380
410
  const [color, setColor] = useState("");
381
411
  const [label, setLabel] = useState("");
382
- const anchorRef = useRef(null);
412
+ const defaultRef = useRef(null);
413
+ const anchorRef = usePopoverContentRef() ?? defaultRef;
383
414
  const resetFields = () => {
384
415
  setColor("");
385
416
  setLabel("");
@@ -401,14 +432,14 @@ var ColorVariableCreation = ({ onClose }) => {
401
432
  const isFormInvalid = () => {
402
433
  return !color?.trim() || !label?.trim();
403
434
  };
404
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
435
+ return /* @__PURE__ */ React3.createElement(PopoverScrollableContent, { height: "auto" }, /* @__PURE__ */ React3.createElement(
405
436
  PopoverHeader,
406
437
  {
407
- title: __("Create variable", "elementor"),
408
- onClose: closePopover,
409
- icon: /* @__PURE__ */ React2.createElement(BrushIcon, { fontSize: SIZE })
438
+ icon: /* @__PURE__ */ React3.createElement(React3.Fragment, null, onGoBack && /* @__PURE__ */ React3.createElement(IconButton2, { size: SIZE2, "aria-label": __2("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React3.createElement(ArrowLeftIcon, { fontSize: SIZE2 })), /* @__PURE__ */ React3.createElement(BrushIcon, { fontSize: SIZE2 })),
439
+ title: __2("Create variable", "elementor"),
440
+ onClose: closePopover
410
441
  }
411
- ), /* @__PURE__ */ React2.createElement(Divider2, null), /* @__PURE__ */ React2.createElement(Stack, { p: 1.5, gap: 1.5 }, /* @__PURE__ */ React2.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(FormLabel, { size: "small" }, __("Name", "elementor"))), /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(
442
+ ), /* @__PURE__ */ React3.createElement(Divider, null), /* @__PURE__ */ React3.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React3.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React3.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(FormLabel, { size: "tiny" }, __2("Name", "elementor"))), /* @__PURE__ */ React3.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(
412
443
  TextField,
413
444
  {
414
445
  size: "tiny",
@@ -416,7 +447,7 @@ var ColorVariableCreation = ({ onClose }) => {
416
447
  value: label,
417
448
  onChange: (e) => setLabel(e.target.value)
418
449
  }
419
- ))), /* @__PURE__ */ React2.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(FormLabel, { size: "small" }, __("Value", "elementor"))), /* @__PURE__ */ React2.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(
450
+ ))), /* @__PURE__ */ React3.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React3.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(FormLabel, { size: "tiny" }, __2("Value", "elementor"))), /* @__PURE__ */ React3.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(
420
451
  UnstableColorField,
421
452
  {
422
453
  size: "tiny",
@@ -431,38 +462,344 @@ var ColorVariableCreation = ({ onClose }) => {
431
462
  }
432
463
  }
433
464
  }
434
- )))), /* @__PURE__ */ React2.createElement(CardActions, null, /* @__PURE__ */ React2.createElement(Button, { size: "small", onClick: closePopover, color: "secondary", variant: "text" }, __("Cancel", "elementor")), /* @__PURE__ */ React2.createElement(Button, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __("Create", "elementor"))));
465
+ )))), /* @__PURE__ */ React3.createElement(CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React3.createElement(Button, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __2("Create", "elementor"))));
435
466
  };
436
467
 
437
- // src/components/font-variable-creation.tsx
438
- import * as React3 from "react";
468
+ // src/components/color-variable-edit.tsx
469
+ import * as React4 from "react";
439
470
  import { useRef as useRef2, useState as useState2 } from "react";
440
- import { FontFamilySelector, useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
441
- import { useFontFamilies } from "@elementor/editor-editing-panel";
442
- import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
443
- import { ChevronDownIcon, TextIcon } from "@elementor/icons";
471
+ import { PopoverContent as PopoverContent2 } from "@elementor/editor-controls";
472
+ import { PopoverHeader as PopoverHeader2, PopoverScrollableContent as PopoverScrollableContent2 } from "@elementor/editor-ui";
473
+ import { ArrowLeftIcon as ArrowLeftIcon2, BrushIcon as BrushIcon2, TrashIcon } from "@elementor/icons";
444
474
  import {
445
- bindPopover,
446
- bindTrigger,
447
475
  Button as Button2,
448
476
  CardActions as CardActions2,
449
- Divider as Divider3,
477
+ Divider as Divider2,
450
478
  FormLabel as FormLabel2,
451
479
  Grid as Grid2,
452
- Popover,
453
- Stack as Stack2,
480
+ IconButton as IconButton3,
454
481
  TextField as TextField2,
482
+ UnstableColorField as UnstableColorField2
483
+ } from "@elementor/ui";
484
+ import { __ as __3 } from "@wordpress/i18n";
485
+ var SIZE3 = "tiny";
486
+ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
487
+ const variable = useVariable(editId);
488
+ if (!variable) {
489
+ throw new Error(`Global color variable not found`);
490
+ }
491
+ const defaultRef = useRef2(null);
492
+ const anchorRef = usePopoverContentRef() ?? defaultRef;
493
+ const [color, setColor] = useState2(variable.value);
494
+ const [label, setLabel] = useState2(variable.label);
495
+ const handleUpdate = () => {
496
+ updateVariable(editId, {
497
+ value: color,
498
+ label
499
+ }).then(() => {
500
+ onSubmit?.();
501
+ });
502
+ };
503
+ const handleDelete = () => {
504
+ deleteVariable(editId).then(() => {
505
+ onSubmit?.();
506
+ });
507
+ };
508
+ const noValueChanged = () => color === variable.value && label === variable.label;
509
+ const hasEmptyValue = () => "" === color.trim() || "" === label.trim();
510
+ const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
511
+ const actions = [];
512
+ actions.push(
513
+ /* @__PURE__ */ React4.createElement(IconButton3, { key: "delete", size: SIZE3, "aria-label": __3("Delete", "elementor"), onClick: handleDelete }, /* @__PURE__ */ React4.createElement(TrashIcon, { fontSize: SIZE3 }))
514
+ );
515
+ return /* @__PURE__ */ React4.createElement(PopoverScrollableContent2, { height: "auto" }, /* @__PURE__ */ React4.createElement(
516
+ PopoverHeader2,
517
+ {
518
+ title: __3("Edit variable", "elementor"),
519
+ onClose,
520
+ icon: /* @__PURE__ */ React4.createElement(React4.Fragment, null, onGoBack && /* @__PURE__ */ React4.createElement(IconButton3, { size: SIZE3, "aria-label": __3("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React4.createElement(ArrowLeftIcon2, { fontSize: SIZE3 })), /* @__PURE__ */ React4.createElement(BrushIcon2, { fontSize: SIZE3 })),
521
+ actions
522
+ }
523
+ ), /* @__PURE__ */ React4.createElement(Divider2, null), /* @__PURE__ */ React4.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React4.createElement(Grid2, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React4.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React4.createElement(FormLabel2, { size: "tiny" }, __3("Name", "elementor"))), /* @__PURE__ */ React4.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React4.createElement(
524
+ TextField2,
525
+ {
526
+ size: "tiny",
527
+ fullWidth: true,
528
+ value: label,
529
+ onChange: (e) => setLabel(e.target.value)
530
+ }
531
+ ))), /* @__PURE__ */ React4.createElement(Grid2, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React4.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React4.createElement(FormLabel2, { size: "tiny" }, __3("Value", "elementor"))), /* @__PURE__ */ React4.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React4.createElement(
532
+ UnstableColorField2,
533
+ {
534
+ size: "tiny",
535
+ fullWidth: true,
536
+ value: color,
537
+ onChange: setColor,
538
+ slotProps: {
539
+ colorPicker: {
540
+ anchorEl: anchorRef.current,
541
+ anchorOrigin: { vertical: "top", horizontal: "right" },
542
+ transformOrigin: { vertical: "top", horizontal: -10 }
543
+ }
544
+ }
545
+ }
546
+ )))), /* @__PURE__ */ React4.createElement(CardActions2, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React4.createElement(Button2, { size: "small", variant: "contained", disabled: isSaveDisabled(), onClick: handleUpdate }, __3("Save", "elementor"))));
547
+ };
548
+
549
+ // src/components/color-variables-selection.tsx
550
+ import * as React8 from "react";
551
+ import { useState as useState3 } from "react";
552
+ import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
553
+ import { PopoverScrollableContent as PopoverScrollableContent3 } from "@elementor/editor-editing-panel";
554
+ import { PopoverHeader as PopoverHeader3, PopoverMenuList, PopoverSearch } from "@elementor/editor-ui";
555
+ import { BrushIcon as BrushIcon3, ColorFilterIcon, PlusIcon, SettingsIcon } from "@elementor/icons";
556
+ import { Divider as Divider3, IconButton as IconButton5 } from "@elementor/ui";
557
+ import { __ as __7 } from "@wordpress/i18n";
558
+
559
+ // src/components/ui/menu-item-content.tsx
560
+ import * as React5 from "react";
561
+ import { EllipsisWithTooltip } from "@elementor/editor-ui";
562
+ import { isExperimentActive } from "@elementor/editor-v1-adapters";
563
+ import { EditIcon } from "@elementor/icons";
564
+ import { Box as Box2, IconButton as IconButton4, ListItemIcon, Typography as Typography2 } from "@elementor/ui";
565
+ import { __ as __4 } from "@wordpress/i18n";
566
+ var SIZE4 = "tiny";
567
+ var isVersion330Active = isExperimentActive("e_v_3_30");
568
+ var MenuItemContent = ({ item }) => {
569
+ const onEdit = item.onEdit;
570
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React5.createElement(
571
+ Box2,
572
+ {
573
+ sx: {
574
+ flex: 1,
575
+ minWidth: 0,
576
+ display: "flex",
577
+ alignItems: "center",
578
+ gap: 1
579
+ }
580
+ },
581
+ /* @__PURE__ */ React5.createElement(
582
+ EllipsisWithTooltip,
583
+ {
584
+ title: item.label || item.value,
585
+ as: Typography2,
586
+ variant: isVersion330Active ? "caption" : "body2",
587
+ color: isVersion330Active ? "text.primary" : "text.secondary",
588
+ sx: { marginTop: "1px", lineHeight: "2" },
589
+ maxWidth: "50%"
590
+ }
591
+ ),
592
+ item.secondaryText && /* @__PURE__ */ React5.createElement(
593
+ EllipsisWithTooltip,
594
+ {
595
+ title: item.secondaryText,
596
+ as: Typography2,
597
+ variant: "caption",
598
+ color: "text.tertiary",
599
+ sx: { marginTop: "1px", lineHeight: "1" },
600
+ maxWidth: "50%"
601
+ }
602
+ )
603
+ ), !!onEdit && /* @__PURE__ */ React5.createElement(
604
+ IconButton4,
605
+ {
606
+ sx: { mx: 1, opacity: "0" },
607
+ onClick: (e) => {
608
+ e.stopPropagation();
609
+ onEdit(item.value);
610
+ },
611
+ "aria-label": __4("Edit", "elementor")
612
+ },
613
+ /* @__PURE__ */ React5.createElement(EditIcon, { color: "action", fontSize: SIZE4 })
614
+ ));
615
+ };
616
+
617
+ // src/components/ui/no-search-results.tsx
618
+ import * as React6 from "react";
619
+ import { Link, Stack as Stack2, Typography as Typography3 } from "@elementor/ui";
620
+ import { __ as __5 } from "@wordpress/i18n";
621
+ var NoSearchResults = ({ searchValue, onClear, icon }) => {
622
+ return /* @__PURE__ */ React6.createElement(
623
+ Stack2,
624
+ {
625
+ gap: 1,
626
+ alignItems: "center",
627
+ justifyContent: "center",
628
+ height: "100%",
629
+ p: 2.5,
630
+ color: "text.secondary",
631
+ sx: { pb: 3.5 }
632
+ },
633
+ icon,
634
+ /* @__PURE__ */ React6.createElement(Typography3, { align: "center", variant: "subtitle2" }, __5("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React6.createElement("br", null), "\u201C", searchValue, "\u201D."),
635
+ /* @__PURE__ */ React6.createElement(Typography3, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, __5("Try something else.", "elementor"), /* @__PURE__ */ React6.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __5("Clear & try again", "elementor")))
636
+ );
637
+ };
638
+
639
+ // src/components/ui/no-variables.tsx
640
+ import * as React7 from "react";
641
+ import { Button as Button3, Stack as Stack3, Typography as Typography4 } from "@elementor/ui";
642
+ import { __ as __6 } from "@wordpress/i18n";
643
+ var NoVariables = ({ icon, title, onAdd }) => /* @__PURE__ */ React7.createElement(
644
+ Stack3,
645
+ {
646
+ gap: 1,
647
+ alignItems: "center",
648
+ justifyContent: "center",
649
+ height: "100%",
650
+ color: "text.secondary",
651
+ sx: { p: 2.5, pb: 5.5 }
652
+ },
653
+ icon,
654
+ /* @__PURE__ */ React7.createElement(Typography4, { align: "center", variant: "subtitle2" }, title),
655
+ /* @__PURE__ */ React7.createElement(Typography4, { align: "center", variant: "caption", maxWidth: "180px" }, __6("Variables are saved attributes that you can apply anywhere on your site.", "elementor")),
656
+ onAdd && /* @__PURE__ */ React7.createElement(Button3, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __6("Create a variable", "elementor"))
657
+ );
658
+
659
+ // src/components/ui/styled-menu-list.tsx
660
+ import { MenuList, styled as styled2 } from "@elementor/ui";
661
+ var VariablesStyledMenuList = styled2(MenuList)(({ theme }) => ({
662
+ "& > li": {
663
+ height: 32,
664
+ width: "100%",
665
+ display: "flex",
666
+ alignItems: "center"
667
+ },
668
+ '& > [role="option"]': {
669
+ ...theme.typography.caption,
670
+ lineHeight: "inherit",
671
+ padding: theme.spacing(0.5, 1, 0.5, 2),
672
+ "&:hover, &:focus": {
673
+ backgroundColor: theme.palette.action.hover
674
+ },
675
+ '&[aria-selected="true"]': {
676
+ backgroundColor: theme.palette.action.selected
677
+ },
678
+ cursor: "pointer",
679
+ textOverflow: "ellipsis",
680
+ position: "absolute",
681
+ top: 0,
682
+ left: 0,
683
+ "&:hover .MuiIconButton-root, .MuiIconButton-root:focus": {
684
+ opacity: 1
685
+ }
686
+ },
687
+ width: "100%",
688
+ position: "relative"
689
+ }));
690
+
691
+ // src/components/color-variables-selection.tsx
692
+ var SIZE5 = "tiny";
693
+ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
694
+ const { value: variable, setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
695
+ const [searchValue, setSearchValue] = useState3("");
696
+ const {
697
+ list: variables,
698
+ hasMatches: hasSearchResults,
699
+ isSourceNotEmpty: hasVariables
700
+ } = useFilteredVariables(searchValue, colorVariablePropTypeUtil.key);
701
+ const handleSetColorVariable = (key) => {
702
+ setVariable(key);
703
+ closePopover();
704
+ };
705
+ const actions = [];
706
+ if (onAdd) {
707
+ actions.push(
708
+ /* @__PURE__ */ React8.createElement(IconButton5, { key: "add", size: SIZE5, onClick: onAdd }, /* @__PURE__ */ React8.createElement(PlusIcon, { fontSize: SIZE5 }))
709
+ );
710
+ }
711
+ if (onSettings) {
712
+ actions.push(
713
+ /* @__PURE__ */ React8.createElement(IconButton5, { key: "settings", size: SIZE5, onClick: onSettings }, /* @__PURE__ */ React8.createElement(SettingsIcon, { fontSize: SIZE5 }))
714
+ );
715
+ }
716
+ const items = variables.map(({ value, label, key }) => ({
717
+ type: "item",
718
+ value: key,
719
+ label,
720
+ icon: /* @__PURE__ */ React8.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
721
+ secondaryText: value,
722
+ onEdit: () => onEdit?.(key)
723
+ }));
724
+ const handleSearch = (search) => {
725
+ setSearchValue(search);
726
+ };
727
+ const handleClearSearch = () => {
728
+ setSearchValue("");
729
+ };
730
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
731
+ PopoverHeader3,
732
+ {
733
+ title: __7("Variables", "elementor"),
734
+ icon: /* @__PURE__ */ React8.createElement(ColorFilterIcon, { fontSize: SIZE5 }),
735
+ onClose: closePopover,
736
+ actions
737
+ }
738
+ ), hasVariables && /* @__PURE__ */ React8.createElement(
739
+ PopoverSearch,
740
+ {
741
+ value: searchValue,
742
+ onSearch: handleSearch,
743
+ placeholder: __7("Search", "elementor")
744
+ }
745
+ ), /* @__PURE__ */ React8.createElement(Divider3, null), /* @__PURE__ */ React8.createElement(PopoverScrollableContent3, null, hasVariables && hasSearchResults && /* @__PURE__ */ React8.createElement(
746
+ PopoverMenuList,
747
+ {
748
+ items,
749
+ onSelect: handleSetColorVariable,
750
+ onClose: () => {
751
+ },
752
+ selectedValue: variable,
753
+ "data-testid": "color-variables-list",
754
+ menuListTemplate: VariablesStyledMenuList,
755
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React8.createElement(MenuItemContent, { item })
756
+ }
757
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React8.createElement(
758
+ NoSearchResults,
759
+ {
760
+ searchValue,
761
+ onClear: handleClearSearch,
762
+ icon: /* @__PURE__ */ React8.createElement(BrushIcon3, { fontSize: "large" })
763
+ }
764
+ ), !hasVariables && /* @__PURE__ */ React8.createElement(
765
+ NoVariables,
766
+ {
767
+ title: __7("Create your first color variable", "elementor"),
768
+ icon: /* @__PURE__ */ React8.createElement(BrushIcon3, { fontSize: "large" }),
769
+ onAdd
770
+ }
771
+ )));
772
+ };
773
+
774
+ // src/components/font-variable-creation.tsx
775
+ import * as React9 from "react";
776
+ import { useRef as useRef3, useState as useState4 } from "react";
777
+ import { FontFamilySelector, PopoverContent as PopoverContent3, useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
778
+ import { PopoverScrollableContent as PopoverScrollableContent4, useFontFamilies, useSectionWidth } from "@elementor/editor-editing-panel";
779
+ import { PopoverHeader as PopoverHeader4 } from "@elementor/editor-ui";
780
+ import { ArrowLeftIcon as ArrowLeftIcon3, ChevronDownIcon, TextIcon } from "@elementor/icons";
781
+ import {
782
+ bindPopover,
783
+ bindTrigger,
784
+ Button as Button4,
785
+ CardActions as CardActions3,
786
+ Divider as Divider4,
787
+ FormLabel as FormLabel3,
788
+ Grid as Grid3,
789
+ IconButton as IconButton6,
790
+ Popover,
791
+ TextField as TextField3,
455
792
  UnstableTag,
456
793
  usePopupState
457
794
  } from "@elementor/ui";
458
- import { __ as __2 } from "@wordpress/i18n";
459
- var SIZE2 = "tiny";
460
- var FontVariableCreation = ({ onClose }) => {
795
+ import { __ as __8 } from "@wordpress/i18n";
796
+ var SIZE6 = "tiny";
797
+ var FontVariableCreation = ({ onClose, onGoBack }) => {
461
798
  const fontFamilies = useFontFamilies();
462
799
  const { setValue: setVariable } = useBoundProp3(fontVariablePropTypeUtil);
463
- const [fontFamily, setFontFamily] = useState2("");
464
- const [label, setLabel] = useState2("");
465
- const anchorRef = useRef2(null);
800
+ const [fontFamily, setFontFamily] = useState4("");
801
+ const [label, setLabel] = useState4("");
802
+ const anchorRef = useRef3(null);
466
803
  const fontPopoverState = usePopupState({ variant: "popover" });
467
804
  const resetFields = () => {
468
805
  setFontFamily("");
@@ -485,31 +822,32 @@ var FontVariableCreation = ({ onClose }) => {
485
822
  const isFormInvalid = () => {
486
823
  return !fontFamily?.trim() || !label?.trim();
487
824
  };
488
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
489
- PopoverHeader2,
825
+ const sectionWidth = useSectionWidth();
826
+ return /* @__PURE__ */ React9.createElement(PopoverScrollableContent4, { height: "auto" }, /* @__PURE__ */ React9.createElement(
827
+ PopoverHeader4,
490
828
  {
491
- title: __2("Create variable", "elementor"),
492
- onClose: closePopover,
493
- icon: /* @__PURE__ */ React3.createElement(TextIcon, { fontSize: SIZE2 })
829
+ icon: /* @__PURE__ */ React9.createElement(React9.Fragment, null, onGoBack && /* @__PURE__ */ React9.createElement(IconButton6, { size: SIZE6, "aria-label": __8("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React9.createElement(ArrowLeftIcon3, { fontSize: SIZE6 })), /* @__PURE__ */ React9.createElement(TextIcon, { fontSize: SIZE6 })),
830
+ title: __8("Create variable", "elementor"),
831
+ onClose: closePopover
494
832
  }
495
- ), /* @__PURE__ */ React3.createElement(Divider3, null), /* @__PURE__ */ React3.createElement(Stack2, { p: 1.5, gap: 1.5 }, /* @__PURE__ */ React3.createElement(Grid2, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React3.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(FormLabel2, { size: "small" }, __2("Name", "elementor"))), /* @__PURE__ */ React3.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(
496
- TextField2,
833
+ ), /* @__PURE__ */ React9.createElement(Divider4, null), /* @__PURE__ */ React9.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React9.createElement(Grid3, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React9.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(FormLabel3, { size: "tiny" }, __8("Name", "elementor"))), /* @__PURE__ */ React9.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(
834
+ TextField3,
497
835
  {
498
836
  size: "tiny",
499
837
  fullWidth: true,
500
838
  value: label,
501
839
  onChange: (e) => setLabel(e.target.value)
502
840
  }
503
- ))), /* @__PURE__ */ React3.createElement(Grid2, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React3.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(FormLabel2, { size: "small" }, __2("Value", "elementor"))), /* @__PURE__ */ React3.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
841
+ ))), /* @__PURE__ */ React9.createElement(Grid3, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React9.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(FormLabel3, { size: "tiny" }, __8("Value", "elementor"))), /* @__PURE__ */ React9.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
504
842
  UnstableTag,
505
843
  {
506
844
  variant: "outlined",
507
845
  label: fontFamily,
508
- endIcon: /* @__PURE__ */ React3.createElement(ChevronDownIcon, { fontSize: "tiny" }),
846
+ endIcon: /* @__PURE__ */ React9.createElement(ChevronDownIcon, { fontSize: "tiny" }),
509
847
  ...bindTrigger(fontPopoverState),
510
848
  fullWidth: true
511
849
  }
512
- ), /* @__PURE__ */ React3.createElement(
850
+ ), /* @__PURE__ */ React9.createElement(
513
851
  Popover,
514
852
  {
515
853
  disablePortal: true,
@@ -519,118 +857,371 @@ var FontVariableCreation = ({ onClose }) => {
519
857
  transformOrigin: { vertical: "top", horizontal: -20 },
520
858
  ...bindPopover(fontPopoverState)
521
859
  },
522
- /* @__PURE__ */ React3.createElement(
860
+ /* @__PURE__ */ React9.createElement(
523
861
  FontFamilySelector,
524
862
  {
525
863
  fontFamilies,
526
864
  fontFamily,
527
865
  onFontFamilyChange: setFontFamily,
528
- onClose: fontPopoverState.close
866
+ onClose: fontPopoverState.close,
867
+ sectionWidth
529
868
  }
530
869
  )
531
- ))))), /* @__PURE__ */ React3.createElement(CardActions2, null, /* @__PURE__ */ React3.createElement(Button2, { size: "small", onClick: closePopover, color: "secondary", variant: "text" }, __2("Cancel", "elementor")), /* @__PURE__ */ React3.createElement(Button2, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __2("Create", "elementor"))));
870
+ ))))), /* @__PURE__ */ React9.createElement(CardActions3, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React9.createElement(Button4, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __8("Create", "elementor"))));
532
871
  };
533
872
 
534
- // src/components/variables-selection-popover.tsx
535
- var SIZE3 = "tiny";
536
- var VariablesSelectionPopover = ({
537
- selectedVariable,
538
- unlinkVariable,
539
- startTagAdornment,
540
- children
541
- }) => {
542
- const id = useId();
543
- const popupState = usePopupState2({ variant: "popover", popupId: `elementor-variables-action-${id}` });
544
- const creationPopupState = usePopupState2({ variant: "popover", popupId: `elementor-variables-creation-${id}` });
545
- const closePopover = () => popupState.close();
546
- const handleCreateButtonClick = (event) => {
547
- closePopover();
548
- bindTrigger2(creationPopupState).onClick(event);
873
+ // src/components/font-variable-edit.tsx
874
+ import * as React10 from "react";
875
+ import { useId, useRef as useRef4, useState as useState5 } from "react";
876
+ import { FontFamilySelector as FontFamilySelector2, PopoverContent as PopoverContent4 } from "@elementor/editor-controls";
877
+ import { useFontFamilies as useFontFamilies2, useSectionWidth as useSectionWidth2 } from "@elementor/editor-editing-panel";
878
+ import { PopoverHeader as PopoverHeader5, PopoverScrollableContent as PopoverScrollableContent5 } from "@elementor/editor-ui";
879
+ import { ArrowLeftIcon as ArrowLeftIcon4, ChevronDownIcon as ChevronDownIcon2, TextIcon as TextIcon2, TrashIcon as TrashIcon2 } from "@elementor/icons";
880
+ import {
881
+ bindPopover as bindPopover2,
882
+ bindTrigger as bindTrigger2,
883
+ Button as Button5,
884
+ CardActions as CardActions4,
885
+ Divider as Divider5,
886
+ FormLabel as FormLabel4,
887
+ Grid as Grid4,
888
+ IconButton as IconButton7,
889
+ Popover as Popover2,
890
+ TextField as TextField4,
891
+ UnstableTag as UnstableTag2,
892
+ usePopupState as usePopupState2
893
+ } from "@elementor/ui";
894
+ import { __ as __9 } from "@wordpress/i18n";
895
+ var SIZE7 = "tiny";
896
+ var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
897
+ const variable = useVariable(editId);
898
+ if (!variable) {
899
+ throw new Error(`Global font variable "${editId}" not found`);
900
+ }
901
+ const [fontFamily, setFontFamily] = useState5(variable.value);
902
+ const [label, setLabel] = useState5(variable.label);
903
+ const variableNameId = useId();
904
+ const variableValueId = useId();
905
+ const anchorRef = useRef4(null);
906
+ const fontPopoverState = usePopupState2({ variant: "popover" });
907
+ const fontFamilies = useFontFamilies2();
908
+ const handleUpdate = () => {
909
+ updateVariable(editId, {
910
+ value: fontFamily,
911
+ label
912
+ }).then(() => {
913
+ onSubmit?.();
914
+ });
549
915
  };
550
- const anchorRef = useRef3(null);
551
- const { label } = selectedVariable;
552
- const colorCreationEnabled = colorVariablePropTypeUtil.key === selectedVariable.type;
553
- const fontCreationEnabled = fontVariablePropTypeUtil.key === selectedVariable.type;
554
- return /* @__PURE__ */ React4.createElement(Box2, { ref: anchorRef }, /* @__PURE__ */ React4.createElement(
555
- Tag,
916
+ const handleDelete = () => {
917
+ deleteVariable(editId).then(() => {
918
+ onSubmit?.();
919
+ });
920
+ };
921
+ const noValueChanged = () => fontFamily === variable.value && label === variable.label;
922
+ const hasEmptyValue = () => "" === fontFamily.trim() || "" === label.trim();
923
+ const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
924
+ const sectionWidth = useSectionWidth2();
925
+ const actions = [];
926
+ actions.push(
927
+ /* @__PURE__ */ React10.createElement(IconButton7, { key: "delete", size: SIZE7, "aria-label": __9("Delete", "elementor"), onClick: handleDelete }, /* @__PURE__ */ React10.createElement(TrashIcon2, { fontSize: SIZE7 }))
928
+ );
929
+ return /* @__PURE__ */ React10.createElement(PopoverScrollableContent5, { height: "auto" }, /* @__PURE__ */ React10.createElement(
930
+ PopoverHeader5,
556
931
  {
932
+ icon: /* @__PURE__ */ React10.createElement(React10.Fragment, null, onGoBack && /* @__PURE__ */ React10.createElement(IconButton7, { size: SIZE7, "aria-label": __9("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React10.createElement(ArrowLeftIcon4, { fontSize: SIZE7 })), /* @__PURE__ */ React10.createElement(TextIcon2, { fontSize: SIZE7 })),
933
+ title: __9("Edit variable", "elementor"),
934
+ onClose,
935
+ actions
936
+ }
937
+ ), /* @__PURE__ */ React10.createElement(Divider5, null), /* @__PURE__ */ React10.createElement(PopoverContent4, { p: 2 }, /* @__PURE__ */ React10.createElement(Grid4, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React10.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(FormLabel4, { htmlFor: variableNameId, size: "tiny" }, __9("Name", "elementor"))), /* @__PURE__ */ React10.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(
938
+ TextField4,
939
+ {
940
+ id: variableNameId,
941
+ size: "tiny",
557
942
  fullWidth: true,
558
- showActionsOnHover: true,
559
- ...bindTrigger2(popupState),
560
- startIcon: /* @__PURE__ */ React4.createElement(Stack3, { spacing: 1, direction: "row", alignItems: "center" }, startTagAdornment, /* @__PURE__ */ React4.createElement(ColorFilterIcon, { fontSize: "inherit", sx: { mr: 1 } })),
561
- label: /* @__PURE__ */ React4.createElement(Box2, { sx: { display: "inline-grid" } }, /* @__PURE__ */ React4.createElement(Typography, { sx: { textOverflow: "ellipsis", overflowX: "hidden" }, variant: "subtitle2" }, label)),
562
- actions: /* @__PURE__ */ React4.createElement(IconButton, { size: SIZE3, onClick: unlinkVariable, "aria-label": __3("Unlink", "elementor") }, /* @__PURE__ */ React4.createElement(DetachIcon, { fontSize: SIZE3 }))
943
+ value: label,
944
+ onChange: (e) => setLabel(e.target.value)
945
+ }
946
+ ))), /* @__PURE__ */ React10.createElement(Grid4, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React10.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(FormLabel4, { htmlFor: variableValueId, size: "tiny" }, __9("Value", "elementor"))), /* @__PURE__ */ React10.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
947
+ UnstableTag2,
948
+ {
949
+ id: variableValueId,
950
+ variant: "outlined",
951
+ label: fontFamily,
952
+ endIcon: /* @__PURE__ */ React10.createElement(ChevronDownIcon2, { fontSize: "tiny" }),
953
+ ...bindTrigger2(fontPopoverState),
954
+ fullWidth: true
563
955
  }
564
- ), /* @__PURE__ */ React4.createElement(
956
+ ), /* @__PURE__ */ React10.createElement(
565
957
  Popover2,
566
958
  {
567
- ...bindPopover2(popupState),
959
+ disablePortal: true,
568
960
  disableScrollLock: true,
569
961
  anchorEl: anchorRef.current,
570
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
571
- transformOrigin: { vertical: "top", horizontal: "right" }
962
+ anchorOrigin: { vertical: "top", horizontal: "right" },
963
+ transformOrigin: { vertical: "top", horizontal: -20 },
964
+ ...bindPopover2(fontPopoverState)
572
965
  },
573
- /* @__PURE__ */ React4.createElement(
574
- PopoverHeader3,
966
+ /* @__PURE__ */ React10.createElement(
967
+ FontFamilySelector2,
575
968
  {
576
- title: __3("Variables", "elementor"),
577
- onClose: closePopover,
578
- icon: /* @__PURE__ */ React4.createElement(ColorFilterIcon, { fontSize: SIZE3 }),
579
- actions: [
580
- /* @__PURE__ */ React4.createElement(
581
- IconButton,
582
- {
583
- key: "createVariable",
584
- ...bindTrigger2(creationPopupState),
585
- size: SIZE3,
586
- onClick: handleCreateButtonClick
587
- },
588
- /* @__PURE__ */ React4.createElement(PlusIcon, { fontSize: SIZE3 })
589
- )
590
- ]
969
+ fontFamilies,
970
+ fontFamily,
971
+ onFontFamilyChange: setFontFamily,
972
+ onClose: fontPopoverState.close,
973
+ sectionWidth
591
974
  }
592
- ),
593
- children?.({ closePopover })
594
- ), /* @__PURE__ */ React4.createElement(Box2, { ref: anchorRef }, /* @__PURE__ */ React4.createElement(
595
- Popover2,
975
+ )
976
+ ))))), /* @__PURE__ */ React10.createElement(CardActions4, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React10.createElement(Button5, { size: "small", variant: "contained", disabled: isSaveDisabled(), onClick: handleUpdate }, __9("Save", "elementor"))));
977
+ };
978
+
979
+ // src/components/font-variables-selection.tsx
980
+ import * as React11 from "react";
981
+ import { useState as useState6 } from "react";
982
+ import { useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
983
+ import { PopoverScrollableContent as PopoverScrollableContent6 } from "@elementor/editor-editing-panel";
984
+ import { PopoverHeader as PopoverHeader6, PopoverMenuList as PopoverMenuList2, PopoverSearch as PopoverSearch2 } from "@elementor/editor-ui";
985
+ import { ColorFilterIcon as ColorFilterIcon2, PlusIcon as PlusIcon2, SettingsIcon as SettingsIcon2, TextIcon as TextIcon3 } from "@elementor/icons";
986
+ import { Divider as Divider6, IconButton as IconButton8 } from "@elementor/ui";
987
+ import { __ as __10 } from "@wordpress/i18n";
988
+ var SIZE8 = "tiny";
989
+ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
990
+ const { value: variable, setValue: setVariable } = useBoundProp4(fontVariablePropTypeUtil);
991
+ const [searchValue, setSearchValue] = useState6("");
992
+ const {
993
+ list: variables,
994
+ hasMatches: hasSearchResults,
995
+ isSourceNotEmpty: hasVariables
996
+ } = useFilteredVariables(searchValue, fontVariablePropTypeUtil.key);
997
+ const handleSetVariable = (key) => {
998
+ setVariable(key);
999
+ closePopover();
1000
+ };
1001
+ const actions = [];
1002
+ if (onAdd) {
1003
+ actions.push(
1004
+ /* @__PURE__ */ React11.createElement(IconButton8, { key: "add", size: SIZE8, onClick: onAdd }, /* @__PURE__ */ React11.createElement(PlusIcon2, { fontSize: SIZE8 }))
1005
+ );
1006
+ }
1007
+ if (onSettings) {
1008
+ actions.push(
1009
+ /* @__PURE__ */ React11.createElement(IconButton8, { key: "settings", size: SIZE8, onClick: onSettings }, /* @__PURE__ */ React11.createElement(SettingsIcon2, { fontSize: SIZE8 }))
1010
+ );
1011
+ }
1012
+ const items = variables.map(({ value, label, key }) => ({
1013
+ type: "item",
1014
+ value: key,
1015
+ label,
1016
+ icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: SIZE8 }),
1017
+ secondaryText: value,
1018
+ onEdit: () => onEdit?.(key)
1019
+ }));
1020
+ const handleSearch = (search) => {
1021
+ setSearchValue(search);
1022
+ };
1023
+ const handleClearSearch = () => {
1024
+ setSearchValue("");
1025
+ };
1026
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(
1027
+ PopoverHeader6,
596
1028
  {
597
- ...bindPopover2(creationPopupState),
598
- anchorEl: anchorRef.current,
599
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
600
- transformOrigin: { vertical: "top", horizontal: "right" }
601
- },
602
- colorCreationEnabled && /* @__PURE__ */ React4.createElement(ColorVariableCreation, { onClose: creationPopupState.close }),
603
- fontCreationEnabled && /* @__PURE__ */ React4.createElement(FontVariableCreation, { onClose: creationPopupState.close })
1029
+ title: __10("Variables", "elementor"),
1030
+ onClose: closePopover,
1031
+ icon: /* @__PURE__ */ React11.createElement(ColorFilterIcon2, { fontSize: SIZE8 }),
1032
+ actions
1033
+ }
1034
+ ), hasVariables && /* @__PURE__ */ React11.createElement(
1035
+ PopoverSearch2,
1036
+ {
1037
+ value: searchValue,
1038
+ onSearch: handleSearch,
1039
+ placeholder: __10("Search", "elementor")
1040
+ }
1041
+ ), /* @__PURE__ */ React11.createElement(Divider6, null), /* @__PURE__ */ React11.createElement(PopoverScrollableContent6, null, hasVariables && hasSearchResults && /* @__PURE__ */ React11.createElement(
1042
+ PopoverMenuList2,
1043
+ {
1044
+ items,
1045
+ onSelect: handleSetVariable,
1046
+ onClose: () => {
1047
+ },
1048
+ selectedValue: variable,
1049
+ "data-testid": "font-variables-list",
1050
+ menuListTemplate: VariablesStyledMenuList,
1051
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React11.createElement(MenuItemContent, { item })
1052
+ }
1053
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React11.createElement(
1054
+ NoSearchResults,
1055
+ {
1056
+ searchValue,
1057
+ onClear: handleClearSearch,
1058
+ icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: "large" })
1059
+ }
1060
+ ), !hasVariables && /* @__PURE__ */ React11.createElement(
1061
+ NoVariables,
1062
+ {
1063
+ title: __10("Create your first font variable", "elementor"),
1064
+ icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: "large" }),
1065
+ onAdd
1066
+ }
604
1067
  )));
605
1068
  };
606
1069
 
607
- // src/controls/color-variables-selection-control.tsx
608
- var ColorVariablesSelectionControl = () => {
609
- const { setValue } = useBoundProp4();
610
- const { value: variableValue } = useBoundProp4(colorVariablePropTypeUtil);
1070
+ // src/components/variable-selection-popover.tsx
1071
+ var VIEW_LIST = "list";
1072
+ var VIEW_ADD = "add";
1073
+ var VIEW_EDIT = "edit";
1074
+ var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
1075
+ const [currentView, setCurrentView] = useState7(VIEW_LIST);
1076
+ const editIdRef = useRef5("");
1077
+ const anchorRef = useRef5(null);
1078
+ return /* @__PURE__ */ React12.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React12.createElement(Box3, { ref: anchorRef }, renderStage({
1079
+ propTypeKey,
1080
+ currentView,
1081
+ selectedVariable,
1082
+ editIdRef,
1083
+ setCurrentView,
1084
+ closePopover
1085
+ })));
1086
+ };
1087
+ function renderStage(props) {
1088
+ const handleSubmitOnEdit = () => {
1089
+ if (props?.selectedVariable?.key === props.editIdRef.current) {
1090
+ props.closePopover();
1091
+ } else {
1092
+ props.setCurrentView(VIEW_LIST);
1093
+ }
1094
+ };
1095
+ if (fontVariablePropTypeUtil.key === props.propTypeKey) {
1096
+ if (VIEW_LIST === props.currentView) {
1097
+ return /* @__PURE__ */ React12.createElement(
1098
+ FontVariablesSelection,
1099
+ {
1100
+ closePopover: props.closePopover,
1101
+ onAdd: () => {
1102
+ props.setCurrentView(VIEW_ADD);
1103
+ },
1104
+ onEdit: (key) => {
1105
+ props.editIdRef.current = key;
1106
+ props.setCurrentView(VIEW_EDIT);
1107
+ }
1108
+ }
1109
+ );
1110
+ }
1111
+ if (VIEW_ADD === props.currentView) {
1112
+ return /* @__PURE__ */ React12.createElement(
1113
+ FontVariableCreation,
1114
+ {
1115
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1116
+ onClose: props.closePopover
1117
+ }
1118
+ );
1119
+ }
1120
+ if (VIEW_EDIT === props.currentView) {
1121
+ return /* @__PURE__ */ React12.createElement(
1122
+ FontVariableEdit,
1123
+ {
1124
+ editId: props.editIdRef.current ?? "",
1125
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1126
+ onClose: props.closePopover,
1127
+ onSubmit: handleSubmitOnEdit
1128
+ }
1129
+ );
1130
+ }
1131
+ }
1132
+ if (colorVariablePropTypeUtil.key === props.propTypeKey) {
1133
+ if (VIEW_LIST === props.currentView) {
1134
+ return /* @__PURE__ */ React12.createElement(
1135
+ ColorVariablesSelection,
1136
+ {
1137
+ closePopover: props.closePopover,
1138
+ onAdd: () => {
1139
+ props.setCurrentView(VIEW_ADD);
1140
+ },
1141
+ onEdit: (key) => {
1142
+ props.editIdRef.current = key;
1143
+ props.setCurrentView(VIEW_EDIT);
1144
+ }
1145
+ }
1146
+ );
1147
+ }
1148
+ if (VIEW_ADD === props.currentView) {
1149
+ return /* @__PURE__ */ React12.createElement(
1150
+ ColorVariableCreation,
1151
+ {
1152
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1153
+ onClose: props.closePopover
1154
+ }
1155
+ );
1156
+ }
1157
+ if (VIEW_EDIT === props.currentView) {
1158
+ return /* @__PURE__ */ React12.createElement(
1159
+ ColorVariableEdit,
1160
+ {
1161
+ editId: props.editIdRef.current ?? "",
1162
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1163
+ onClose: props.closePopover,
1164
+ onSubmit: handleSubmitOnEdit
1165
+ }
1166
+ );
1167
+ }
1168
+ }
1169
+ return null;
1170
+ }
1171
+
1172
+ // src/controls/color-variable-control.tsx
1173
+ var ColorVariableControl = () => {
1174
+ const { setValue: setColor } = useBoundProp5();
1175
+ const { value: variableValue } = useBoundProp5(colorVariablePropTypeUtil);
1176
+ const anchorRef = useRef6(null);
1177
+ const popupId = useId2();
1178
+ const popupState = usePopupState3({
1179
+ variant: "popover",
1180
+ popupId: `elementor-variables-list-${popupId}`
1181
+ });
611
1182
  const selectedVariable = useVariable(variableValue);
612
1183
  if (!selectedVariable) {
613
1184
  throw new Error(`Global color variable ${variableValue} not found`);
614
1185
  }
615
1186
  const unlinkVariable = () => {
616
- setValue(colorPropTypeUtil.create(selectedVariable.value));
1187
+ setColor(colorPropTypeUtil.create(selectedVariable.value));
617
1188
  };
618
- return /* @__PURE__ */ React5.createElement(
619
- VariablesSelectionPopover,
1189
+ return /* @__PURE__ */ React13.createElement(Box4, { ref: anchorRef }, /* @__PURE__ */ React13.createElement(
1190
+ VariableTag,
1191
+ {
1192
+ label: selectedVariable.label,
1193
+ startIcon: /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(ColorFilterIcon3, { fontSize: SIZE }), /* @__PURE__ */ React13.createElement(ColorIndicator, { size: "inherit", value: selectedVariable.value, component: "span" })),
1194
+ onUnlink: unlinkVariable,
1195
+ ...bindTrigger3(popupState)
1196
+ }
1197
+ ), /* @__PURE__ */ React13.createElement(
1198
+ Popover3,
620
1199
  {
621
- selectedVariable,
622
- unlinkVariable,
623
- startTagAdornment: /* @__PURE__ */ React5.createElement(ColorIndicator, { size: "inherit", component: "span", value: selectedVariable.value })
1200
+ disableScrollLock: true,
1201
+ anchorEl: anchorRef.current,
1202
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
1203
+ transformOrigin: { vertical: "top", horizontal: "right" },
1204
+ PaperProps: {
1205
+ sx: { my: 1 }
1206
+ },
1207
+ ...bindPopover3(popupState)
624
1208
  },
625
- ({ closePopover }) => /* @__PURE__ */ React5.createElement(ColorVariablesSelection, { onSelect: closePopover })
626
- );
1209
+ /* @__PURE__ */ React13.createElement(
1210
+ VariableSelectionPopover,
1211
+ {
1212
+ selectedVariable,
1213
+ closePopover: popupState.close,
1214
+ propTypeKey: colorVariablePropTypeUtil.key
1215
+ }
1216
+ )
1217
+ ));
627
1218
  };
628
1219
 
629
1220
  // src/hooks/use-prop-color-variable-action.tsx
630
- import * as React6 from "react";
631
- import { useBoundProp as useBoundProp5 } from "@elementor/editor-editing-panel";
632
- import { ColorFilterIcon as ColorFilterIcon2 } from "@elementor/icons";
633
- import { __ as __4 } from "@wordpress/i18n";
1221
+ import * as React14 from "react";
1222
+ import { useBoundProp as useBoundProp6 } from "@elementor/editor-editing-panel";
1223
+ import { ColorFilterIcon as ColorFilterIcon4 } from "@elementor/icons";
1224
+ import { __ as __11 } from "@wordpress/i18n";
634
1225
 
635
1226
  // src/utils.ts
636
1227
  var hasAssignedColorVariable = (propValue) => {
@@ -648,13 +1239,15 @@ var supportsFontVariables = (propType) => {
648
1239
 
649
1240
  // src/hooks/use-prop-color-variable-action.tsx
650
1241
  var usePropColorVariableAction = () => {
651
- const { propType } = useBoundProp5();
1242
+ const { propType } = useBoundProp6();
652
1243
  const visible = !!propType && supportsColorVariables(propType);
653
1244
  return {
654
1245
  visible,
655
- icon: ColorFilterIcon2,
656
- title: __4("Variables", "elementor"),
657
- popoverContent: ({ closePopover }) => /* @__PURE__ */ React6.createElement(ColorVariablesSelection, { onSelect: closePopover })
1246
+ icon: ColorFilterIcon4,
1247
+ title: __11("Variables", "elementor"),
1248
+ content: ({ close: closePopover }) => {
1249
+ return /* @__PURE__ */ React14.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1250
+ }
658
1251
  };
659
1252
  };
660
1253
 
@@ -669,81 +1262,73 @@ var variableTransformer = createTransformer((value) => {
669
1262
 
670
1263
  // src/init-color-variables.ts
671
1264
  var { registerPopoverAction } = controlActionsMenu;
672
- function initColorVariables() {
1265
+ var conditions = {
1266
+ backgroundOverlay: ({ value: prop }) => {
1267
+ return hasAssignedColorVariable(backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
1268
+ },
1269
+ boxShadow: ({ value: prop }) => {
1270
+ return hasAssignedColorVariable(shadowPropTypeUtil.extract(prop)?.color);
1271
+ }
1272
+ };
1273
+ function registerControlsAndActions() {
673
1274
  registerControlReplacement({
674
- component: ColorVariablesSelectionControl,
1275
+ component: ColorVariableControl,
675
1276
  condition: ({ value }) => hasAssignedColorVariable(value)
676
1277
  });
677
1278
  registerPopoverAction({
678
1279
  id: "color-variables",
679
1280
  useProps: usePropColorVariableAction
680
1281
  });
1282
+ }
1283
+ function registerRepeaterItemIcons() {
1284
+ injectIntoRepeaterItemIcon({
1285
+ id: "color-variables-background-icon",
1286
+ component: BackgroundRepeaterColorIndicator,
1287
+ condition: conditions.backgroundOverlay
1288
+ });
1289
+ injectIntoRepeaterItemIcon({
1290
+ id: "color-variables-icon",
1291
+ component: BoxShadowRepeaterColorIndicator,
1292
+ condition: conditions.boxShadow
1293
+ });
1294
+ }
1295
+ function registerRepeaterItemLabels() {
1296
+ injectIntoRepeaterItemLabel({
1297
+ id: "color-variables-label",
1298
+ component: BackgroundRepeaterLabel,
1299
+ condition: conditions.backgroundOverlay
1300
+ });
1301
+ }
1302
+ function registerStyleTransformers() {
681
1303
  styleTransformersRegistry.register(colorVariablePropTypeUtil.key, variableTransformer);
682
1304
  }
1305
+ function initColorVariables() {
1306
+ registerControlsAndActions();
1307
+ registerRepeaterItemIcons();
1308
+ registerRepeaterItemLabels();
1309
+ registerStyleTransformers();
1310
+ }
683
1311
 
684
1312
  // src/init-font-variables.ts
685
1313
  import { styleTransformersRegistry as styleTransformersRegistry2 } from "@elementor/editor-canvas";
686
1314
  import { controlActionsMenu as controlActionsMenu2, registerControlReplacement as registerControlReplacement2 } from "@elementor/editor-editing-panel";
687
1315
 
688
- // src/controls/font-variables-selection-control.tsx
689
- import * as React8 from "react";
1316
+ // src/controls/font-variable-control.tsx
1317
+ import * as React15 from "react";
1318
+ import { useId as useId3, useRef as useRef7 } from "react";
690
1319
  import { useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
691
1320
  import { stringPropTypeUtil } from "@elementor/editor-props";
692
-
693
- // src/components/font-variables-selection.tsx
694
- import * as React7 from "react";
695
- import { Fragment as Fragment4 } from "react";
696
- import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
697
- import { EditIcon as EditIcon2, TextIcon as TextIcon2 } from "@elementor/icons";
698
- import { Box as Box3, Divider as Divider4, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, MenuList as MenuList2 } from "@elementor/ui";
699
- var FontVariablesSelection = ({ onSelect }) => {
700
- const { value: variable, setValue: setVariable } = useBoundProp6(fontVariablePropTypeUtil);
701
- const variables = usePropVariables(fontVariablePropTypeUtil.key);
702
- const handleSetVariable = (key) => {
703
- setVariable(key);
704
- onSelect?.();
705
- };
706
- return /* @__PURE__ */ React7.createElement(Fragment4, null, /* @__PURE__ */ React7.createElement(Divider4, null), /* @__PURE__ */ React7.createElement(Box3, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React7.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React7.createElement(
707
- StyledMenuItem,
708
- {
709
- key,
710
- onClick: () => handleSetVariable(key),
711
- selected: key === variable
712
- },
713
- /* @__PURE__ */ React7.createElement(ListItemIcon2, null, /* @__PURE__ */ React7.createElement(TextIcon2, null)),
714
- /* @__PURE__ */ React7.createElement(
715
- ListItemText2,
716
- {
717
- primary: label,
718
- secondary: value,
719
- primaryTypographyProps: {
720
- variant: "body2",
721
- color: "text.secondary",
722
- style: {
723
- lineHeight: 2,
724
- display: "inline-block",
725
- overflow: "hidden",
726
- textOverflow: "ellipsis",
727
- whiteSpace: "nowrap",
728
- maxWidth: "81px"
729
- }
730
- },
731
- secondaryTypographyProps: {
732
- variant: "caption",
733
- color: "text.tertiary",
734
- style: { marginTop: "1px", lineHeight: "1" }
735
- },
736
- sx: { display: "flex", alignItems: "center", gap: 1 }
737
- }
738
- ),
739
- /* @__PURE__ */ React7.createElement(EditIcon2, { color: "action", fontSize: "inherit", sx: { mx: 1, opacity: "0" } })
740
- )))));
741
- };
742
-
743
- // src/controls/font-variables-selection-control.tsx
744
- var FontVariablesSelectionControl = () => {
1321
+ import { ColorFilterIcon as ColorFilterIcon5 } from "@elementor/icons";
1322
+ import { bindPopover as bindPopover4, bindTrigger as bindTrigger4, Box as Box5, Popover as Popover4, usePopupState as usePopupState4 } from "@elementor/ui";
1323
+ var FontVariableControl = () => {
745
1324
  const { setValue: setFontFamily } = useBoundProp7();
746
1325
  const { value: variableValue } = useBoundProp7(fontVariablePropTypeUtil);
1326
+ const anchorRef = useRef7(null);
1327
+ const popupId = useId3();
1328
+ const popupState = usePopupState4({
1329
+ variant: "popover",
1330
+ popupId: `elementor-variables-list-${popupId}`
1331
+ });
747
1332
  const selectedVariable = useVariable(variableValue);
748
1333
  if (!selectedVariable) {
749
1334
  throw new Error(`Global font variable ${variableValue} not found`);
@@ -751,22 +1336,52 @@ var FontVariablesSelectionControl = () => {
751
1336
  const unlinkVariable = () => {
752
1337
  setFontFamily(stringPropTypeUtil.create(selectedVariable.value));
753
1338
  };
754
- return /* @__PURE__ */ React8.createElement(VariablesSelectionPopover, { selectedVariable, unlinkVariable }, ({ closePopover }) => /* @__PURE__ */ React8.createElement(FontVariablesSelection, { onSelect: closePopover }));
1339
+ return /* @__PURE__ */ React15.createElement(Box5, { ref: anchorRef }, /* @__PURE__ */ React15.createElement(
1340
+ VariableTag,
1341
+ {
1342
+ label: selectedVariable.label,
1343
+ startIcon: /* @__PURE__ */ React15.createElement(ColorFilterIcon5, { fontSize: SIZE }),
1344
+ onUnlink: unlinkVariable,
1345
+ ...bindTrigger4(popupState)
1346
+ }
1347
+ ), /* @__PURE__ */ React15.createElement(
1348
+ Popover4,
1349
+ {
1350
+ disableScrollLock: true,
1351
+ anchorEl: anchorRef.current,
1352
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
1353
+ transformOrigin: { vertical: "top", horizontal: "right" },
1354
+ PaperProps: {
1355
+ sx: { my: 1 }
1356
+ },
1357
+ ...bindPopover4(popupState)
1358
+ },
1359
+ /* @__PURE__ */ React15.createElement(
1360
+ VariableSelectionPopover,
1361
+ {
1362
+ selectedVariable,
1363
+ closePopover: popupState.close,
1364
+ propTypeKey: fontVariablePropTypeUtil.key
1365
+ }
1366
+ )
1367
+ ));
755
1368
  };
756
1369
 
757
1370
  // src/hooks/use-prop-font-variable-action.tsx
758
- import * as React9 from "react";
1371
+ import * as React16 from "react";
759
1372
  import { useBoundProp as useBoundProp8 } from "@elementor/editor-editing-panel";
760
- import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
761
- import { __ as __5 } from "@wordpress/i18n";
1373
+ import { ColorFilterIcon as ColorFilterIcon6 } from "@elementor/icons";
1374
+ import { __ as __12 } from "@wordpress/i18n";
762
1375
  var usePropFontVariableAction = () => {
763
1376
  const { propType } = useBoundProp8();
764
1377
  const visible = !!propType && supportsFontVariables(propType);
765
1378
  return {
766
1379
  visible,
767
- icon: ColorFilterIcon3,
768
- title: __5("Variables", "elementor"),
769
- popoverContent: ({ closePopover }) => /* @__PURE__ */ React9.createElement(FontVariablesSelection, { onSelect: closePopover })
1380
+ icon: ColorFilterIcon6,
1381
+ title: __12("Variables", "elementor"),
1382
+ content: ({ close: closePopover }) => {
1383
+ return /* @__PURE__ */ React16.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1384
+ }
770
1385
  };
771
1386
  };
772
1387
 
@@ -774,7 +1389,7 @@ var usePropFontVariableAction = () => {
774
1389
  var { registerPopoverAction: registerPopoverAction2 } = controlActionsMenu2;
775
1390
  function initFontVariables() {
776
1391
  registerControlReplacement2({
777
- component: FontVariablesSelectionControl,
1392
+ component: FontVariableControl,
778
1393
  condition: ({ value }) => hasAssignedFontVariable(value)
779
1394
  });
780
1395
  registerPopoverAction2({
@@ -785,8 +1400,8 @@ function initFontVariables() {
785
1400
  }
786
1401
 
787
1402
  // src/renderers/style-variables-renderer.tsx
788
- import * as React10 from "react";
789
- import { useEffect, useState as useState3 } from "react";
1403
+ import * as React17 from "react";
1404
+ import { useEffect, useState as useState8 } from "react";
790
1405
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
791
1406
  import { Portal } from "@elementor/ui";
792
1407
 
@@ -807,13 +1422,13 @@ function StyleVariablesRenderer() {
807
1422
  }
808
1423
  const cssVariables = convertToCssVariables(styleVariables);
809
1424
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
810
- return /* @__PURE__ */ React10.createElement(Portal, { container }, /* @__PURE__ */ React10.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
1425
+ return /* @__PURE__ */ React17.createElement(Portal, { container }, /* @__PURE__ */ React17.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
811
1426
  }
812
1427
  function usePortalContainer() {
813
1428
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
814
1429
  }
815
1430
  function useStyleVariables() {
816
- const [variables, setVariables] = useState3({});
1431
+ const [variables, setVariables] = useState8({});
817
1432
  useEffect(() => {
818
1433
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
819
1434
  return () => {