@elementor/editor-variables 0.12.0 → 0.14.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 (34) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/index.js +918 -332
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +961 -329
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +10 -9
  7. package/src/components/color-variable-creation.tsx +65 -64
  8. package/src/components/color-variable-edit.tsx +117 -0
  9. package/src/components/color-variables-selection.tsx +98 -52
  10. package/src/components/font-variable-creation.tsx +143 -0
  11. package/src/components/font-variable-edit.tsx +146 -0
  12. package/src/components/font-variables-selection.tsx +97 -51
  13. package/src/components/ui/menu-item-content.tsx +51 -0
  14. package/src/components/ui/no-search-results.tsx +38 -0
  15. package/src/components/ui/no-variables.tsx +35 -0
  16. package/src/components/ui/styled-menu-list.tsx +31 -0
  17. package/src/components/variable-selection-popover.tsx +133 -0
  18. package/src/components/variables-repeater-item-slot.tsx +29 -0
  19. package/src/controls/color-variable-control.tsx +90 -0
  20. package/src/controls/font-variable-control.tsx +88 -0
  21. package/src/create-style-variables-repository.ts +3 -2
  22. package/src/hooks/use-prop-color-variable-action.tsx +7 -2
  23. package/src/hooks/use-prop-font-variable-action.tsx +7 -2
  24. package/src/hooks/use-prop-variables.ts +31 -4
  25. package/src/init-color-variables.ts +51 -3
  26. package/src/init-font-variables.ts +2 -2
  27. package/src/service.ts +23 -3
  28. package/src/storage.ts +5 -1
  29. package/src/types.ts +12 -8
  30. package/src/components/styled-menu-item.tsx +0 -10
  31. package/src/components/variables-selection-popover.tsx +0 -106
  32. package/src/controls/color-variables-selection-control.tsx +0 -34
  33. package/src/controls/font-variables-selection-control.tsx +0 -29
  34. /package/src/components/{color-indicator.tsx → ui/color-indicator.tsx} +0 -0
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 React4 from "react";
10
- import { useBoundProp as useBoundProp3 } 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,6 +264,20 @@ 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
+ };
267
281
  var normalizeVariables = (propKey) => {
268
282
  const variables = service.variables();
269
283
  styleVariablesRepository.update(variables);
@@ -281,109 +295,93 @@ var createVariable = (newVariable) => {
281
295
  return id;
282
296
  });
283
297
  };
298
+ var updateVariable = (updateId, { value, label }) => {
299
+ return service.update(updateId, { value, label }).then(({ id, variable }) => {
300
+ styleVariablesRepository.update({
301
+ [id]: variable
302
+ });
303
+ return id;
304
+ });
305
+ };
284
306
 
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
- }
307
+ // src/components/ui/color-indicator.tsx
308
+ import { styled, UnstableColorIndicator } from "@elementor/ui";
309
+ var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
310
+ borderRadius: `${theme.shape.borderRadius / 2}px`
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,
311
- {
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
- )))));
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 });
344
329
  };
345
330
 
346
- // src/components/variables-selection-popover.tsx
347
- import * as React3 from "react";
348
- import { useId, useRef as useRef2 } from "react";
349
- import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
350
- import { ColorFilterIcon, DetachIcon, PlusIcon } from "@elementor/icons";
331
+ // src/controls/color-variable-control.tsx
332
+ import * as React12 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 ColorFilterIcon4, DetachIcon } from "@elementor/icons";
351
337
  import {
352
- bindPopover as bindPopover2,
353
- bindTrigger,
354
- Box as Box3,
355
- IconButton,
356
- Popover as Popover2,
357
- Stack as Stack2,
358
- Typography,
338
+ bindPopover as bindPopover3,
339
+ bindTrigger as bindTrigger3,
340
+ Box,
341
+ IconButton as IconButton8,
342
+ Popover as Popover3,
343
+ Stack as Stack7,
344
+ Typography as Typography3,
359
345
  UnstableTag as Tag,
360
- usePopupState
346
+ usePopupState as usePopupState3
361
347
  } from "@elementor/ui";
362
- import { __ as __2 } from "@wordpress/i18n";
348
+ import { __ as __10 } from "@wordpress/i18n";
349
+
350
+ // src/components/variable-selection-popover.tsx
351
+ import * as React11 from "react";
352
+ import { useRef as useRef5, useState as useState7 } from "react";
353
+
354
+ // src/prop-types/color-variable-prop-type.ts
355
+ import { createPropUtils } from "@elementor/editor-props";
356
+ import { z } from "@elementor/schema";
357
+ var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
358
+
359
+ // src/prop-types/font-variable-prop-type.ts
360
+ import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
361
+ import { z as z2 } from "@elementor/schema";
362
+ var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
363
363
 
364
364
  // src/components/color-variable-creation.tsx
365
365
  import * as React2 from "react";
366
366
  import { useRef, useState } from "react";
367
- import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
367
+ import { useBoundProp } from "@elementor/editor-controls";
368
368
  import { PopoverHeader } from "@elementor/editor-ui";
369
- import { BrushIcon } from "@elementor/icons";
369
+ import { ArrowLeftIcon, BrushIcon } from "@elementor/icons";
370
370
  import {
371
- bindPopover,
372
- Box as Box2,
373
371
  Button,
374
372
  CardActions,
375
- Divider as Divider2,
373
+ Divider,
376
374
  FormLabel,
377
375
  Grid,
378
- Popover,
376
+ IconButton,
379
377
  Stack,
380
378
  TextField,
381
379
  UnstableColorField
382
380
  } from "@elementor/ui";
383
381
  import { __ } from "@wordpress/i18n";
384
382
  var SIZE = "tiny";
385
- var ColorVariableCreation = ({ popupState }) => {
386
- const { setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
383
+ var ColorVariableCreation = ({ onGoBack, onClose }) => {
384
+ const { setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
387
385
  const [color, setColor] = useState("");
388
386
  const [label, setLabel] = useState("");
389
387
  const anchorRef = useRef(null);
@@ -393,7 +391,7 @@ var ColorVariableCreation = ({ popupState }) => {
393
391
  };
394
392
  const closePopover = () => {
395
393
  resetFields();
396
- popupState.close();
394
+ onClose();
397
395
  };
398
396
  const handleCreate = () => {
399
397
  createVariable({
@@ -405,148 +403,740 @@ var ColorVariableCreation = ({ popupState }) => {
405
403
  closePopover();
406
404
  });
407
405
  };
408
- const isInValidForm = () => {
406
+ const isFormInvalid = () => {
409
407
  return !color?.trim() || !label?.trim();
410
408
  };
411
- return /* @__PURE__ */ React2.createElement(Box2, { ref: anchorRef }, /* @__PURE__ */ React2.createElement(
412
- Popover,
409
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
410
+ PopoverHeader,
413
411
  {
414
- ...bindPopover(popupState),
415
- anchorEl: anchorRef.current,
416
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
417
- transformOrigin: { vertical: "top", horizontal: "right" }
418
- },
419
- /* @__PURE__ */ React2.createElement(
420
- PopoverHeader,
421
- {
422
- title: __("Create variable", "elementor"),
423
- onClose: closePopover,
424
- icon: /* @__PURE__ */ React2.createElement(BrushIcon, { fontSize: SIZE })
425
- }
426
- ),
427
- /* @__PURE__ */ React2.createElement(Divider2, null),
428
- /* @__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(
429
- TextField,
430
- {
431
- size: "tiny",
432
- fullWidth: true,
433
- value: label,
434
- onChange: (e) => setLabel(e.target.value)
412
+ icon: /* @__PURE__ */ React2.createElement(React2.Fragment, null, onGoBack && /* @__PURE__ */ React2.createElement(IconButton, { size: SIZE, "aria-label": __("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React2.createElement(ArrowLeftIcon, { fontSize: SIZE })), /* @__PURE__ */ React2.createElement(BrushIcon, { fontSize: SIZE })),
413
+ title: __("Create variable", "elementor"),
414
+ onClose: closePopover
415
+ }
416
+ ), /* @__PURE__ */ React2.createElement(Divider, 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(
417
+ TextField,
418
+ {
419
+ size: "tiny",
420
+ fullWidth: true,
421
+ value: label,
422
+ onChange: (e) => setLabel(e.target.value)
423
+ }
424
+ ))), /* @__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(
425
+ UnstableColorField,
426
+ {
427
+ size: "tiny",
428
+ fullWidth: true,
429
+ value: color,
430
+ onChange: setColor,
431
+ slotProps: {
432
+ colorPicker: {
433
+ anchorEl: anchorRef.current,
434
+ anchorOrigin: { vertical: "top", horizontal: "right" },
435
+ transformOrigin: { vertical: "top", horizontal: -10 }
436
+ }
435
437
  }
436
- ))), /* @__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(
437
- UnstableColorField,
438
- {
439
- size: "tiny",
440
- fullWidth: true,
441
- value: color,
442
- onChange: setColor,
443
- slotProps: {
444
- colorPicker: {
445
- anchorEl: anchorRef.current,
446
- anchorOrigin: { vertical: "top", horizontal: "right" },
447
- transformOrigin: { vertical: "top", horizontal: -10 }
448
- }
438
+ }
439
+ )))), /* @__PURE__ */ React2.createElement(CardActions, null, /* @__PURE__ */ React2.createElement(Button, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __("Create", "elementor"))));
440
+ };
441
+
442
+ // src/components/color-variable-edit.tsx
443
+ import * as React3 from "react";
444
+ import { useRef as useRef2, useState as useState2 } from "react";
445
+ import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
446
+ import { ArrowLeftIcon as ArrowLeftIcon2, BrushIcon as BrushIcon2 } from "@elementor/icons";
447
+ import {
448
+ Button as Button2,
449
+ CardActions as CardActions2,
450
+ Divider as Divider2,
451
+ FormLabel as FormLabel2,
452
+ Grid as Grid2,
453
+ IconButton as IconButton2,
454
+ Stack as Stack2,
455
+ TextField as TextField2,
456
+ UnstableColorField as UnstableColorField2
457
+ } from "@elementor/ui";
458
+ import { __ as __2 } from "@wordpress/i18n";
459
+ var SIZE2 = "tiny";
460
+ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
461
+ const variable = useVariable(editId);
462
+ if (!variable) {
463
+ throw new Error(`Global color variable not found`);
464
+ }
465
+ const anchorRef = useRef2(null);
466
+ const [color, setColor] = useState2(variable.value);
467
+ const [label, setLabel] = useState2(variable.label);
468
+ const handleUpdate = () => {
469
+ updateVariable(editId, {
470
+ value: color,
471
+ label
472
+ }).then(() => {
473
+ onSubmit?.();
474
+ });
475
+ };
476
+ const noValueChanged = () => color === variable.value && label === variable.label;
477
+ const hasEmptyValue = () => "" === color.trim() || "" === label.trim();
478
+ const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
479
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
480
+ PopoverHeader2,
481
+ {
482
+ title: __2("Edit variable", "elementor"),
483
+ onClose,
484
+ 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(ArrowLeftIcon2, { fontSize: SIZE2 })), /* @__PURE__ */ React3.createElement(BrushIcon2, { fontSize: SIZE2 }))
485
+ }
486
+ ), /* @__PURE__ */ React3.createElement(Divider2, 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(
487
+ TextField2,
488
+ {
489
+ size: "tiny",
490
+ fullWidth: true,
491
+ value: label,
492
+ onChange: (e) => setLabel(e.target.value)
493
+ }
494
+ ))), /* @__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(
495
+ UnstableColorField2,
496
+ {
497
+ size: "tiny",
498
+ fullWidth: true,
499
+ value: color,
500
+ onChange: setColor,
501
+ slotProps: {
502
+ colorPicker: {
503
+ anchorEl: anchorRef.current,
504
+ anchorOrigin: { vertical: "top", horizontal: "right" },
505
+ transformOrigin: { vertical: "top", horizontal: -10 }
449
506
  }
450
507
  }
451
- )))),
452
- /* @__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: isInValidForm(), onClick: handleCreate }, __("Create", "elementor")))
508
+ }
509
+ )))), /* @__PURE__ */ React3.createElement(CardActions2, null, /* @__PURE__ */ React3.createElement(Button2, { size: "small", variant: "contained", disabled: isSaveDisabled(), onClick: handleUpdate }, __2("Save", "elementor"))));
510
+ };
511
+
512
+ // src/components/color-variables-selection.tsx
513
+ import * as React7 from "react";
514
+ import { useState as useState3 } from "react";
515
+ import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
516
+ import { PopoverHeader as PopoverHeader3, PopoverMenuList, PopoverSearch } from "@elementor/editor-ui";
517
+ import { ColorFilterIcon as ColorFilterIcon2, PlusIcon, SettingsIcon } from "@elementor/icons";
518
+ import { Divider as Divider3, IconButton as IconButton4 } from "@elementor/ui";
519
+ import { __ as __6 } from "@wordpress/i18n";
520
+
521
+ // src/components/ui/menu-item-content.tsx
522
+ import * as React4 from "react";
523
+ import { EditIcon } from "@elementor/icons";
524
+ import { IconButton as IconButton3, ListItemIcon, ListItemText } from "@elementor/ui";
525
+ import { __ as __3 } from "@wordpress/i18n";
526
+ var SIZE3 = "tiny";
527
+ var MenuItemContent = ({ item }) => {
528
+ const onEdit = item.onEdit;
529
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React4.createElement(
530
+ ListItemText,
531
+ {
532
+ primary: item.label || item.value,
533
+ secondary: item.secondaryText,
534
+ primaryTypographyProps: {
535
+ variant: "body2",
536
+ color: "text.secondary",
537
+ style: {
538
+ lineHeight: 2,
539
+ display: "inline-block",
540
+ overflow: "hidden",
541
+ textOverflow: "ellipsis",
542
+ whiteSpace: "nowrap",
543
+ maxWidth: "81px"
544
+ }
545
+ },
546
+ secondaryTypographyProps: {
547
+ variant: "caption",
548
+ color: "text.tertiary",
549
+ style: { marginTop: "1px", lineHeight: "1" }
550
+ },
551
+ sx: { display: "flex", alignItems: "center", gap: 1 }
552
+ }
553
+ ), !!onEdit && /* @__PURE__ */ React4.createElement(
554
+ IconButton3,
555
+ {
556
+ sx: { mx: 1, opacity: "0" },
557
+ onClick: (e) => {
558
+ e.stopPropagation();
559
+ onEdit(item.value);
560
+ },
561
+ "aria-label": __3("Edit", "elementor")
562
+ },
563
+ /* @__PURE__ */ React4.createElement(EditIcon, { color: "action", fontSize: SIZE3 })
453
564
  ));
454
565
  };
455
566
 
456
- // src/components/variables-selection-popover.tsx
457
- var SIZE2 = "tiny";
458
- var VariablesSelectionPopover = ({
459
- selectedVariable,
460
- unlinkVariable,
461
- startTagAdornment,
462
- children
463
- }) => {
464
- const id = useId();
465
- const popupState = usePopupState({ variant: "popover", popupId: `elementor-variables-action-${id}` });
466
- const creationPopupState = usePopupState({ variant: "popover", popupId: `elementor-variables-creation-${id}` });
467
- const closePopover = () => popupState.close();
468
- const handleCreateButtonClick = (event) => {
567
+ // src/components/ui/no-search-results.tsx
568
+ import * as React5 from "react";
569
+ import { ColorFilterIcon } from "@elementor/icons";
570
+ import { Link, Stack as Stack3, Typography } from "@elementor/ui";
571
+ import { __ as __4 } from "@wordpress/i18n";
572
+ var NoSearchResults = ({ searchValue, onClear }) => {
573
+ return /* @__PURE__ */ React5.createElement(
574
+ Stack3,
575
+ {
576
+ gap: 1,
577
+ alignItems: "center",
578
+ justifyContent: "center",
579
+ height: "100%",
580
+ color: "text.secondary",
581
+ sx: { p: 2.5, pb: 5.5 }
582
+ },
583
+ /* @__PURE__ */ React5.createElement(ColorFilterIcon, { fontSize: "large" }),
584
+ /* @__PURE__ */ React5.createElement(Typography, { align: "center", variant: "subtitle2" }, __4("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React5.createElement("br", null), "\u201C", searchValue, "\u201D."),
585
+ /* @__PURE__ */ React5.createElement(Typography, { align: "center", variant: "caption" }, __4("Try something else.", "elementor"), /* @__PURE__ */ React5.createElement("br", null), /* @__PURE__ */ React5.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __4("Clear & try again", "elementor")))
586
+ );
587
+ };
588
+
589
+ // src/components/ui/no-variables.tsx
590
+ import * as React6 from "react";
591
+ import { Button as Button3, Stack as Stack4, Typography as Typography2 } from "@elementor/ui";
592
+ import { __ as __5 } from "@wordpress/i18n";
593
+ var NoVariables = ({ icon, onAdd }) => /* @__PURE__ */ React6.createElement(
594
+ Stack4,
595
+ {
596
+ gap: 1,
597
+ alignItems: "center",
598
+ justifyContent: "center",
599
+ height: "100%",
600
+ color: "text.secondary",
601
+ sx: { p: 2.5, pb: 5.5 }
602
+ },
603
+ icon,
604
+ /* @__PURE__ */ React6.createElement(Typography2, { align: "center", variant: "subtitle2" }, __5("Create your first variable", "elementor")),
605
+ /* @__PURE__ */ React6.createElement(Typography2, { align: "center", variant: "caption", maxWidth: "180px" }, __5("Variables are saved attributes that you can apply anywhere on your site.", "elementor")),
606
+ onAdd && /* @__PURE__ */ React6.createElement(Button3, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __5("Create a variable", "elementor"))
607
+ );
608
+
609
+ // src/components/ui/styled-menu-list.tsx
610
+ import { MenuList, styled as styled2 } from "@elementor/ui";
611
+ var VariablesStyledMenuList = styled2(MenuList)(({ theme }) => ({
612
+ "& > li": {
613
+ height: 32,
614
+ width: "100%",
615
+ display: "flex",
616
+ alignItems: "center"
617
+ },
618
+ '& > [role="option"]': {
619
+ ...theme.typography.caption,
620
+ lineHeight: "inherit",
621
+ padding: theme.spacing(0.5, 1, 0.5, 2),
622
+ "&:hover, &:focus": {
623
+ backgroundColor: theme.palette.action.hover
624
+ },
625
+ '&[aria-selected="true"]': {
626
+ backgroundColor: theme.palette.action.selected
627
+ },
628
+ cursor: "pointer",
629
+ textOverflow: "ellipsis",
630
+ position: "absolute",
631
+ top: 0,
632
+ left: 0,
633
+ "&:hover .MuiIconButton-root, .MuiIconButton-root:focus": {
634
+ opacity: 1
635
+ }
636
+ },
637
+ width: "100%",
638
+ position: "relative"
639
+ }));
640
+
641
+ // src/components/color-variables-selection.tsx
642
+ var SIZE4 = "tiny";
643
+ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
644
+ const { value: variable, setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
645
+ const [searchValue, setSearchValue] = useState3("");
646
+ const {
647
+ list: variables,
648
+ hasMatches: hasSearchResults,
649
+ isSourceNotEmpty: hasVariables
650
+ } = useFilteredVariables(searchValue, colorVariablePropTypeUtil.key);
651
+ const handleSetColorVariable = (key) => {
652
+ setVariable(key);
469
653
  closePopover();
470
- bindTrigger(creationPopupState).onClick(event);
471
654
  };
472
- const anchorRef = useRef2(null);
473
- const { label } = selectedVariable;
474
- const colorCreationEnabled = colorVariablePropTypeUtil.key === selectedVariable.type;
475
- return /* @__PURE__ */ React3.createElement(Box3, { ref: anchorRef }, /* @__PURE__ */ React3.createElement(
476
- Tag,
655
+ const actions = [];
656
+ if (onAdd) {
657
+ actions.push(
658
+ /* @__PURE__ */ React7.createElement(IconButton4, { key: "add", size: SIZE4, onClick: onAdd }, /* @__PURE__ */ React7.createElement(PlusIcon, { fontSize: SIZE4 }))
659
+ );
660
+ }
661
+ if (onSettings) {
662
+ actions.push(
663
+ /* @__PURE__ */ React7.createElement(IconButton4, { key: "settings", size: SIZE4, onClick: onSettings }, /* @__PURE__ */ React7.createElement(SettingsIcon, { fontSize: SIZE4 }))
664
+ );
665
+ }
666
+ const items = variables.map(({ value, label, key }) => ({
667
+ type: "item",
668
+ value: key,
669
+ label,
670
+ icon: /* @__PURE__ */ React7.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
671
+ secondaryText: value,
672
+ onEdit: () => onEdit?.(key)
673
+ }));
674
+ const handleSearch = (search) => {
675
+ setSearchValue(search);
676
+ };
677
+ const handleClearSearch = () => {
678
+ setSearchValue("");
679
+ };
680
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
681
+ PopoverHeader3,
682
+ {
683
+ title: __6("Variables", "elementor"),
684
+ icon: /* @__PURE__ */ React7.createElement(ColorFilterIcon2, { fontSize: SIZE4 }),
685
+ onClose: closePopover,
686
+ actions
687
+ }
688
+ ), hasVariables && /* @__PURE__ */ React7.createElement(
689
+ PopoverSearch,
690
+ {
691
+ value: searchValue,
692
+ onSearch: handleSearch,
693
+ placeholder: __6("Search", "elementor")
694
+ }
695
+ ), /* @__PURE__ */ React7.createElement(Divider3, null), hasVariables && hasSearchResults && /* @__PURE__ */ React7.createElement(
696
+ PopoverMenuList,
697
+ {
698
+ items,
699
+ onSelect: handleSetColorVariable,
700
+ onClose: () => {
701
+ },
702
+ selectedValue: variable,
703
+ "data-testid": "color-variables-list",
704
+ menuListTemplate: VariablesStyledMenuList,
705
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React7.createElement(MenuItemContent, { item })
706
+ }
707
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React7.createElement(NoSearchResults, { searchValue, onClear: handleClearSearch }), !hasVariables && /* @__PURE__ */ React7.createElement(NoVariables, { icon: /* @__PURE__ */ React7.createElement(ColorFilterIcon2, { fontSize: "large" }), onAdd }));
708
+ };
709
+
710
+ // src/components/font-variable-creation.tsx
711
+ import * as React8 from "react";
712
+ import { useRef as useRef3, useState as useState4 } from "react";
713
+ import { FontFamilySelector, useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
714
+ import { useFontFamilies } from "@elementor/editor-editing-panel";
715
+ import { PopoverHeader as PopoverHeader4 } from "@elementor/editor-ui";
716
+ import { ArrowLeftIcon as ArrowLeftIcon3, ChevronDownIcon, TextIcon } from "@elementor/icons";
717
+ import {
718
+ bindPopover,
719
+ bindTrigger,
720
+ Button as Button4,
721
+ CardActions as CardActions3,
722
+ Divider as Divider4,
723
+ FormLabel as FormLabel3,
724
+ Grid as Grid3,
725
+ IconButton as IconButton5,
726
+ Popover,
727
+ Stack as Stack5,
728
+ TextField as TextField3,
729
+ UnstableTag,
730
+ usePopupState
731
+ } from "@elementor/ui";
732
+ import { __ as __7 } from "@wordpress/i18n";
733
+ var SIZE5 = "tiny";
734
+ var FontVariableCreation = ({ onClose, onGoBack }) => {
735
+ const fontFamilies = useFontFamilies();
736
+ const { setValue: setVariable } = useBoundProp3(fontVariablePropTypeUtil);
737
+ const [fontFamily, setFontFamily] = useState4("");
738
+ const [label, setLabel] = useState4("");
739
+ const anchorRef = useRef3(null);
740
+ const fontPopoverState = usePopupState({ variant: "popover" });
741
+ const resetFields = () => {
742
+ setFontFamily("");
743
+ setLabel("");
744
+ };
745
+ const closePopover = () => {
746
+ resetFields();
747
+ onClose();
748
+ };
749
+ const handleCreate = () => {
750
+ createVariable({
751
+ value: fontFamily,
752
+ label,
753
+ type: fontVariablePropTypeUtil.key
754
+ }).then((key) => {
755
+ setVariable(key);
756
+ closePopover();
757
+ });
758
+ };
759
+ const isFormInvalid = () => {
760
+ return !fontFamily?.trim() || !label?.trim();
761
+ };
762
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
763
+ PopoverHeader4,
764
+ {
765
+ icon: /* @__PURE__ */ React8.createElement(React8.Fragment, null, onGoBack && /* @__PURE__ */ React8.createElement(IconButton5, { size: SIZE5, "aria-label": __7("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React8.createElement(ArrowLeftIcon3, { fontSize: SIZE5 })), /* @__PURE__ */ React8.createElement(TextIcon, { fontSize: SIZE5 })),
766
+ title: __7("Create variable", "elementor"),
767
+ onClose: closePopover
768
+ }
769
+ ), /* @__PURE__ */ React8.createElement(Divider4, null), /* @__PURE__ */ React8.createElement(Stack5, { p: 1.5, gap: 1.5 }, /* @__PURE__ */ React8.createElement(Grid3, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React8.createElement(FormLabel3, { size: "small" }, __7("Name", "elementor"))), /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React8.createElement(
770
+ TextField3,
477
771
  {
772
+ size: "tiny",
478
773
  fullWidth: true,
479
- showActionsOnHover: true,
480
- ...bindTrigger(popupState),
481
- startIcon: /* @__PURE__ */ React3.createElement(Stack2, { spacing: 1, direction: "row", alignItems: "center" }, startTagAdornment, /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: "inherit", sx: { mr: 1 } })),
482
- label: /* @__PURE__ */ React3.createElement(Box3, { sx: { display: "inline-grid" } }, /* @__PURE__ */ React3.createElement(Typography, { sx: { textOverflow: "ellipsis", overflowX: "hidden" }, variant: "subtitle2" }, label)),
483
- actions: /* @__PURE__ */ React3.createElement(IconButton, { size: SIZE2, onClick: unlinkVariable, "aria-label": __2("Unlink", "elementor") }, /* @__PURE__ */ React3.createElement(DetachIcon, { fontSize: SIZE2 }))
774
+ value: label,
775
+ onChange: (e) => setLabel(e.target.value)
776
+ }
777
+ ))), /* @__PURE__ */ React8.createElement(Grid3, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React8.createElement(FormLabel3, { size: "small" }, __7("Value", "elementor"))), /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
778
+ UnstableTag,
779
+ {
780
+ variant: "outlined",
781
+ label: fontFamily,
782
+ endIcon: /* @__PURE__ */ React8.createElement(ChevronDownIcon, { fontSize: "tiny" }),
783
+ ...bindTrigger(fontPopoverState),
784
+ fullWidth: true
484
785
  }
485
- ), /* @__PURE__ */ React3.createElement(
786
+ ), /* @__PURE__ */ React8.createElement(
787
+ Popover,
788
+ {
789
+ disablePortal: true,
790
+ disableScrollLock: true,
791
+ anchorEl: anchorRef.current,
792
+ anchorOrigin: { vertical: "top", horizontal: "right" },
793
+ transformOrigin: { vertical: "top", horizontal: -20 },
794
+ ...bindPopover(fontPopoverState)
795
+ },
796
+ /* @__PURE__ */ React8.createElement(
797
+ FontFamilySelector,
798
+ {
799
+ fontFamilies,
800
+ fontFamily,
801
+ onFontFamilyChange: setFontFamily,
802
+ onClose: fontPopoverState.close
803
+ }
804
+ )
805
+ ))))), /* @__PURE__ */ React8.createElement(CardActions3, null, /* @__PURE__ */ React8.createElement(Button4, { size: "small", variant: "contained", disabled: isFormInvalid(), onClick: handleCreate }, __7("Create", "elementor"))));
806
+ };
807
+
808
+ // src/components/font-variable-edit.tsx
809
+ import * as React9 from "react";
810
+ import { useId, useRef as useRef4, useState as useState5 } from "react";
811
+ import { FontFamilySelector as FontFamilySelector2 } from "@elementor/editor-controls";
812
+ import { useFontFamilies as useFontFamilies2 } from "@elementor/editor-editing-panel";
813
+ import { PopoverHeader as PopoverHeader5 } from "@elementor/editor-ui";
814
+ import { ArrowLeftIcon as ArrowLeftIcon4, ChevronDownIcon as ChevronDownIcon2, TextIcon as TextIcon2 } from "@elementor/icons";
815
+ import {
816
+ bindPopover as bindPopover2,
817
+ bindTrigger as bindTrigger2,
818
+ Button as Button5,
819
+ CardActions as CardActions4,
820
+ Divider as Divider5,
821
+ FormLabel as FormLabel4,
822
+ Grid as Grid4,
823
+ IconButton as IconButton6,
824
+ Popover as Popover2,
825
+ Stack as Stack6,
826
+ TextField as TextField4,
827
+ UnstableTag as UnstableTag2,
828
+ usePopupState as usePopupState2
829
+ } from "@elementor/ui";
830
+ import { __ as __8 } from "@wordpress/i18n";
831
+ var SIZE6 = "tiny";
832
+ var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
833
+ const variable = useVariable(editId);
834
+ if (!variable) {
835
+ throw new Error(`Global font variable "${editId}" not found`);
836
+ }
837
+ const [fontFamily, setFontFamily] = useState5(variable.value);
838
+ const [label, setLabel] = useState5(variable.label);
839
+ const variableNameId = useId();
840
+ const variableValueId = useId();
841
+ const anchorRef = useRef4(null);
842
+ const fontPopoverState = usePopupState2({ variant: "popover" });
843
+ const fontFamilies = useFontFamilies2();
844
+ const handleUpdate = () => {
845
+ updateVariable(editId, {
846
+ value: fontFamily,
847
+ label
848
+ }).then(() => {
849
+ onSubmit?.();
850
+ });
851
+ };
852
+ const noValueChanged = () => fontFamily === variable.value && label === variable.label;
853
+ const hasEmptyValue = () => "" === fontFamily.trim() || "" === label.trim();
854
+ const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
855
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
856
+ PopoverHeader5,
857
+ {
858
+ 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(ArrowLeftIcon4, { fontSize: SIZE6 })), /* @__PURE__ */ React9.createElement(TextIcon2, { fontSize: SIZE6 })),
859
+ title: __8("Edit variable", "elementor"),
860
+ onClose
861
+ }
862
+ ), /* @__PURE__ */ React9.createElement(Divider5, null), /* @__PURE__ */ React9.createElement(Stack6, { p: 1.5, gap: 1.5 }, /* @__PURE__ */ React9.createElement(Grid4, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React9.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(FormLabel4, { htmlFor: variableNameId, size: "small" }, __8("Name", "elementor"))), /* @__PURE__ */ React9.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(
863
+ TextField4,
864
+ {
865
+ id: variableNameId,
866
+ size: "tiny",
867
+ fullWidth: true,
868
+ value: label,
869
+ onChange: (e) => setLabel(e.target.value)
870
+ }
871
+ ))), /* @__PURE__ */ React9.createElement(Grid4, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React9.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(FormLabel4, { htmlFor: variableValueId, size: "small" }, __8("Value", "elementor"))), /* @__PURE__ */ React9.createElement(Grid4, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
872
+ UnstableTag2,
873
+ {
874
+ id: variableValueId,
875
+ variant: "outlined",
876
+ label: fontFamily,
877
+ endIcon: /* @__PURE__ */ React9.createElement(ChevronDownIcon2, { fontSize: "tiny" }),
878
+ ...bindTrigger2(fontPopoverState),
879
+ fullWidth: true
880
+ }
881
+ ), /* @__PURE__ */ React9.createElement(
486
882
  Popover2,
487
883
  {
488
- ...bindPopover2(popupState),
884
+ disablePortal: true,
489
885
  disableScrollLock: true,
490
886
  anchorEl: anchorRef.current,
491
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
492
- transformOrigin: { vertical: "top", horizontal: "right" }
887
+ anchorOrigin: { vertical: "top", horizontal: "right" },
888
+ transformOrigin: { vertical: "top", horizontal: -20 },
889
+ ...bindPopover2(fontPopoverState)
493
890
  },
494
- /* @__PURE__ */ React3.createElement(
495
- PopoverHeader2,
891
+ /* @__PURE__ */ React9.createElement(
892
+ FontFamilySelector2,
496
893
  {
497
- title: __2("Variables", "elementor"),
498
- onClose: closePopover,
499
- icon: /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: SIZE2 }),
500
- actions: [
501
- /* @__PURE__ */ React3.createElement(
502
- IconButton,
503
- {
504
- key: "createVariable",
505
- ...bindTrigger(creationPopupState),
506
- size: SIZE2,
507
- onClick: handleCreateButtonClick
508
- },
509
- /* @__PURE__ */ React3.createElement(PlusIcon, { fontSize: SIZE2 })
510
- )
511
- ]
894
+ fontFamilies,
895
+ fontFamily,
896
+ onFontFamilyChange: setFontFamily,
897
+ onClose: fontPopoverState.close
512
898
  }
513
- ),
514
- children?.({ closePopover })
515
- ), colorCreationEnabled && /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
899
+ )
900
+ ))))), /* @__PURE__ */ React9.createElement(CardActions4, null, /* @__PURE__ */ React9.createElement(Button5, { size: "small", variant: "contained", disabled: isSaveDisabled(), onClick: handleUpdate }, __8("Save", "elementor"))));
901
+ };
902
+
903
+ // src/components/font-variables-selection.tsx
904
+ import * as React10 from "react";
905
+ import { useState as useState6 } from "react";
906
+ import { useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
907
+ import { PopoverHeader as PopoverHeader6, PopoverMenuList as PopoverMenuList2, PopoverSearch as PopoverSearch2 } from "@elementor/editor-ui";
908
+ import { ColorFilterIcon as ColorFilterIcon3, PlusIcon as PlusIcon2, SettingsIcon as SettingsIcon2, TextIcon as TextIcon3 } from "@elementor/icons";
909
+ import { Divider as Divider6, IconButton as IconButton7 } from "@elementor/ui";
910
+ import { __ as __9 } from "@wordpress/i18n";
911
+ var SIZE7 = "tiny";
912
+ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
913
+ const { value: variable, setValue: setVariable } = useBoundProp4(fontVariablePropTypeUtil);
914
+ const [searchValue, setSearchValue] = useState6("");
915
+ const {
916
+ list: variables,
917
+ hasMatches: hasSearchResults,
918
+ isSourceNotEmpty: hasVariables
919
+ } = useFilteredVariables(searchValue, fontVariablePropTypeUtil.key);
920
+ const handleSetVariable = (key) => {
921
+ setVariable(key);
922
+ closePopover();
923
+ };
924
+ const actions = [];
925
+ if (onAdd) {
926
+ actions.push(
927
+ /* @__PURE__ */ React10.createElement(IconButton7, { key: "add", size: SIZE7, onClick: onAdd }, /* @__PURE__ */ React10.createElement(PlusIcon2, { fontSize: SIZE7 }))
928
+ );
929
+ }
930
+ if (onSettings) {
931
+ actions.push(
932
+ /* @__PURE__ */ React10.createElement(IconButton7, { key: "settings", size: SIZE7, onClick: onSettings }, /* @__PURE__ */ React10.createElement(SettingsIcon2, { fontSize: SIZE7 }))
933
+ );
934
+ }
935
+ const items = variables.map(({ value, label, key }) => ({
936
+ type: "item",
937
+ value: key,
938
+ label,
939
+ icon: /* @__PURE__ */ React10.createElement(TextIcon3, null),
940
+ secondaryText: value,
941
+ onEdit: () => onEdit?.(key)
942
+ }));
943
+ const handleSearch = (search) => {
944
+ setSearchValue(search);
945
+ };
946
+ const handleClearSearch = () => {
947
+ setSearchValue("");
948
+ };
949
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
950
+ PopoverHeader6,
951
+ {
952
+ title: __9("Variables", "elementor"),
953
+ onClose: closePopover,
954
+ icon: /* @__PURE__ */ React10.createElement(ColorFilterIcon3, { fontSize: SIZE7 }),
955
+ actions
956
+ }
957
+ ), hasVariables && /* @__PURE__ */ React10.createElement(
958
+ PopoverSearch2,
959
+ {
960
+ value: searchValue,
961
+ onSearch: handleSearch,
962
+ placeholder: __9("Search", "elementor")
963
+ }
964
+ ), /* @__PURE__ */ React10.createElement(Divider6, null), hasVariables && hasSearchResults && /* @__PURE__ */ React10.createElement(
965
+ PopoverMenuList2,
966
+ {
967
+ items,
968
+ onSelect: handleSetVariable,
969
+ onClose: () => {
970
+ },
971
+ selectedValue: variable,
972
+ "data-testid": "font-variables-list",
973
+ menuListTemplate: VariablesStyledMenuList,
974
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React10.createElement(MenuItemContent, { item })
975
+ }
976
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React10.createElement(NoSearchResults, { searchValue, onClear: handleClearSearch }), !hasVariables && /* @__PURE__ */ React10.createElement(NoVariables, { icon: /* @__PURE__ */ React10.createElement(TextIcon3, { fontSize: "large" }), onAdd }));
516
977
  };
517
978
 
518
- // src/controls/color-variables-selection-control.tsx
519
- var ColorVariablesSelectionControl = () => {
520
- const { setValue } = useBoundProp3();
521
- const { value: variableValue } = useBoundProp3(colorVariablePropTypeUtil);
979
+ // src/components/variable-selection-popover.tsx
980
+ var VIEW_LIST = "list";
981
+ var VIEW_ADD = "add";
982
+ var VIEW_EDIT = "edit";
983
+ var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
984
+ const [currentView, setCurrentView] = useState7(VIEW_LIST);
985
+ const editIdRef = useRef5("");
986
+ return renderStage({
987
+ propTypeKey,
988
+ currentView,
989
+ selectedVariable,
990
+ editIdRef,
991
+ setCurrentView,
992
+ closePopover
993
+ });
994
+ };
995
+ function renderStage(props) {
996
+ const handleSubmitOnEdit = () => {
997
+ if (props?.selectedVariable?.key === props.editIdRef.current) {
998
+ props.closePopover();
999
+ } else {
1000
+ props.setCurrentView(VIEW_LIST);
1001
+ }
1002
+ };
1003
+ if (fontVariablePropTypeUtil.key === props.propTypeKey) {
1004
+ if (VIEW_LIST === props.currentView) {
1005
+ return /* @__PURE__ */ React11.createElement(
1006
+ FontVariablesSelection,
1007
+ {
1008
+ closePopover: props.closePopover,
1009
+ onAdd: () => {
1010
+ props.setCurrentView(VIEW_ADD);
1011
+ },
1012
+ onEdit: (key) => {
1013
+ props.editIdRef.current = key;
1014
+ props.setCurrentView(VIEW_EDIT);
1015
+ }
1016
+ }
1017
+ );
1018
+ }
1019
+ if (VIEW_ADD === props.currentView) {
1020
+ return /* @__PURE__ */ React11.createElement(
1021
+ FontVariableCreation,
1022
+ {
1023
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1024
+ onClose: props.closePopover
1025
+ }
1026
+ );
1027
+ }
1028
+ if (VIEW_EDIT === props.currentView) {
1029
+ return /* @__PURE__ */ React11.createElement(
1030
+ FontVariableEdit,
1031
+ {
1032
+ editId: props.editIdRef.current ?? "",
1033
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1034
+ onClose: props.closePopover,
1035
+ onSubmit: handleSubmitOnEdit
1036
+ }
1037
+ );
1038
+ }
1039
+ }
1040
+ if (colorVariablePropTypeUtil.key === props.propTypeKey) {
1041
+ if (VIEW_LIST === props.currentView) {
1042
+ return /* @__PURE__ */ React11.createElement(
1043
+ ColorVariablesSelection,
1044
+ {
1045
+ closePopover: props.closePopover,
1046
+ onAdd: () => {
1047
+ props.setCurrentView(VIEW_ADD);
1048
+ },
1049
+ onEdit: (key) => {
1050
+ props.editIdRef.current = key;
1051
+ props.setCurrentView(VIEW_EDIT);
1052
+ }
1053
+ }
1054
+ );
1055
+ }
1056
+ if (VIEW_ADD === props.currentView) {
1057
+ return /* @__PURE__ */ React11.createElement(
1058
+ ColorVariableCreation,
1059
+ {
1060
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1061
+ onClose: props.closePopover
1062
+ }
1063
+ );
1064
+ }
1065
+ if (VIEW_EDIT === props.currentView) {
1066
+ return /* @__PURE__ */ React11.createElement(
1067
+ ColorVariableEdit,
1068
+ {
1069
+ editId: props.editIdRef.current ?? "",
1070
+ onGoBack: () => props.setCurrentView(VIEW_LIST),
1071
+ onClose: props.closePopover,
1072
+ onSubmit: handleSubmitOnEdit
1073
+ }
1074
+ );
1075
+ }
1076
+ }
1077
+ return null;
1078
+ }
1079
+
1080
+ // src/controls/color-variable-control.tsx
1081
+ var SIZE8 = "tiny";
1082
+ var ColorVariableControl = () => {
1083
+ const { setValue: setColor } = useBoundProp5();
1084
+ const { value: variableValue } = useBoundProp5(colorVariablePropTypeUtil);
1085
+ const anchorRef = useRef6(null);
1086
+ const popupId = useId2();
1087
+ const popupState = usePopupState3({
1088
+ variant: "popover",
1089
+ popupId: `elementor-variables-list-${popupId}`
1090
+ });
522
1091
  const selectedVariable = useVariable(variableValue);
523
1092
  if (!selectedVariable) {
524
1093
  throw new Error(`Global color variable ${variableValue} not found`);
525
1094
  }
526
1095
  const unlinkVariable = () => {
527
- setValue(colorPropTypeUtil.create(selectedVariable.value));
1096
+ setColor(colorPropTypeUtil.create(selectedVariable.value));
528
1097
  };
529
- return /* @__PURE__ */ React4.createElement(
530
- VariablesSelectionPopover,
1098
+ return /* @__PURE__ */ React12.createElement(Box, { ref: anchorRef }, /* @__PURE__ */ React12.createElement(
1099
+ Tag,
1100
+ {
1101
+ fullWidth: true,
1102
+ showActionsOnHover: true,
1103
+ startIcon: /* @__PURE__ */ React12.createElement(Stack7, { spacing: 0.75, direction: "row", alignItems: "center" }, /* @__PURE__ */ React12.createElement(ColorIndicator, { size: "inherit", value: selectedVariable.value, component: "span" }), /* @__PURE__ */ React12.createElement(ColorFilterIcon4, { fontSize: "inherit", sx: { mr: 1 } })),
1104
+ label: /* @__PURE__ */ React12.createElement(Box, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React12.createElement(
1105
+ Typography3,
1106
+ {
1107
+ sx: { textOverflow: "ellipsis", overflowX: "hidden", lineHeight: 1 },
1108
+ variant: "caption"
1109
+ },
1110
+ selectedVariable.label
1111
+ )),
1112
+ actions: /* @__PURE__ */ React12.createElement(IconButton8, { size: SIZE8, onClick: unlinkVariable, "aria-label": __10("Unlink", "elementor") }, /* @__PURE__ */ React12.createElement(DetachIcon, { fontSize: SIZE8 })),
1113
+ ...bindTrigger3(popupState)
1114
+ }
1115
+ ), /* @__PURE__ */ React12.createElement(
1116
+ Popover3,
531
1117
  {
532
- selectedVariable,
533
- unlinkVariable,
534
- startTagAdornment: /* @__PURE__ */ React4.createElement(ColorIndicator, { size: "inherit", component: "span", value: selectedVariable.value })
1118
+ disableScrollLock: true,
1119
+ anchorEl: anchorRef.current,
1120
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
1121
+ transformOrigin: { vertical: "top", horizontal: "right" },
1122
+ ...bindPopover3(popupState)
535
1123
  },
536
- ({ closePopover }) => /* @__PURE__ */ React4.createElement(ColorVariablesSelection, { onSelect: closePopover })
537
- );
1124
+ /* @__PURE__ */ React12.createElement(
1125
+ VariableSelectionPopover,
1126
+ {
1127
+ selectedVariable,
1128
+ closePopover: popupState.close,
1129
+ propTypeKey: colorVariablePropTypeUtil.key
1130
+ }
1131
+ )
1132
+ ));
538
1133
  };
539
1134
 
540
1135
  // src/hooks/use-prop-color-variable-action.tsx
541
- import * as React5 from "react";
542
- import { useBoundProp as useBoundProp4 } from "@elementor/editor-editing-panel";
543
- import { ColorFilterIcon as ColorFilterIcon2 } from "@elementor/icons";
544
- import { __ as __3 } from "@wordpress/i18n";
545
-
546
- // src/prop-types/font-variable-prop-type.ts
547
- import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
548
- import { z as z2 } from "@elementor/schema";
549
- var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
1136
+ import * as React13 from "react";
1137
+ import { useBoundProp as useBoundProp6 } from "@elementor/editor-editing-panel";
1138
+ import { ColorFilterIcon as ColorFilterIcon5 } from "@elementor/icons";
1139
+ import { __ as __11 } from "@wordpress/i18n";
550
1140
 
551
1141
  // src/utils.ts
552
1142
  var hasAssignedColorVariable = (propValue) => {
@@ -564,13 +1154,15 @@ var supportsFontVariables = (propType) => {
564
1154
 
565
1155
  // src/hooks/use-prop-color-variable-action.tsx
566
1156
  var usePropColorVariableAction = () => {
567
- const { propType } = useBoundProp4();
1157
+ const { propType } = useBoundProp6();
568
1158
  const visible = !!propType && supportsColorVariables(propType);
569
1159
  return {
570
1160
  visible,
571
- icon: ColorFilterIcon2,
572
- title: __3("Variables", "elementor"),
573
- popoverContent: ({ closePopover }) => /* @__PURE__ */ React5.createElement(ColorVariablesSelection, { onSelect: closePopover })
1161
+ icon: ColorFilterIcon5,
1162
+ title: __11("Variables", "elementor"),
1163
+ content: ({ close: closePopover }) => {
1164
+ return /* @__PURE__ */ React13.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1165
+ }
574
1166
  };
575
1167
  };
576
1168
 
@@ -585,81 +1177,85 @@ var variableTransformer = createTransformer((value) => {
585
1177
 
586
1178
  // src/init-color-variables.ts
587
1179
  var { registerPopoverAction } = controlActionsMenu;
588
- function initColorVariables() {
1180
+ var conditions = {
1181
+ backgroundOverlay: ({ value: prop }) => {
1182
+ return hasAssignedColorVariable(backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
1183
+ },
1184
+ boxShadow: ({ value: prop }) => {
1185
+ return hasAssignedColorVariable(shadowPropTypeUtil.extract(prop)?.color);
1186
+ }
1187
+ };
1188
+ function registerControlsAndActions() {
589
1189
  registerControlReplacement({
590
- component: ColorVariablesSelectionControl,
1190
+ component: ColorVariableControl,
591
1191
  condition: ({ value }) => hasAssignedColorVariable(value)
592
1192
  });
593
1193
  registerPopoverAction({
594
1194
  id: "color-variables",
595
1195
  useProps: usePropColorVariableAction
596
1196
  });
1197
+ }
1198
+ function registerRepeaterItemIcons() {
1199
+ injectIntoRepeaterItemIcon({
1200
+ id: "color-variables-background-icon",
1201
+ component: BackgroundRepeaterColorIndicator,
1202
+ condition: conditions.backgroundOverlay
1203
+ });
1204
+ injectIntoRepeaterItemIcon({
1205
+ id: "color-variables-icon",
1206
+ component: BoxShadowRepeaterColorIndicator,
1207
+ condition: conditions.boxShadow
1208
+ });
1209
+ }
1210
+ function registerRepeaterItemLabels() {
1211
+ injectIntoRepeaterItemLabel({
1212
+ id: "color-variables-label",
1213
+ component: BackgroundRepeaterLabel,
1214
+ condition: conditions.backgroundOverlay
1215
+ });
1216
+ }
1217
+ function registerStyleTransformers() {
597
1218
  styleTransformersRegistry.register(colorVariablePropTypeUtil.key, variableTransformer);
598
1219
  }
1220
+ function initColorVariables() {
1221
+ registerControlsAndActions();
1222
+ registerRepeaterItemIcons();
1223
+ registerRepeaterItemLabels();
1224
+ registerStyleTransformers();
1225
+ }
599
1226
 
600
1227
  // src/init-font-variables.ts
601
1228
  import { styleTransformersRegistry as styleTransformersRegistry2 } from "@elementor/editor-canvas";
602
1229
  import { controlActionsMenu as controlActionsMenu2, registerControlReplacement as registerControlReplacement2 } from "@elementor/editor-editing-panel";
603
1230
 
604
- // src/controls/font-variables-selection-control.tsx
605
- import * as React7 from "react";
606
- import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
1231
+ // src/controls/font-variable-control.tsx
1232
+ import * as React14 from "react";
1233
+ import { useId as useId3, useRef as useRef7 } from "react";
1234
+ import { useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
607
1235
  import { stringPropTypeUtil } from "@elementor/editor-props";
608
-
609
- // src/components/font-variables-selection.tsx
610
- import * as React6 from "react";
611
- import { Fragment as Fragment2 } from "react";
612
- import { useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
613
- import { EditIcon as EditIcon2, TextIcon } from "@elementor/icons";
614
- import { Box as Box4, Divider as Divider3, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, MenuList as MenuList2 } from "@elementor/ui";
615
- var FontVariablesSelection = ({ onSelect }) => {
616
- const { value: variable, setValue: setVariable } = useBoundProp5(fontVariablePropTypeUtil);
617
- const variables = usePropVariables(fontVariablePropTypeUtil.key);
618
- const handleSetVariable = (key) => {
619
- setVariable(key);
620
- onSelect?.();
621
- };
622
- return /* @__PURE__ */ React6.createElement(Fragment2, null, /* @__PURE__ */ React6.createElement(Divider3, null), /* @__PURE__ */ React6.createElement(Box4, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
623
- StyledMenuItem,
624
- {
625
- key,
626
- onClick: () => handleSetVariable(key),
627
- selected: key === variable
628
- },
629
- /* @__PURE__ */ React6.createElement(ListItemIcon2, null, /* @__PURE__ */ React6.createElement(TextIcon, null)),
630
- /* @__PURE__ */ React6.createElement(
631
- ListItemText2,
632
- {
633
- primary: label,
634
- secondary: value,
635
- primaryTypographyProps: {
636
- variant: "body2",
637
- color: "text.secondary",
638
- style: {
639
- lineHeight: 2,
640
- display: "inline-block",
641
- overflow: "hidden",
642
- textOverflow: "ellipsis",
643
- whiteSpace: "nowrap",
644
- maxWidth: "81px"
645
- }
646
- },
647
- secondaryTypographyProps: {
648
- variant: "caption",
649
- color: "text.tertiary",
650
- style: { marginTop: "1px", lineHeight: "1" }
651
- },
652
- sx: { display: "flex", alignItems: "center", gap: 1 }
653
- }
654
- ),
655
- /* @__PURE__ */ React6.createElement(EditIcon2, { color: "action", fontSize: "inherit", sx: { mx: 1, opacity: "0" } })
656
- )))));
657
- };
658
-
659
- // src/controls/font-variables-selection-control.tsx
660
- var FontVariablesSelectionControl = () => {
661
- const { setValue: setFontFamily } = useBoundProp6();
662
- const { value: variableValue } = useBoundProp6(fontVariablePropTypeUtil);
1236
+ import { ColorFilterIcon as ColorFilterIcon6, DetachIcon as DetachIcon2 } from "@elementor/icons";
1237
+ import {
1238
+ bindPopover as bindPopover4,
1239
+ bindTrigger as bindTrigger4,
1240
+ Box as Box2,
1241
+ IconButton as IconButton9,
1242
+ Popover as Popover4,
1243
+ Stack as Stack8,
1244
+ Typography as Typography4,
1245
+ UnstableTag as Tag2,
1246
+ usePopupState as usePopupState4
1247
+ } from "@elementor/ui";
1248
+ import { __ as __12 } from "@wordpress/i18n";
1249
+ var SIZE9 = "tiny";
1250
+ var FontVariableControl = () => {
1251
+ const { setValue: setFontFamily } = useBoundProp7();
1252
+ const { value: variableValue } = useBoundProp7(fontVariablePropTypeUtil);
1253
+ const anchorRef = useRef7(null);
1254
+ const popupId = useId3();
1255
+ const popupState = usePopupState4({
1256
+ variant: "popover",
1257
+ popupId: `elementor-variables-list-${popupId}`
1258
+ });
663
1259
  const selectedVariable = useVariable(variableValue);
664
1260
  if (!selectedVariable) {
665
1261
  throw new Error(`Global font variable ${variableValue} not found`);
@@ -667,22 +1263,58 @@ var FontVariablesSelectionControl = () => {
667
1263
  const unlinkVariable = () => {
668
1264
  setFontFamily(stringPropTypeUtil.create(selectedVariable.value));
669
1265
  };
670
- return /* @__PURE__ */ React7.createElement(VariablesSelectionPopover, { selectedVariable, unlinkVariable }, ({ closePopover }) => /* @__PURE__ */ React7.createElement(FontVariablesSelection, { onSelect: closePopover }));
1266
+ return /* @__PURE__ */ React14.createElement(Box2, { ref: anchorRef }, /* @__PURE__ */ React14.createElement(
1267
+ Tag2,
1268
+ {
1269
+ fullWidth: true,
1270
+ showActionsOnHover: true,
1271
+ startIcon: /* @__PURE__ */ React14.createElement(Stack8, { spacing: 0.75, direction: "row", alignItems: "center" }, /* @__PURE__ */ React14.createElement(ColorFilterIcon6, { fontSize: "inherit", sx: { mr: 1 } })),
1272
+ label: /* @__PURE__ */ React14.createElement(Box2, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React14.createElement(
1273
+ Typography4,
1274
+ {
1275
+ sx: { textOverflow: "ellipsis", overflowX: "hidden", lineHeight: 1 },
1276
+ variant: "caption"
1277
+ },
1278
+ selectedVariable.label
1279
+ )),
1280
+ actions: /* @__PURE__ */ React14.createElement(IconButton9, { size: SIZE9, onClick: unlinkVariable, "aria-label": __12("Unlink", "elementor") }, /* @__PURE__ */ React14.createElement(DetachIcon2, { fontSize: SIZE9 })),
1281
+ ...bindTrigger4(popupState)
1282
+ }
1283
+ ), /* @__PURE__ */ React14.createElement(
1284
+ Popover4,
1285
+ {
1286
+ disableScrollLock: true,
1287
+ anchorEl: anchorRef.current,
1288
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
1289
+ transformOrigin: { vertical: "top", horizontal: "right" },
1290
+ ...bindPopover4(popupState)
1291
+ },
1292
+ /* @__PURE__ */ React14.createElement(
1293
+ VariableSelectionPopover,
1294
+ {
1295
+ selectedVariable,
1296
+ closePopover: popupState.close,
1297
+ propTypeKey: fontVariablePropTypeUtil.key
1298
+ }
1299
+ )
1300
+ ));
671
1301
  };
672
1302
 
673
1303
  // src/hooks/use-prop-font-variable-action.tsx
674
- import * as React8 from "react";
675
- import { useBoundProp as useBoundProp7 } from "@elementor/editor-editing-panel";
676
- import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
677
- import { __ as __4 } from "@wordpress/i18n";
1304
+ import * as React15 from "react";
1305
+ import { useBoundProp as useBoundProp8 } from "@elementor/editor-editing-panel";
1306
+ import { ColorFilterIcon as ColorFilterIcon7 } from "@elementor/icons";
1307
+ import { __ as __13 } from "@wordpress/i18n";
678
1308
  var usePropFontVariableAction = () => {
679
- const { propType } = useBoundProp7();
1309
+ const { propType } = useBoundProp8();
680
1310
  const visible = !!propType && supportsFontVariables(propType);
681
1311
  return {
682
1312
  visible,
683
- icon: ColorFilterIcon3,
684
- title: __4("Variables", "elementor"),
685
- popoverContent: ({ closePopover }) => /* @__PURE__ */ React8.createElement(FontVariablesSelection, { onSelect: closePopover })
1313
+ icon: ColorFilterIcon7,
1314
+ title: __13("Variables", "elementor"),
1315
+ content: ({ close: closePopover }) => {
1316
+ return /* @__PURE__ */ React15.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1317
+ }
686
1318
  };
687
1319
  };
688
1320
 
@@ -690,7 +1322,7 @@ var usePropFontVariableAction = () => {
690
1322
  var { registerPopoverAction: registerPopoverAction2 } = controlActionsMenu2;
691
1323
  function initFontVariables() {
692
1324
  registerControlReplacement2({
693
- component: FontVariablesSelectionControl,
1325
+ component: FontVariableControl,
694
1326
  condition: ({ value }) => hasAssignedFontVariable(value)
695
1327
  });
696
1328
  registerPopoverAction2({
@@ -701,8 +1333,8 @@ function initFontVariables() {
701
1333
  }
702
1334
 
703
1335
  // src/renderers/style-variables-renderer.tsx
704
- import * as React9 from "react";
705
- import { useEffect, useState as useState2 } from "react";
1336
+ import * as React16 from "react";
1337
+ import { useEffect, useState as useState8 } from "react";
706
1338
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
707
1339
  import { Portal } from "@elementor/ui";
708
1340
 
@@ -723,13 +1355,13 @@ function StyleVariablesRenderer() {
723
1355
  }
724
1356
  const cssVariables = convertToCssVariables(styleVariables);
725
1357
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
726
- return /* @__PURE__ */ React9.createElement(Portal, { container }, /* @__PURE__ */ React9.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
1358
+ return /* @__PURE__ */ React16.createElement(Portal, { container }, /* @__PURE__ */ React16.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
727
1359
  }
728
1360
  function usePortalContainer() {
729
1361
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
730
1362
  }
731
1363
  function useStyleVariables() {
732
- const [variables, setVariables] = useState2({});
1364
+ const [variables, setVariables] = useState8({});
733
1365
  useEffect(() => {
734
1366
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
735
1367
  return () => {