@elementor/editor-variables 0.15.0 → 0.18.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 +88 -0
  2. package/dist/index.js +894 -486
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +892 -511
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +9 -9
  7. package/src/components/color-variable-creation.tsx +37 -58
  8. package/src/components/color-variable-edit.tsx +110 -86
  9. package/src/components/color-variables-selection.tsx +32 -34
  10. package/src/components/fields/color-field.tsx +54 -0
  11. package/src/components/fields/font-field.tsx +85 -0
  12. package/src/components/fields/label-field.tsx +54 -0
  13. package/src/components/font-variable-creation.tsx +39 -78
  14. package/src/components/font-variable-edit.tsx +108 -114
  15. package/src/components/font-variables-selection.tsx +32 -34
  16. package/src/components/ui/delete-confirmation-dialog.tsx +52 -0
  17. package/src/components/ui/deleted-variable-alert.tsx +47 -0
  18. package/src/components/ui/menu-item-content.tsx +2 -5
  19. package/src/components/ui/tags/assigned-tag.tsx +45 -0
  20. package/src/components/ui/tags/deleted-tag.tsx +37 -0
  21. package/src/components/ui/variable/assigned-variable.tsx +70 -0
  22. package/src/components/ui/variable/deleted-variable.tsx +76 -0
  23. package/src/controls/color-variable-control.tsx +21 -48
  24. package/src/controls/font-variable-control.tsx +20 -43
  25. package/src/create-style-variables-repository.ts +44 -5
  26. package/src/hooks/use-prop-variables.ts +6 -0
  27. package/src/init-color-variables.ts +3 -48
  28. package/src/renderers/style-variables-renderer.tsx +10 -4
  29. package/src/repeater-injections.ts +35 -0
  30. package/src/service.ts +23 -2
  31. package/src/sync/enqueue-font.ts +7 -0
  32. package/src/sync/types.ts +5 -0
  33. package/src/transformers/variable-transformer.ts +21 -3
  34. package/src/types.ts +1 -1
  35. package/src/utils/validations.ts +42 -0
  36. package/src/components/ui/variable-tag.tsx +0 -43
package/dist/index.mjs CHANGED
@@ -3,16 +3,58 @@ 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";
7
6
  import { controlActionsMenu, registerControlReplacement } from "@elementor/editor-editing-panel";
8
- import { backgroundColorOverlayPropTypeUtil, shadowPropTypeUtil } from "@elementor/editor-props";
9
7
 
10
- // src/components/variables-repeater-item-slot.tsx
11
- import * as React from "react";
8
+ // src/controls/color-variable-control.tsx
9
+ import * as React20 from "react";
10
+ import { useBoundProp as useBoundProp9 } from "@elementor/editor-controls";
11
+ import { colorPropTypeUtil } from "@elementor/editor-props";
12
+
13
+ // src/components/ui/color-indicator.tsx
14
+ import { styled, UnstableColorIndicator } from "@elementor/ui";
15
+ var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
16
+ borderRadius: `${theme.shape.borderRadius / 2}px`,
17
+ marginRight: theme.spacing(0.25)
18
+ }));
19
+
20
+ // src/components/ui/variable/assigned-variable.tsx
21
+ import { useId as useId2, useRef as useRef4 } from "react";
22
+ import * as React16 from "react";
23
+ import { useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
24
+ import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
25
+ import { bindPopover as bindPopover2, bindTrigger as bindTrigger2, Box as Box4, Popover as Popover2, usePopupState as usePopupState2 } from "@elementor/ui";
26
+
27
+ // src/components/variable-selection-popover.tsx
28
+ import * as React14 from "react";
29
+ import { useRef as useRef3, useState as useState10 } from "react";
30
+ import { Box as Box2 } from "@elementor/ui";
31
+
32
+ // src/prop-types/color-variable-prop-type.ts
33
+ import { createPropUtils } from "@elementor/editor-props";
34
+ import { z } from "@elementor/schema";
35
+ var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
36
+
37
+ // src/prop-types/font-variable-prop-type.ts
38
+ import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
39
+ import { z as z2 } from "@elementor/schema";
40
+ var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
41
+
42
+ // src/components/color-variable-creation.tsx
43
+ import * as React3 from "react";
44
+ import { useState as useState3 } from "react";
45
+ import { PopoverContent, useBoundProp } from "@elementor/editor-controls";
46
+ import { PopoverBody } from "@elementor/editor-editing-panel";
47
+ import { PopoverHeader } from "@elementor/editor-ui";
48
+ import { ArrowLeftIcon, BrushIcon } from "@elementor/icons";
49
+ import { Button, CardActions, Divider, FormHelperText as FormHelperText3, IconButton } from "@elementor/ui";
50
+ import { __ as __5 } from "@wordpress/i18n";
12
51
 
13
52
  // src/hooks/use-prop-variables.ts
14
53
  import { useMemo } from "react";
15
54
 
55
+ // src/service.ts
56
+ import { __ } from "@wordpress/i18n";
57
+
16
58
  // src/api.ts
17
59
  import { httpService } from "@elementor/http-client";
18
60
  var BASE_PATH = "elementor/v1/variables";
@@ -95,6 +137,12 @@ var Storage = class {
95
137
  }
96
138
  };
97
139
 
140
+ // src/sync/enqueue-font.ts
141
+ var enqueueFont = (fontFamily, context = "preview") => {
142
+ const extendedWindow = window;
143
+ return extendedWindow.elementor?.helpers?.enqueueFont?.(fontFamily, context) ?? null;
144
+ };
145
+
98
146
  // src/create-style-variables-repository.ts
99
147
  var createStyleVariablesRepository = () => {
100
148
  const variables = {};
@@ -111,19 +159,46 @@ var createStyleVariablesRepository = () => {
111
159
  subscription({ ...variables });
112
160
  }
113
161
  };
114
- const shouldUpdate = (key, newValue) => {
115
- return !(key in variables) || variables[key] !== newValue;
162
+ const shouldUpdate = (key, maybeUpdated) => {
163
+ if (!(key in variables)) {
164
+ return true;
165
+ }
166
+ if (variables[key].label !== maybeUpdated.label) {
167
+ return true;
168
+ }
169
+ if (variables[key].value !== maybeUpdated.value) {
170
+ return true;
171
+ }
172
+ if (!variables[key]?.deleted && maybeUpdated?.deleted) {
173
+ return true;
174
+ }
175
+ if (variables[key]?.deleted && !maybeUpdated?.deleted) {
176
+ return true;
177
+ }
178
+ return false;
116
179
  };
117
180
  const applyUpdates = (updatedVars) => {
118
181
  let hasChanges = false;
119
- for (const [key, { value }] of Object.entries(updatedVars)) {
120
- if (shouldUpdate(key, value)) {
121
- variables[key] = value;
182
+ for (const [key, variable] of Object.entries(updatedVars)) {
183
+ if (shouldUpdate(key, variable)) {
184
+ variables[key] = variable;
185
+ if (variable.type === fontVariablePropTypeUtil.key) {
186
+ fontEnqueue(variable.value);
187
+ }
122
188
  hasChanges = true;
123
189
  }
124
190
  }
125
191
  return hasChanges;
126
192
  };
193
+ const fontEnqueue = (value) => {
194
+ if (!value) {
195
+ return;
196
+ }
197
+ try {
198
+ enqueueFont(value);
199
+ } catch {
200
+ }
201
+ };
127
202
  const update = (updatedVars) => {
128
203
  if (applyUpdates(updatedVars)) {
129
204
  notify();
@@ -165,7 +240,8 @@ var service = {
165
240
  return apiClient.create(type, label, value).then((response) => {
166
241
  const { success, data: payload } = response.data;
167
242
  if (!success) {
168
- throw new Error("Unexpected response from server");
243
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
244
+ throw new Error(errorMessage);
169
245
  }
170
246
  return payload;
171
247
  }).then((data) => {
@@ -180,13 +256,17 @@ var service = {
180
256
  id: variableId,
181
257
  variable: createdVariable
182
258
  };
259
+ }).catch((error) => {
260
+ const message = getErrorMessage(error.response);
261
+ throw message ? new Error(message) : error;
183
262
  });
184
263
  },
185
264
  update: (id, { label, value }) => {
186
265
  return apiClient.update(id, label, value).then((response) => {
187
266
  const { success, data: payload } = response.data;
188
267
  if (!success) {
189
- throw new Error("Unexpected response from server");
268
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
269
+ throw new Error(errorMessage);
190
270
  }
191
271
  return payload;
192
272
  }).then((data) => {
@@ -201,6 +281,9 @@ var service = {
201
281
  id: variableId,
202
282
  variable: updatedVariable
203
283
  };
284
+ }).catch((error) => {
285
+ const message = getErrorMessage(error.response);
286
+ throw message ? new Error(message) : error;
204
287
  });
205
288
  },
206
289
  delete: (id) => {
@@ -252,6 +335,12 @@ var handleWatermark = (operation, newWatermark) => {
252
335
  }
253
336
  storage.watermark(newWatermark);
254
337
  };
338
+ var getErrorMessage = (response) => {
339
+ if (response?.data?.code === "duplicated_label") {
340
+ return __("This variable name already exists. Please choose a unique name.", "elementor");
341
+ }
342
+ return __("There was a glitch. Try saving your variable again.", "elementor");
343
+ };
255
344
 
256
345
  // src/hooks/use-prop-variables.ts
257
346
  var useVariable = (key) => {
@@ -302,100 +391,52 @@ var deleteVariable = (deleteId) => {
302
391
  return id;
303
392
  });
304
393
  };
394
+ var restoreVariable = (restoreId) => {
395
+ return service.restore(restoreId).then(({ id }) => {
396
+ return id;
397
+ });
398
+ };
305
399
 
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)
311
- }));
400
+ // src/components/fields/color-field.tsx
401
+ import * as React from "react";
402
+ import { useRef, useState } from "react";
403
+ import { FormHelperText, FormLabel, Grid, UnstableColorField } from "@elementor/ui";
404
+ import { __ as __3 } from "@wordpress/i18n";
312
405
 
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);
406
+ // src/utils/validations.ts
407
+ import { __ as __2 } from "@wordpress/i18n";
408
+ var VARIABLE_LABEL_MAX_LENGTH = 50;
409
+ var validateLabel = (name) => {
410
+ if (!name.trim()) {
411
+ return __2("Give your variable a name.", "elementor");
412
+ }
413
+ const allowedChars = /^[a-zA-Z0-9_-]+$/;
414
+ if (!allowedChars.test(name)) {
415
+ return __2("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor");
416
+ }
417
+ const hasAlphanumeric = /[a-zA-Z0-9]/;
418
+ if (!hasAlphanumeric.test(name)) {
419
+ return __2("Names have to include at least one non-special character.", "elementor");
420
+ }
421
+ if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
422
+ return __2("Keep names up to 50 characters.", "elementor");
423
+ }
424
+ return "";
325
425
  };
326
- var BoxShadowRepeaterColorIndicator = ({ value }) => {
327
- const colorVariable = useColorVariable(value);
328
- return /* @__PURE__ */ React.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
426
+ var labelHint = (name) => {
427
+ const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
428
+ if (hintThreshold < name.length) {
429
+ return __2("Keep names up to 50 characters.", "elementor");
430
+ }
431
+ return "";
329
432
  };
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
- );
433
+ var validateValue = (value) => {
434
+ if (!value.trim()) {
435
+ return __2("Add a value to complete your variable.", "elementor");
351
436
  }
352
- return /* @__PURE__ */ React2.createElement(
353
- Tag,
354
- {
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
- );
437
+ return "";
363
438
  };
364
439
 
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());
374
-
375
- // src/prop-types/font-variable-prop-type.ts
376
- import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
377
- import { z as z2 } from "@elementor/schema";
378
- var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
379
-
380
- // src/components/color-variable-creation.tsx
381
- import * as React3 from "react";
382
- import { useRef, useState } from "react";
383
- import { PopoverContent, useBoundProp } from "@elementor/editor-controls";
384
- import { PopoverScrollableContent } from "@elementor/editor-editing-panel";
385
- import { PopoverHeader } from "@elementor/editor-ui";
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
440
  // src/components/variable-selection-popover.context.ts
400
441
  import { createContext, useContext } from "react";
401
442
  var PopoverContentRefContext = createContext(null);
@@ -403,17 +444,80 @@ var usePopoverContentRef = () => {
403
444
  return useContext(PopoverContentRefContext);
404
445
  };
405
446
 
447
+ // src/components/fields/color-field.tsx
448
+ var ColorField = ({ value, onChange }) => {
449
+ const [color, setColor] = useState(value);
450
+ const [errorMessage, setErrorMessage] = useState("");
451
+ const defaultRef = useRef(null);
452
+ const anchorRef = usePopoverContentRef() ?? defaultRef;
453
+ const handleChange = (newValue) => {
454
+ setColor(newValue);
455
+ const errorMsg = validateValue(newValue);
456
+ setErrorMessage(errorMsg);
457
+ onChange(errorMsg ? "" : newValue);
458
+ };
459
+ return /* @__PURE__ */ React.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(FormLabel, { size: "tiny" }, __3("Value", "elementor"))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
460
+ UnstableColorField,
461
+ {
462
+ size: "tiny",
463
+ fullWidth: true,
464
+ value: color,
465
+ onChange: handleChange,
466
+ error: errorMessage ?? void 0,
467
+ slotProps: {
468
+ colorPicker: {
469
+ anchorEl: anchorRef.current,
470
+ anchorOrigin: { vertical: "top", horizontal: "right" },
471
+ transformOrigin: { vertical: "top", horizontal: -10 }
472
+ }
473
+ }
474
+ }
475
+ ), errorMessage && /* @__PURE__ */ React.createElement(FormHelperText, { error: true }, errorMessage)));
476
+ };
477
+
478
+ // src/components/fields/label-field.tsx
479
+ import * as React2 from "react";
480
+ import { useId, useState as useState2 } from "react";
481
+ import { FormHelperText as FormHelperText2, FormLabel as FormLabel2, Grid as Grid2, TextField } from "@elementor/ui";
482
+ import { __ as __4 } from "@wordpress/i18n";
483
+ var LabelField = ({ value, onChange }) => {
484
+ const [label, setLabel] = useState2(value);
485
+ const [errorMessage, setErrorMessage] = useState2("");
486
+ const [noticeMessage, setNoticeMessage] = useState2(() => labelHint(value));
487
+ const handleChange = (newValue) => {
488
+ setLabel(newValue);
489
+ const errorMsg = validateLabel(newValue);
490
+ const hintMsg = labelHint(newValue);
491
+ setErrorMessage(errorMsg);
492
+ setNoticeMessage(errorMsg ? "" : hintMsg);
493
+ onChange(errorMsg ? "" : newValue);
494
+ };
495
+ const id = useId();
496
+ return /* @__PURE__ */ React2.createElement(Grid2, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React2.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(FormLabel2, { htmlFor: id, size: "tiny" }, __4("Name", "elementor"))), /* @__PURE__ */ React2.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(
497
+ TextField,
498
+ {
499
+ id,
500
+ size: "tiny",
501
+ fullWidth: true,
502
+ value: label,
503
+ error: !!errorMessage,
504
+ onChange: (e) => handleChange(e.target.value),
505
+ inputProps: { maxLength: VARIABLE_LABEL_MAX_LENGTH }
506
+ }
507
+ ), errorMessage && /* @__PURE__ */ React2.createElement(FormHelperText2, { error: true }, errorMessage), noticeMessage && /* @__PURE__ */ React2.createElement(FormHelperText2, null, noticeMessage)));
508
+ };
509
+
406
510
  // src/components/color-variable-creation.tsx
407
- var SIZE2 = "tiny";
511
+ var SIZE = "tiny";
408
512
  var ColorVariableCreation = ({ onGoBack, onClose }) => {
409
513
  const { setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
410
- const [color, setColor] = useState("");
411
- const [label, setLabel] = useState("");
412
- const defaultRef = useRef(null);
413
- const anchorRef = usePopoverContentRef() ?? defaultRef;
514
+ const [color, setColor] = useState3("");
515
+ const [label, setLabel] = useState3("");
516
+ const [errorMessage, setErrorMessage] = useState3("");
414
517
  const resetFields = () => {
415
518
  setColor("");
416
519
  setLabel("");
520
+ setErrorMessage("");
417
521
  };
418
522
  const closePopover = () => {
419
523
  resetFields();
@@ -427,148 +531,201 @@ var ColorVariableCreation = ({ onGoBack, onClose }) => {
427
531
  }).then((key) => {
428
532
  setVariable(key);
429
533
  closePopover();
534
+ }).catch((error) => {
535
+ setErrorMessage(error.message);
430
536
  });
431
537
  };
432
- const isFormInvalid = () => {
433
- return !color?.trim() || !label?.trim();
538
+ const hasEmptyValue = () => {
539
+ return "" === color.trim() || "" === label.trim();
434
540
  };
435
- return /* @__PURE__ */ React3.createElement(PopoverScrollableContent, { height: "auto" }, /* @__PURE__ */ React3.createElement(
541
+ const isSubmitDisabled = hasEmptyValue();
542
+ return /* @__PURE__ */ React3.createElement(PopoverBody, { height: "auto" }, /* @__PURE__ */ React3.createElement(
436
543
  PopoverHeader,
437
544
  {
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"),
545
+ icon: /* @__PURE__ */ React3.createElement(React3.Fragment, null, onGoBack && /* @__PURE__ */ React3.createElement(IconButton, { size: SIZE, "aria-label": __5("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React3.createElement(ArrowLeftIcon, { fontSize: SIZE })), /* @__PURE__ */ React3.createElement(BrushIcon, { fontSize: SIZE })),
546
+ title: __5("Create variable", "elementor"),
440
547
  onClose: closePopover
441
548
  }
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(
443
- TextField,
549
+ ), /* @__PURE__ */ React3.createElement(Divider, null), /* @__PURE__ */ React3.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React3.createElement(
550
+ LabelField,
444
551
  {
445
- size: "tiny",
446
- fullWidth: true,
447
552
  value: label,
448
- onChange: (e) => setLabel(e.target.value)
553
+ onChange: (value) => {
554
+ setLabel(value);
555
+ setErrorMessage("");
556
+ }
449
557
  }
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(
451
- UnstableColorField,
558
+ ), /* @__PURE__ */ React3.createElement(
559
+ ColorField,
452
560
  {
453
- size: "tiny",
454
- fullWidth: true,
455
561
  value: color,
456
- onChange: setColor,
457
- slotProps: {
458
- colorPicker: {
459
- anchorEl: anchorRef.current,
460
- anchorOrigin: { vertical: "top", horizontal: "right" },
461
- transformOrigin: { vertical: "top", horizontal: -10 }
462
- }
562
+ onChange: (value) => {
563
+ setColor(value);
564
+ setErrorMessage("");
463
565
  }
464
566
  }
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"))));
567
+ ), errorMessage && /* @__PURE__ */ React3.createElement(FormHelperText3, { error: true }, errorMessage)), /* @__PURE__ */ React3.createElement(CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React3.createElement(Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreate }, __5("Create", "elementor"))));
466
568
  };
467
569
 
468
570
  // src/components/color-variable-edit.tsx
469
- import * as React4 from "react";
470
- import { useRef as useRef2, useState as useState2 } from "react";
471
- import { PopoverContent as PopoverContent2 } from "@elementor/editor-controls";
472
- import { PopoverHeader as PopoverHeader2, PopoverScrollableContent as PopoverScrollableContent2 } from "@elementor/editor-ui";
571
+ import * as React5 from "react";
572
+ import { useState as useState4 } from "react";
573
+ import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
574
+ import { PopoverBody as PopoverBody2 } from "@elementor/editor-editing-panel";
575
+ import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
473
576
  import { ArrowLeftIcon as ArrowLeftIcon2, BrushIcon as BrushIcon2, TrashIcon } from "@elementor/icons";
577
+ import { Button as Button3, CardActions as CardActions2, Divider as Divider2, FormHelperText as FormHelperText4, IconButton as IconButton2 } from "@elementor/ui";
578
+ import { __ as __7 } from "@wordpress/i18n";
579
+
580
+ // src/components/ui/delete-confirmation-dialog.tsx
581
+ import * as React4 from "react";
582
+ import { AlertOctagonFilledIcon } from "@elementor/icons";
474
583
  import {
475
584
  Button as Button2,
476
- CardActions as CardActions2,
477
- Divider as Divider2,
478
- FormLabel as FormLabel2,
479
- Grid as Grid2,
480
- IconButton as IconButton3,
481
- TextField as TextField2,
482
- UnstableColorField as UnstableColorField2
585
+ Dialog,
586
+ DialogActions,
587
+ DialogContent,
588
+ DialogContentText,
589
+ DialogTitle,
590
+ Typography
483
591
  } from "@elementor/ui";
484
- import { __ as __3 } from "@wordpress/i18n";
485
- var SIZE3 = "tiny";
592
+ import { __ as __6 } from "@wordpress/i18n";
593
+ var TITLE_ID = "delete-variable-dialog";
594
+ var DeleteConfirmationDialog = ({
595
+ open,
596
+ label,
597
+ closeDialog,
598
+ onConfirm
599
+ }) => {
600
+ return /* @__PURE__ */ React4.createElement(Dialog, { open, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React4.createElement(DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React4.createElement(AlertOctagonFilledIcon, { color: "error" }), __6("Delete this variable?", "elementor")), /* @__PURE__ */ React4.createElement(DialogContent, null, /* @__PURE__ */ React4.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __6("All elements using", "elementor"), /* @__PURE__ */ React4.createElement(Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), __6("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ React4.createElement(DialogActions, null, /* @__PURE__ */ React4.createElement(Button2, { color: "secondary", onClick: closeDialog }, __6("Not now", "elementor")), /* @__PURE__ */ React4.createElement(Button2, { variant: "contained", color: "error", onClick: onConfirm }, __6("Delete", "elementor"))));
601
+ };
602
+
603
+ // src/components/color-variable-edit.tsx
604
+ var SIZE2 = "tiny";
486
605
  var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
606
+ const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp2(colorVariablePropTypeUtil);
607
+ const [deleteConfirmation, setDeleteConfirmation] = useState4(false);
608
+ const [errorMessage, setErrorMessage] = useState4("");
487
609
  const variable = useVariable(editId);
488
610
  if (!variable) {
489
611
  throw new Error(`Global color variable not found`);
490
612
  }
491
- const defaultRef = useRef2(null);
492
- const anchorRef = usePopoverContentRef() ?? defaultRef;
493
- const [color, setColor] = useState2(variable.value);
494
- const [label, setLabel] = useState2(variable.label);
613
+ const [color, setColor] = useState4(variable.value);
614
+ const [label, setLabel] = useState4(variable.label);
495
615
  const handleUpdate = () => {
496
616
  updateVariable(editId, {
497
617
  value: color,
498
618
  label
499
619
  }).then(() => {
620
+ maybeTriggerBoundPropChange();
500
621
  onSubmit?.();
622
+ }).catch((error) => {
623
+ setErrorMessage(error.message);
501
624
  });
502
625
  };
503
626
  const handleDelete = () => {
504
627
  deleteVariable(editId).then(() => {
628
+ maybeTriggerBoundPropChange();
505
629
  onSubmit?.();
506
630
  });
507
631
  };
508
- const noValueChanged = () => color === variable.value && label === variable.label;
509
- const hasEmptyValue = () => "" === color.trim() || "" === label.trim();
510
- const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
632
+ const maybeTriggerBoundPropChange = () => {
633
+ if (editId === assignedValue) {
634
+ notifyBoundPropChange(editId);
635
+ }
636
+ };
637
+ const handleDeleteConfirmation = () => {
638
+ setDeleteConfirmation(true);
639
+ };
640
+ const closeDeleteDialog = () => () => {
641
+ setDeleteConfirmation(false);
642
+ };
511
643
  const actions = [];
512
644
  actions.push(
513
- /* @__PURE__ */ React4.createElement(IconButton3, { key: "delete", size: SIZE3, "aria-label": __3("Delete", "elementor"), onClick: handleDelete }, /* @__PURE__ */ React4.createElement(TrashIcon, { fontSize: SIZE3 }))
645
+ /* @__PURE__ */ React5.createElement(
646
+ IconButton2,
647
+ {
648
+ key: "delete",
649
+ size: SIZE2,
650
+ "aria-label": __7("Delete", "elementor"),
651
+ onClick: handleDeleteConfirmation
652
+ },
653
+ /* @__PURE__ */ React5.createElement(TrashIcon, { fontSize: SIZE2 })
654
+ )
514
655
  );
515
- return /* @__PURE__ */ React4.createElement(PopoverScrollableContent2, { height: "auto" }, /* @__PURE__ */ React4.createElement(
656
+ const hasEmptyValues = () => {
657
+ return !color.trim() || !label.trim();
658
+ };
659
+ const noValueChanged = () => {
660
+ return color === variable.value && label === variable.label;
661
+ };
662
+ const isSubmitDisabled = noValueChanged() || hasEmptyValues();
663
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(PopoverBody2, { height: "auto" }, /* @__PURE__ */ React5.createElement(
516
664
  PopoverHeader2,
517
665
  {
518
- title: __3("Edit variable", "elementor"),
666
+ title: __7("Edit variable", "elementor"),
519
667
  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 })),
668
+ icon: /* @__PURE__ */ React5.createElement(React5.Fragment, null, onGoBack && /* @__PURE__ */ React5.createElement(
669
+ IconButton2,
670
+ {
671
+ size: SIZE2,
672
+ "aria-label": __7("Go Back", "elementor"),
673
+ onClick: onGoBack
674
+ },
675
+ /* @__PURE__ */ React5.createElement(ArrowLeftIcon2, { fontSize: SIZE2 })
676
+ ), /* @__PURE__ */ React5.createElement(BrushIcon2, { fontSize: SIZE2 })),
521
677
  actions
522
678
  }
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,
679
+ ), /* @__PURE__ */ React5.createElement(Divider2, null), /* @__PURE__ */ React5.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React5.createElement(
680
+ LabelField,
525
681
  {
526
- size: "tiny",
527
- fullWidth: true,
528
682
  value: label,
529
- onChange: (e) => setLabel(e.target.value)
683
+ onChange: (value) => {
684
+ setLabel(value);
685
+ setErrorMessage("");
686
+ }
530
687
  }
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,
688
+ ), /* @__PURE__ */ React5.createElement(
689
+ ColorField,
533
690
  {
534
- size: "tiny",
535
- fullWidth: true,
536
691
  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
- }
692
+ onChange: (value) => {
693
+ setColor(value);
694
+ setErrorMessage("");
544
695
  }
545
696
  }
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"))));
697
+ ), errorMessage && /* @__PURE__ */ React5.createElement(FormHelperText4, { error: true }, errorMessage)), /* @__PURE__ */ React5.createElement(CardActions2, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React5.createElement(Button3, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __7("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React5.createElement(
698
+ DeleteConfirmationDialog,
699
+ {
700
+ open: true,
701
+ label,
702
+ onConfirm: handleDelete,
703
+ closeDialog: closeDeleteDialog()
704
+ }
705
+ ));
547
706
  };
548
707
 
549
708
  // 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";
709
+ import * as React9 from "react";
710
+ import { useState as useState5 } from "react";
711
+ import { useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
712
+ import { PopoverBody as PopoverBody3 } from "@elementor/editor-editing-panel";
554
713
  import { PopoverHeader as PopoverHeader3, PopoverMenuList, PopoverSearch } from "@elementor/editor-ui";
555
714
  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";
715
+ import { Divider as Divider3, IconButton as IconButton4 } from "@elementor/ui";
716
+ import { __ as __11 } from "@wordpress/i18n";
558
717
 
559
718
  // src/components/ui/menu-item-content.tsx
560
- import * as React5 from "react";
719
+ import * as React6 from "react";
561
720
  import { EllipsisWithTooltip } from "@elementor/editor-ui";
562
- import { isExperimentActive } from "@elementor/editor-v1-adapters";
563
721
  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");
722
+ import { Box, IconButton as IconButton3, ListItemIcon, Typography as Typography2 } from "@elementor/ui";
723
+ import { __ as __8 } from "@wordpress/i18n";
724
+ var SIZE3 = "tiny";
568
725
  var MenuItemContent = ({ item }) => {
569
726
  const onEdit = item.onEdit;
570
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React5.createElement(
571
- Box2,
727
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React6.createElement(
728
+ Box,
572
729
  {
573
730
  sx: {
574
731
  flex: 1,
@@ -578,18 +735,18 @@ var MenuItemContent = ({ item }) => {
578
735
  gap: 1
579
736
  }
580
737
  },
581
- /* @__PURE__ */ React5.createElement(
738
+ /* @__PURE__ */ React6.createElement(
582
739
  EllipsisWithTooltip,
583
740
  {
584
741
  title: item.label || item.value,
585
742
  as: Typography2,
586
- variant: isVersion330Active ? "caption" : "body2",
587
- color: isVersion330Active ? "text.primary" : "text.secondary",
743
+ variant: "caption",
744
+ color: "text.primary",
588
745
  sx: { marginTop: "1px", lineHeight: "2" },
589
746
  maxWidth: "50%"
590
747
  }
591
748
  ),
592
- item.secondaryText && /* @__PURE__ */ React5.createElement(
749
+ item.secondaryText && /* @__PURE__ */ React6.createElement(
593
750
  EllipsisWithTooltip,
594
751
  {
595
752
  title: item.secondaryText,
@@ -600,27 +757,27 @@ var MenuItemContent = ({ item }) => {
600
757
  maxWidth: "50%"
601
758
  }
602
759
  )
603
- ), !!onEdit && /* @__PURE__ */ React5.createElement(
604
- IconButton4,
760
+ ), !!onEdit && /* @__PURE__ */ React6.createElement(
761
+ IconButton3,
605
762
  {
606
763
  sx: { mx: 1, opacity: "0" },
607
764
  onClick: (e) => {
608
765
  e.stopPropagation();
609
766
  onEdit(item.value);
610
767
  },
611
- "aria-label": __4("Edit", "elementor")
768
+ "aria-label": __8("Edit", "elementor")
612
769
  },
613
- /* @__PURE__ */ React5.createElement(EditIcon, { color: "action", fontSize: SIZE4 })
770
+ /* @__PURE__ */ React6.createElement(EditIcon, { color: "action", fontSize: SIZE3 })
614
771
  ));
615
772
  };
616
773
 
617
774
  // 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";
775
+ import * as React7 from "react";
776
+ import { Link, Stack, Typography as Typography3 } from "@elementor/ui";
777
+ import { __ as __9 } from "@wordpress/i18n";
621
778
  var NoSearchResults = ({ searchValue, onClear, icon }) => {
622
- return /* @__PURE__ */ React6.createElement(
623
- Stack2,
779
+ return /* @__PURE__ */ React7.createElement(
780
+ Stack,
624
781
  {
625
782
  gap: 1,
626
783
  alignItems: "center",
@@ -631,17 +788,17 @@ var NoSearchResults = ({ searchValue, onClear, icon }) => {
631
788
  sx: { pb: 3.5 }
632
789
  },
633
790
  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")))
791
+ /* @__PURE__ */ React7.createElement(Typography3, { align: "center", variant: "subtitle2" }, __9("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React7.createElement("br", null), "\u201C", searchValue, "\u201D."),
792
+ /* @__PURE__ */ React7.createElement(Typography3, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, __9("Try something else.", "elementor"), /* @__PURE__ */ React7.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __9("Clear & try again", "elementor")))
636
793
  );
637
794
  };
638
795
 
639
796
  // 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,
797
+ import * as React8 from "react";
798
+ import { Button as Button4, Stack as Stack2, Typography as Typography4 } from "@elementor/ui";
799
+ import { __ as __10 } from "@wordpress/i18n";
800
+ var NoVariables = ({ icon, title, onAdd }) => /* @__PURE__ */ React8.createElement(
801
+ Stack2,
645
802
  {
646
803
  gap: 1,
647
804
  alignItems: "center",
@@ -651,9 +808,9 @@ var NoVariables = ({ icon, title, onAdd }) => /* @__PURE__ */ React7.createEleme
651
808
  sx: { p: 2.5, pb: 5.5 }
652
809
  },
653
810
  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"))
811
+ /* @__PURE__ */ React8.createElement(Typography4, { align: "center", variant: "subtitle2" }, title),
812
+ /* @__PURE__ */ React8.createElement(Typography4, { align: "center", variant: "caption", maxWidth: "180px" }, __10("Variables are saved attributes that you can apply anywhere on your site.", "elementor")),
813
+ onAdd && /* @__PURE__ */ React8.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __10("Create a variable", "elementor"))
657
814
  );
658
815
 
659
816
  // src/components/ui/styled-menu-list.tsx
@@ -689,10 +846,10 @@ var VariablesStyledMenuList = styled2(MenuList)(({ theme }) => ({
689
846
  }));
690
847
 
691
848
  // src/components/color-variables-selection.tsx
692
- var SIZE5 = "tiny";
849
+ var SIZE4 = "tiny";
693
850
  var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
694
- const { value: variable, setValue: setVariable } = useBoundProp2(colorVariablePropTypeUtil);
695
- const [searchValue, setSearchValue] = useState3("");
851
+ const { value: variable, setValue: setVariable } = useBoundProp3(colorVariablePropTypeUtil);
852
+ const [searchValue, setSearchValue] = useState5("");
696
853
  const {
697
854
  list: variables,
698
855
  hasMatches: hasSearchResults,
@@ -705,19 +862,19 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
705
862
  const actions = [];
706
863
  if (onAdd) {
707
864
  actions.push(
708
- /* @__PURE__ */ React8.createElement(IconButton5, { key: "add", size: SIZE5, onClick: onAdd }, /* @__PURE__ */ React8.createElement(PlusIcon, { fontSize: SIZE5 }))
865
+ /* @__PURE__ */ React9.createElement(IconButton4, { key: "add", size: SIZE4, onClick: onAdd }, /* @__PURE__ */ React9.createElement(PlusIcon, { fontSize: SIZE4 }))
709
866
  );
710
867
  }
711
868
  if (onSettings) {
712
869
  actions.push(
713
- /* @__PURE__ */ React8.createElement(IconButton5, { key: "settings", size: SIZE5, onClick: onSettings }, /* @__PURE__ */ React8.createElement(SettingsIcon, { fontSize: SIZE5 }))
870
+ /* @__PURE__ */ React9.createElement(IconButton4, { key: "settings", size: SIZE4, onClick: onSettings }, /* @__PURE__ */ React9.createElement(SettingsIcon, { fontSize: SIZE4 }))
714
871
  );
715
872
  }
716
873
  const items = variables.map(({ value, label, key }) => ({
717
874
  type: "item",
718
875
  value: key,
719
876
  label,
720
- icon: /* @__PURE__ */ React8.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
877
+ icon: /* @__PURE__ */ React9.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
721
878
  secondaryText: value,
722
879
  onEdit: () => onEdit?.(key)
723
880
  }));
@@ -727,22 +884,22 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
727
884
  const handleClearSearch = () => {
728
885
  setSearchValue("");
729
886
  };
730
- return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
887
+ return /* @__PURE__ */ React9.createElement(PopoverBody3, null, /* @__PURE__ */ React9.createElement(
731
888
  PopoverHeader3,
732
889
  {
733
- title: __7("Variables", "elementor"),
734
- icon: /* @__PURE__ */ React8.createElement(ColorFilterIcon, { fontSize: SIZE5 }),
890
+ title: __11("Variables", "elementor"),
891
+ icon: /* @__PURE__ */ React9.createElement(ColorFilterIcon, { fontSize: SIZE4 }),
735
892
  onClose: closePopover,
736
893
  actions
737
894
  }
738
- ), hasVariables && /* @__PURE__ */ React8.createElement(
895
+ ), hasVariables && /* @__PURE__ */ React9.createElement(
739
896
  PopoverSearch,
740
897
  {
741
898
  value: searchValue,
742
899
  onSearch: handleSearch,
743
- placeholder: __7("Search", "elementor")
900
+ placeholder: __11("Search", "elementor")
744
901
  }
745
- ), /* @__PURE__ */ React8.createElement(Divider3, null), /* @__PURE__ */ React8.createElement(PopoverScrollableContent3, null, hasVariables && hasSearchResults && /* @__PURE__ */ React8.createElement(
902
+ ), /* @__PURE__ */ React9.createElement(Divider3, null), hasVariables && hasSearchResults && /* @__PURE__ */ React9.createElement(
746
903
  PopoverMenuList,
747
904
  {
748
905
  items,
@@ -752,58 +909,113 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
752
909
  selectedValue: variable,
753
910
  "data-testid": "color-variables-list",
754
911
  menuListTemplate: VariablesStyledMenuList,
755
- menuItemContentTemplate: (item) => /* @__PURE__ */ React8.createElement(MenuItemContent, { item })
912
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React9.createElement(MenuItemContent, { item })
756
913
  }
757
- ), !hasSearchResults && hasVariables && /* @__PURE__ */ React8.createElement(
914
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React9.createElement(
758
915
  NoSearchResults,
759
916
  {
760
917
  searchValue,
761
918
  onClear: handleClearSearch,
762
- icon: /* @__PURE__ */ React8.createElement(BrushIcon3, { fontSize: "large" })
919
+ icon: /* @__PURE__ */ React9.createElement(BrushIcon3, { fontSize: "large" })
763
920
  }
764
- ), !hasVariables && /* @__PURE__ */ React8.createElement(
921
+ ), !hasVariables && /* @__PURE__ */ React9.createElement(
765
922
  NoVariables,
766
923
  {
767
- title: __7("Create your first color variable", "elementor"),
768
- icon: /* @__PURE__ */ React8.createElement(BrushIcon3, { fontSize: "large" }),
924
+ title: __11("Create your first color variable", "elementor"),
925
+ icon: /* @__PURE__ */ React9.createElement(BrushIcon3, { fontSize: "large" }),
769
926
  onAdd
770
927
  }
771
- )));
928
+ ));
772
929
  };
773
930
 
774
931
  // 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";
932
+ import * as React11 from "react";
933
+ import { useState as useState7 } from "react";
934
+ import { PopoverContent as PopoverContent3, useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
935
+ import { PopoverBody as PopoverBody4 } from "@elementor/editor-editing-panel";
779
936
  import { PopoverHeader as PopoverHeader4 } from "@elementor/editor-ui";
780
- import { ArrowLeftIcon as ArrowLeftIcon3, ChevronDownIcon, TextIcon } from "@elementor/icons";
937
+ import { ArrowLeftIcon as ArrowLeftIcon3, TextIcon } from "@elementor/icons";
938
+ import { Button as Button5, CardActions as CardActions3, Divider as Divider4, FormHelperText as FormHelperText6, IconButton as IconButton5 } from "@elementor/ui";
939
+ import { __ as __13 } from "@wordpress/i18n";
940
+
941
+ // src/components/fields/font-field.tsx
942
+ import * as React10 from "react";
943
+ import { useRef as useRef2, useState as useState6 } from "react";
944
+ import { FontFamilySelector } from "@elementor/editor-controls";
945
+ import { useFontFamilies, useSectionWidth } from "@elementor/editor-editing-panel";
946
+ import { ChevronDownIcon } from "@elementor/icons";
781
947
  import {
782
948
  bindPopover,
783
949
  bindTrigger,
784
- Button as Button4,
785
- CardActions as CardActions3,
786
- Divider as Divider4,
950
+ FormHelperText as FormHelperText5,
787
951
  FormLabel as FormLabel3,
788
952
  Grid as Grid3,
789
- IconButton as IconButton6,
790
953
  Popover,
791
- TextField as TextField3,
792
954
  UnstableTag,
793
955
  usePopupState
794
956
  } from "@elementor/ui";
795
- import { __ as __8 } from "@wordpress/i18n";
796
- var SIZE6 = "tiny";
797
- var FontVariableCreation = ({ onClose, onGoBack }) => {
798
- const fontFamilies = useFontFamilies();
799
- const { setValue: setVariable } = useBoundProp3(fontVariablePropTypeUtil);
800
- const [fontFamily, setFontFamily] = useState4("");
801
- const [label, setLabel] = useState4("");
802
- const anchorRef = useRef3(null);
803
- const fontPopoverState = usePopupState({ variant: "popover" });
957
+ import { __ as __12 } from "@wordpress/i18n";
958
+ var FontField = ({ value, onChange }) => {
959
+ const [fontFamily, setFontFamily] = useState6(value);
960
+ const [errorMessage, setErrorMessage] = useState6("");
961
+ const defaultRef = useRef2(null);
962
+ const anchorRef = usePopoverContentRef() ?? defaultRef;
963
+ const fontPopoverState = usePopupState({ variant: "popover" });
964
+ const fontFamilies = useFontFamilies();
965
+ const sectionWidth = useSectionWidth();
966
+ const handleChange = (newValue) => {
967
+ setFontFamily(newValue);
968
+ const errorMsg = validateValue(newValue);
969
+ setErrorMessage(errorMsg);
970
+ onChange(errorMsg ? "" : newValue);
971
+ };
972
+ const handleFontFamilyChange = (newFontFamily) => {
973
+ handleChange(newFontFamily);
974
+ fontPopoverState.close();
975
+ };
976
+ return /* @__PURE__ */ React10.createElement(Grid3, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React10.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(FormLabel3, { size: "tiny" }, __12("Value", "elementor"))), /* @__PURE__ */ React10.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(
977
+ UnstableTag,
978
+ {
979
+ variant: "outlined",
980
+ label: fontFamily,
981
+ endIcon: /* @__PURE__ */ React10.createElement(ChevronDownIcon, { fontSize: "tiny" }),
982
+ ...bindTrigger(fontPopoverState),
983
+ fullWidth: true
984
+ }
985
+ ), /* @__PURE__ */ React10.createElement(
986
+ Popover,
987
+ {
988
+ disablePortal: true,
989
+ disableScrollLock: true,
990
+ anchorEl: anchorRef.current,
991
+ anchorOrigin: { vertical: "top", horizontal: "right" },
992
+ transformOrigin: { vertical: "top", horizontal: -20 },
993
+ ...bindPopover(fontPopoverState)
994
+ },
995
+ /* @__PURE__ */ React10.createElement(
996
+ FontFamilySelector,
997
+ {
998
+ fontFamilies,
999
+ fontFamily,
1000
+ onFontFamilyChange: handleFontFamilyChange,
1001
+ onClose: fontPopoverState.close,
1002
+ sectionWidth
1003
+ }
1004
+ )
1005
+ ), errorMessage && /* @__PURE__ */ React10.createElement(FormHelperText5, { error: true }, errorMessage)));
1006
+ };
1007
+
1008
+ // src/components/font-variable-creation.tsx
1009
+ var SIZE5 = "tiny";
1010
+ var FontVariableCreation = ({ onClose, onGoBack }) => {
1011
+ const { setValue: setVariable } = useBoundProp4(fontVariablePropTypeUtil);
1012
+ const [fontFamily, setFontFamily] = useState7("");
1013
+ const [label, setLabel] = useState7("");
1014
+ const [errorMessage, setErrorMessage] = useState7("");
804
1015
  const resetFields = () => {
805
1016
  setFontFamily("");
806
1017
  setLabel("");
1018
+ setErrorMessage("");
807
1019
  };
808
1020
  const closePopover = () => {
809
1021
  resetFields();
@@ -817,178 +1029,168 @@ var FontVariableCreation = ({ onClose, onGoBack }) => {
817
1029
  }).then((key) => {
818
1030
  setVariable(key);
819
1031
  closePopover();
1032
+ }).catch((error) => {
1033
+ setErrorMessage(error.message);
820
1034
  });
821
1035
  };
822
- const isFormInvalid = () => {
823
- return !fontFamily?.trim() || !label?.trim();
1036
+ const hasEmptyValue = () => {
1037
+ return "" === fontFamily.trim() || "" === label.trim();
824
1038
  };
825
- const sectionWidth = useSectionWidth();
826
- return /* @__PURE__ */ React9.createElement(PopoverScrollableContent4, { height: "auto" }, /* @__PURE__ */ React9.createElement(
1039
+ const isSubmitDisabled = hasEmptyValue();
1040
+ return /* @__PURE__ */ React11.createElement(PopoverBody4, { height: "auto" }, /* @__PURE__ */ React11.createElement(
827
1041
  PopoverHeader4,
828
1042
  {
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"),
1043
+ icon: /* @__PURE__ */ React11.createElement(React11.Fragment, null, onGoBack && /* @__PURE__ */ React11.createElement(IconButton5, { size: SIZE5, "aria-label": __13("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React11.createElement(ArrowLeftIcon3, { fontSize: SIZE5 })), /* @__PURE__ */ React11.createElement(TextIcon, { fontSize: SIZE5 })),
1044
+ title: __13("Create variable", "elementor"),
831
1045
  onClose: closePopover
832
1046
  }
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,
1047
+ ), /* @__PURE__ */ React11.createElement(Divider4, null), /* @__PURE__ */ React11.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React11.createElement(
1048
+ LabelField,
835
1049
  {
836
- size: "tiny",
837
- fullWidth: true,
838
1050
  value: label,
839
- onChange: (e) => setLabel(e.target.value)
840
- }
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(
842
- UnstableTag,
843
- {
844
- variant: "outlined",
845
- label: fontFamily,
846
- endIcon: /* @__PURE__ */ React9.createElement(ChevronDownIcon, { fontSize: "tiny" }),
847
- ...bindTrigger(fontPopoverState),
848
- fullWidth: true
1051
+ onChange: (value) => {
1052
+ setLabel(value);
1053
+ setErrorMessage("");
1054
+ }
849
1055
  }
850
- ), /* @__PURE__ */ React9.createElement(
851
- Popover,
1056
+ ), /* @__PURE__ */ React11.createElement(
1057
+ FontField,
852
1058
  {
853
- disablePortal: true,
854
- disableScrollLock: true,
855
- anchorEl: anchorRef.current,
856
- anchorOrigin: { vertical: "top", horizontal: "right" },
857
- transformOrigin: { vertical: "top", horizontal: -20 },
858
- ...bindPopover(fontPopoverState)
859
- },
860
- /* @__PURE__ */ React9.createElement(
861
- FontFamilySelector,
862
- {
863
- fontFamilies,
864
- fontFamily,
865
- onFontFamilyChange: setFontFamily,
866
- onClose: fontPopoverState.close,
867
- sectionWidth
1059
+ value: fontFamily,
1060
+ onChange: (value) => {
1061
+ setFontFamily(value);
1062
+ setErrorMessage("");
868
1063
  }
869
- )
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"))));
1064
+ }
1065
+ ), errorMessage && /* @__PURE__ */ React11.createElement(FormHelperText6, { error: true }, errorMessage)), /* @__PURE__ */ React11.createElement(CardActions3, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React11.createElement(Button5, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreate }, __13("Create", "elementor"))));
871
1066
  };
872
1067
 
873
1068
  // 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";
1069
+ import * as React12 from "react";
1070
+ import { useState as useState8 } from "react";
1071
+ import { PopoverContent as PopoverContent4, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
1072
+ import { PopoverBody as PopoverBody5 } from "@elementor/editor-editing-panel";
1073
+ import { PopoverHeader as PopoverHeader5 } from "@elementor/editor-ui";
1074
+ import { ArrowLeftIcon as ArrowLeftIcon4, TextIcon as TextIcon2, TrashIcon as TrashIcon2 } from "@elementor/icons";
1075
+ import { Button as Button6, CardActions as CardActions4, Divider as Divider5, FormHelperText as FormHelperText7, IconButton as IconButton6 } from "@elementor/ui";
1076
+ import { __ as __14 } from "@wordpress/i18n";
1077
+ var SIZE6 = "tiny";
896
1078
  var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1079
+ const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp5(fontVariablePropTypeUtil);
1080
+ const [deleteConfirmation, setDeleteConfirmation] = useState8(false);
1081
+ const [errorMessage, setErrorMessage] = useState8("");
897
1082
  const variable = useVariable(editId);
898
1083
  if (!variable) {
899
1084
  throw new Error(`Global font variable "${editId}" not found`);
900
1085
  }
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();
1086
+ const [fontFamily, setFontFamily] = useState8(variable.value);
1087
+ const [label, setLabel] = useState8(variable.label);
908
1088
  const handleUpdate = () => {
909
1089
  updateVariable(editId, {
910
1090
  value: fontFamily,
911
1091
  label
912
1092
  }).then(() => {
1093
+ maybeTriggerBoundPropChange();
913
1094
  onSubmit?.();
1095
+ }).catch((error) => {
1096
+ setErrorMessage(error.message);
914
1097
  });
915
1098
  };
916
1099
  const handleDelete = () => {
917
1100
  deleteVariable(editId).then(() => {
1101
+ maybeTriggerBoundPropChange();
918
1102
  onSubmit?.();
919
1103
  });
920
1104
  };
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();
1105
+ const maybeTriggerBoundPropChange = () => {
1106
+ if (editId === assignedValue) {
1107
+ notifyBoundPropChange(editId);
1108
+ }
1109
+ };
1110
+ const handleDeleteConfirmation = () => {
1111
+ setDeleteConfirmation(true);
1112
+ };
1113
+ const closeDeleteDialog = () => () => {
1114
+ setDeleteConfirmation(false);
1115
+ };
1116
+ const hasEmptyValue = () => {
1117
+ return !fontFamily.trim() || !label.trim();
1118
+ };
1119
+ const noValueChanged = () => {
1120
+ return fontFamily === variable.value && label === variable.label;
1121
+ };
1122
+ const isSubmitDisabled = noValueChanged() || hasEmptyValue();
925
1123
  const actions = [];
926
1124
  actions.push(
927
- /* @__PURE__ */ React10.createElement(IconButton7, { key: "delete", size: SIZE7, "aria-label": __9("Delete", "elementor"), onClick: handleDelete }, /* @__PURE__ */ React10.createElement(TrashIcon2, { fontSize: SIZE7 }))
1125
+ /* @__PURE__ */ React12.createElement(
1126
+ IconButton6,
1127
+ {
1128
+ key: "delete",
1129
+ size: SIZE6,
1130
+ "aria-label": __14("Delete", "elementor"),
1131
+ onClick: handleDeleteConfirmation
1132
+ },
1133
+ /* @__PURE__ */ React12.createElement(TrashIcon2, { fontSize: SIZE6 })
1134
+ )
928
1135
  );
929
- return /* @__PURE__ */ React10.createElement(PopoverScrollableContent5, { height: "auto" }, /* @__PURE__ */ React10.createElement(
1136
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(PopoverBody5, { height: "auto" }, /* @__PURE__ */ React12.createElement(
930
1137
  PopoverHeader5,
931
1138
  {
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"),
1139
+ icon: /* @__PURE__ */ React12.createElement(React12.Fragment, null, onGoBack && /* @__PURE__ */ React12.createElement(
1140
+ IconButton6,
1141
+ {
1142
+ size: SIZE6,
1143
+ "aria-label": __14("Go Back", "elementor"),
1144
+ onClick: onGoBack
1145
+ },
1146
+ /* @__PURE__ */ React12.createElement(ArrowLeftIcon4, { fontSize: SIZE6 })
1147
+ ), /* @__PURE__ */ React12.createElement(TextIcon2, { fontSize: SIZE6 })),
1148
+ title: __14("Edit variable", "elementor"),
934
1149
  onClose,
935
1150
  actions
936
1151
  }
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,
1152
+ ), /* @__PURE__ */ React12.createElement(Divider5, null), /* @__PURE__ */ React12.createElement(PopoverContent4, { p: 2 }, /* @__PURE__ */ React12.createElement(
1153
+ LabelField,
939
1154
  {
940
- id: variableNameId,
941
- size: "tiny",
942
- fullWidth: true,
943
1155
  value: label,
944
- onChange: (e) => setLabel(e.target.value)
1156
+ onChange: (value) => {
1157
+ setLabel(value);
1158
+ setErrorMessage("");
1159
+ }
945
1160
  }
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,
1161
+ ), /* @__PURE__ */ React12.createElement(
1162
+ FontField,
948
1163
  {
949
- id: variableValueId,
950
- variant: "outlined",
951
- label: fontFamily,
952
- endIcon: /* @__PURE__ */ React10.createElement(ChevronDownIcon2, { fontSize: "tiny" }),
953
- ...bindTrigger2(fontPopoverState),
954
- fullWidth: true
1164
+ value: fontFamily,
1165
+ onChange: (value) => {
1166
+ setFontFamily(value);
1167
+ setErrorMessage("");
1168
+ }
955
1169
  }
956
- ), /* @__PURE__ */ React10.createElement(
957
- Popover2,
1170
+ ), errorMessage && /* @__PURE__ */ React12.createElement(FormHelperText7, { error: true }, errorMessage)), /* @__PURE__ */ React12.createElement(CardActions4, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React12.createElement(Button6, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __14("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React12.createElement(
1171
+ DeleteConfirmationDialog,
958
1172
  {
959
- disablePortal: true,
960
- disableScrollLock: true,
961
- anchorEl: anchorRef.current,
962
- anchorOrigin: { vertical: "top", horizontal: "right" },
963
- transformOrigin: { vertical: "top", horizontal: -20 },
964
- ...bindPopover2(fontPopoverState)
965
- },
966
- /* @__PURE__ */ React10.createElement(
967
- FontFamilySelector2,
968
- {
969
- fontFamilies,
970
- fontFamily,
971
- onFontFamilyChange: setFontFamily,
972
- onClose: fontPopoverState.close,
973
- sectionWidth
974
- }
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"))));
1173
+ open: true,
1174
+ label,
1175
+ onConfirm: handleDelete,
1176
+ closeDialog: closeDeleteDialog()
1177
+ }
1178
+ ));
977
1179
  };
978
1180
 
979
1181
  // 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";
1182
+ import * as React13 from "react";
1183
+ import { useState as useState9 } from "react";
1184
+ import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
1185
+ import { PopoverBody as PopoverBody6 } from "@elementor/editor-editing-panel";
984
1186
  import { PopoverHeader as PopoverHeader6, PopoverMenuList as PopoverMenuList2, PopoverSearch as PopoverSearch2 } from "@elementor/editor-ui";
985
1187
  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";
1188
+ import { Divider as Divider6, IconButton as IconButton7 } from "@elementor/ui";
1189
+ import { __ as __15 } from "@wordpress/i18n";
1190
+ var SIZE7 = "tiny";
989
1191
  var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
990
- const { value: variable, setValue: setVariable } = useBoundProp4(fontVariablePropTypeUtil);
991
- const [searchValue, setSearchValue] = useState6("");
1192
+ const { value: variable, setValue: setVariable } = useBoundProp6(fontVariablePropTypeUtil);
1193
+ const [searchValue, setSearchValue] = useState9("");
992
1194
  const {
993
1195
  list: variables,
994
1196
  hasMatches: hasSearchResults,
@@ -1001,19 +1203,19 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1001
1203
  const actions = [];
1002
1204
  if (onAdd) {
1003
1205
  actions.push(
1004
- /* @__PURE__ */ React11.createElement(IconButton8, { key: "add", size: SIZE8, onClick: onAdd }, /* @__PURE__ */ React11.createElement(PlusIcon2, { fontSize: SIZE8 }))
1206
+ /* @__PURE__ */ React13.createElement(IconButton7, { key: "add", size: SIZE7, onClick: onAdd }, /* @__PURE__ */ React13.createElement(PlusIcon2, { fontSize: SIZE7 }))
1005
1207
  );
1006
1208
  }
1007
1209
  if (onSettings) {
1008
1210
  actions.push(
1009
- /* @__PURE__ */ React11.createElement(IconButton8, { key: "settings", size: SIZE8, onClick: onSettings }, /* @__PURE__ */ React11.createElement(SettingsIcon2, { fontSize: SIZE8 }))
1211
+ /* @__PURE__ */ React13.createElement(IconButton7, { key: "settings", size: SIZE7, onClick: onSettings }, /* @__PURE__ */ React13.createElement(SettingsIcon2, { fontSize: SIZE7 }))
1010
1212
  );
1011
1213
  }
1012
1214
  const items = variables.map(({ value, label, key }) => ({
1013
1215
  type: "item",
1014
1216
  value: key,
1015
1217
  label,
1016
- icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: SIZE8 }),
1218
+ icon: /* @__PURE__ */ React13.createElement(TextIcon3, { fontSize: SIZE7 }),
1017
1219
  secondaryText: value,
1018
1220
  onEdit: () => onEdit?.(key)
1019
1221
  }));
@@ -1023,22 +1225,22 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1023
1225
  const handleClearSearch = () => {
1024
1226
  setSearchValue("");
1025
1227
  };
1026
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(
1228
+ return /* @__PURE__ */ React13.createElement(PopoverBody6, null, /* @__PURE__ */ React13.createElement(
1027
1229
  PopoverHeader6,
1028
1230
  {
1029
- title: __10("Variables", "elementor"),
1231
+ title: __15("Variables", "elementor"),
1030
1232
  onClose: closePopover,
1031
- icon: /* @__PURE__ */ React11.createElement(ColorFilterIcon2, { fontSize: SIZE8 }),
1233
+ icon: /* @__PURE__ */ React13.createElement(ColorFilterIcon2, { fontSize: SIZE7 }),
1032
1234
  actions
1033
1235
  }
1034
- ), hasVariables && /* @__PURE__ */ React11.createElement(
1236
+ ), hasVariables && /* @__PURE__ */ React13.createElement(
1035
1237
  PopoverSearch2,
1036
1238
  {
1037
1239
  value: searchValue,
1038
1240
  onSearch: handleSearch,
1039
- placeholder: __10("Search", "elementor")
1241
+ placeholder: __15("Search", "elementor")
1040
1242
  }
1041
- ), /* @__PURE__ */ React11.createElement(Divider6, null), /* @__PURE__ */ React11.createElement(PopoverScrollableContent6, null, hasVariables && hasSearchResults && /* @__PURE__ */ React11.createElement(
1243
+ ), /* @__PURE__ */ React13.createElement(Divider6, null), hasVariables && hasSearchResults && /* @__PURE__ */ React13.createElement(
1042
1244
  PopoverMenuList2,
1043
1245
  {
1044
1246
  items,
@@ -1048,23 +1250,23 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1048
1250
  selectedValue: variable,
1049
1251
  "data-testid": "font-variables-list",
1050
1252
  menuListTemplate: VariablesStyledMenuList,
1051
- menuItemContentTemplate: (item) => /* @__PURE__ */ React11.createElement(MenuItemContent, { item })
1253
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React13.createElement(MenuItemContent, { item })
1052
1254
  }
1053
- ), !hasSearchResults && hasVariables && /* @__PURE__ */ React11.createElement(
1255
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React13.createElement(
1054
1256
  NoSearchResults,
1055
1257
  {
1056
1258
  searchValue,
1057
1259
  onClear: handleClearSearch,
1058
- icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: "large" })
1260
+ icon: /* @__PURE__ */ React13.createElement(TextIcon3, { fontSize: "large" })
1059
1261
  }
1060
- ), !hasVariables && /* @__PURE__ */ React11.createElement(
1262
+ ), !hasVariables && /* @__PURE__ */ React13.createElement(
1061
1263
  NoVariables,
1062
1264
  {
1063
- title: __10("Create your first font variable", "elementor"),
1064
- icon: /* @__PURE__ */ React11.createElement(TextIcon3, { fontSize: "large" }),
1265
+ title: __15("Create your first font variable", "elementor"),
1266
+ icon: /* @__PURE__ */ React13.createElement(TextIcon3, { fontSize: "large" }),
1065
1267
  onAdd
1066
1268
  }
1067
- )));
1269
+ ));
1068
1270
  };
1069
1271
 
1070
1272
  // src/components/variable-selection-popover.tsx
@@ -1072,10 +1274,10 @@ var VIEW_LIST = "list";
1072
1274
  var VIEW_ADD = "add";
1073
1275
  var VIEW_EDIT = "edit";
1074
1276
  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({
1277
+ const [currentView, setCurrentView] = useState10(VIEW_LIST);
1278
+ const editIdRef = useRef3("");
1279
+ const anchorRef = useRef3(null);
1280
+ return /* @__PURE__ */ React14.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React14.createElement(Box2, { ref: anchorRef }, renderStage({
1079
1281
  propTypeKey,
1080
1282
  currentView,
1081
1283
  selectedVariable,
@@ -1094,7 +1296,7 @@ function renderStage(props) {
1094
1296
  };
1095
1297
  if (fontVariablePropTypeUtil.key === props.propTypeKey) {
1096
1298
  if (VIEW_LIST === props.currentView) {
1097
- return /* @__PURE__ */ React12.createElement(
1299
+ return /* @__PURE__ */ React14.createElement(
1098
1300
  FontVariablesSelection,
1099
1301
  {
1100
1302
  closePopover: props.closePopover,
@@ -1109,7 +1311,7 @@ function renderStage(props) {
1109
1311
  );
1110
1312
  }
1111
1313
  if (VIEW_ADD === props.currentView) {
1112
- return /* @__PURE__ */ React12.createElement(
1314
+ return /* @__PURE__ */ React14.createElement(
1113
1315
  FontVariableCreation,
1114
1316
  {
1115
1317
  onGoBack: () => props.setCurrentView(VIEW_LIST),
@@ -1118,7 +1320,7 @@ function renderStage(props) {
1118
1320
  );
1119
1321
  }
1120
1322
  if (VIEW_EDIT === props.currentView) {
1121
- return /* @__PURE__ */ React12.createElement(
1323
+ return /* @__PURE__ */ React14.createElement(
1122
1324
  FontVariableEdit,
1123
1325
  {
1124
1326
  editId: props.editIdRef.current ?? "",
@@ -1131,7 +1333,7 @@ function renderStage(props) {
1131
1333
  }
1132
1334
  if (colorVariablePropTypeUtil.key === props.propTypeKey) {
1133
1335
  if (VIEW_LIST === props.currentView) {
1134
- return /* @__PURE__ */ React12.createElement(
1336
+ return /* @__PURE__ */ React14.createElement(
1135
1337
  ColorVariablesSelection,
1136
1338
  {
1137
1339
  closePopover: props.closePopover,
@@ -1146,7 +1348,7 @@ function renderStage(props) {
1146
1348
  );
1147
1349
  }
1148
1350
  if (VIEW_ADD === props.currentView) {
1149
- return /* @__PURE__ */ React12.createElement(
1351
+ return /* @__PURE__ */ React14.createElement(
1150
1352
  ColorVariableCreation,
1151
1353
  {
1152
1354
  onGoBack: () => props.setCurrentView(VIEW_LIST),
@@ -1155,7 +1357,7 @@ function renderStage(props) {
1155
1357
  );
1156
1358
  }
1157
1359
  if (VIEW_EDIT === props.currentView) {
1158
- return /* @__PURE__ */ React12.createElement(
1360
+ return /* @__PURE__ */ React14.createElement(
1159
1361
  ColorVariableEdit,
1160
1362
  {
1161
1363
  editId: props.editIdRef.current ?? "",
@@ -1169,33 +1371,59 @@ function renderStage(props) {
1169
1371
  return null;
1170
1372
  }
1171
1373
 
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);
1374
+ // src/components/ui/tags/assigned-tag.tsx
1375
+ import * as React15 from "react";
1376
+ import { DetachIcon } from "@elementor/icons";
1377
+ import { Box as Box3, IconButton as IconButton8, Stack as Stack3, Tooltip, Typography as Typography5, UnstableTag as Tag } from "@elementor/ui";
1378
+ import { __ as __16 } from "@wordpress/i18n";
1379
+ var SIZE8 = "tiny";
1380
+ var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1381
+ const actions = [];
1382
+ if (onUnlink) {
1383
+ actions.push(
1384
+ /* @__PURE__ */ React15.createElement(IconButton8, { key: "unlink", size: SIZE8, onClick: onUnlink, "aria-label": __16("Unlink", "elementor") }, /* @__PURE__ */ React15.createElement(DetachIcon, { fontSize: SIZE8 }))
1385
+ );
1386
+ }
1387
+ return /* @__PURE__ */ React15.createElement(Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React15.createElement(
1388
+ Tag,
1389
+ {
1390
+ fullWidth: true,
1391
+ showActionsOnHover: true,
1392
+ startIcon: /* @__PURE__ */ React15.createElement(Stack3, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
1393
+ label: /* @__PURE__ */ React15.createElement(Box3, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React15.createElement(Typography5, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
1394
+ actions,
1395
+ ...props
1396
+ }
1397
+ ));
1398
+ };
1399
+
1400
+ // src/components/ui/variable/assigned-variable.tsx
1401
+ var AssignedVariable = ({
1402
+ variable,
1403
+ variablePropTypeUtil,
1404
+ fallbackPropTypeUtil,
1405
+ additionalStartIcon
1406
+ }) => {
1407
+ const { setValue } = useBoundProp7();
1408
+ const anchorRef = useRef4(null);
1177
1409
  const popupId = useId2();
1178
- const popupState = usePopupState3({
1410
+ const popupState = usePopupState2({
1179
1411
  variant: "popover",
1180
1412
  popupId: `elementor-variables-list-${popupId}`
1181
1413
  });
1182
- const selectedVariable = useVariable(variableValue);
1183
- if (!selectedVariable) {
1184
- throw new Error(`Global color variable ${variableValue} not found`);
1185
- }
1186
1414
  const unlinkVariable = () => {
1187
- setColor(colorPropTypeUtil.create(selectedVariable.value));
1415
+ setValue(fallbackPropTypeUtil.create(variable.value));
1188
1416
  };
1189
- return /* @__PURE__ */ React13.createElement(Box4, { ref: anchorRef }, /* @__PURE__ */ React13.createElement(
1190
- VariableTag,
1417
+ return /* @__PURE__ */ React16.createElement(Box4, { ref: anchorRef }, /* @__PURE__ */ React16.createElement(
1418
+ AssignedTag,
1191
1419
  {
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" })),
1420
+ label: variable.label,
1421
+ startIcon: /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(ColorFilterIcon3, { fontSize: SIZE8 }), additionalStartIcon),
1194
1422
  onUnlink: unlinkVariable,
1195
- ...bindTrigger3(popupState)
1423
+ ...bindTrigger2(popupState)
1196
1424
  }
1197
- ), /* @__PURE__ */ React13.createElement(
1198
- Popover3,
1425
+ ), /* @__PURE__ */ React16.createElement(
1426
+ Popover2,
1199
1427
  {
1200
1428
  disableScrollLock: true,
1201
1429
  anchorEl: anchorRef.current,
@@ -1204,24 +1432,168 @@ var ColorVariableControl = () => {
1204
1432
  PaperProps: {
1205
1433
  sx: { my: 1 }
1206
1434
  },
1207
- ...bindPopover3(popupState)
1435
+ ...bindPopover2(popupState)
1208
1436
  },
1209
- /* @__PURE__ */ React13.createElement(
1437
+ /* @__PURE__ */ React16.createElement(
1210
1438
  VariableSelectionPopover,
1211
1439
  {
1212
- selectedVariable,
1440
+ selectedVariable: variable,
1213
1441
  closePopover: popupState.close,
1214
- propTypeKey: colorVariablePropTypeUtil.key
1442
+ propTypeKey: variablePropTypeUtil.key
1215
1443
  }
1216
1444
  )
1217
1445
  ));
1218
1446
  };
1219
1447
 
1448
+ // src/components/ui/variable/deleted-variable.tsx
1449
+ import * as React19 from "react";
1450
+ import { useState as useState11 } from "react";
1451
+ import { useBoundProp as useBoundProp8 } from "@elementor/editor-controls";
1452
+ import { isExperimentActive } from "@elementor/editor-v1-adapters";
1453
+ import { Backdrop, Infotip } from "@elementor/ui";
1454
+
1455
+ // src/components/ui/deleted-variable-alert.tsx
1456
+ import * as React17 from "react";
1457
+ import { useSectionWidth as useSectionWidth2 } from "@elementor/editor-editing-panel";
1458
+ import { Alert, AlertAction, AlertTitle, ClickAwayListener } from "@elementor/ui";
1459
+ import { __ as __17 } from "@wordpress/i18n";
1460
+ var DeletedVariableAlert = ({ onClose, onUnlink, onRestore, label }) => {
1461
+ const sectionWidth = useSectionWidth2();
1462
+ return /* @__PURE__ */ React17.createElement(ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React17.createElement(
1463
+ Alert,
1464
+ {
1465
+ variant: "standard",
1466
+ severity: "warning",
1467
+ onClose,
1468
+ action: /* @__PURE__ */ React17.createElement(React17.Fragment, null, onUnlink && /* @__PURE__ */ React17.createElement(AlertAction, { variant: "contained", onClick: onUnlink }, __17("Unlink", "elementor")), onRestore && /* @__PURE__ */ React17.createElement(AlertAction, { variant: "outlined", onClick: onRestore }, __17("Restore", "elementor"))),
1469
+ sx: { width: sectionWidth }
1470
+ },
1471
+ /* @__PURE__ */ React17.createElement(AlertTitle, null, __17("Deleted variable", "elementor")),
1472
+ __17("The variable", "elementor"),
1473
+ " '",
1474
+ label,
1475
+ "'",
1476
+ " ",
1477
+ __17(
1478
+ "has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.",
1479
+ "elementor"
1480
+ )
1481
+ ));
1482
+ };
1483
+
1484
+ // src/components/ui/tags/deleted-tag.tsx
1485
+ import * as React18 from "react";
1486
+ import { AlertTriangleFilledIcon } from "@elementor/icons";
1487
+ import { Box as Box5, Chip, Tooltip as Tooltip2, Typography as Typography6 } from "@elementor/ui";
1488
+ import { __ as __18 } from "@wordpress/i18n";
1489
+ var DeletedTag = React18.forwardRef(({ label, onClick, ...props }, ref) => {
1490
+ return /* @__PURE__ */ React18.createElement(
1491
+ Chip,
1492
+ {
1493
+ ref,
1494
+ size: "tiny",
1495
+ color: "warning",
1496
+ shape: "rounded",
1497
+ variant: "standard",
1498
+ onClick,
1499
+ icon: /* @__PURE__ */ React18.createElement(AlertTriangleFilledIcon, null),
1500
+ label: /* @__PURE__ */ React18.createElement(Tooltip2, { title: label, placement: "top" }, /* @__PURE__ */ React18.createElement(Box5, { sx: { display: "flex", gap: 0.5, alignItems: "center" } }, /* @__PURE__ */ React18.createElement(Typography6, { variant: "caption", noWrap: true }, label), /* @__PURE__ */ React18.createElement(Typography6, { variant: "caption", noWrap: true, sx: { textOverflow: "initial", overflow: "visible" } }, "(", __18("deleted", "elementor"), ")"))),
1501
+ sx: {
1502
+ height: (theme) => theme.spacing(3.5),
1503
+ borderRadius: (theme) => theme.spacing(1),
1504
+ justifyContent: "flex-start",
1505
+ width: "100%"
1506
+ },
1507
+ ...props
1508
+ }
1509
+ );
1510
+ });
1511
+
1512
+ // src/components/ui/variable/deleted-variable.tsx
1513
+ var isV331Active = isExperimentActive("e_v_3_31");
1514
+ var DeletedVariable = ({ variable, variablePropTypeUtil, fallbackPropTypeUtil }) => {
1515
+ const { setValue } = useBoundProp8();
1516
+ const [showInfotip, setShowInfotip] = useState11(false);
1517
+ const toggleInfotip = () => setShowInfotip((prev) => !prev);
1518
+ const closeInfotip = () => setShowInfotip(false);
1519
+ const unlinkVariable = () => {
1520
+ setValue(fallbackPropTypeUtil.create(variable.value));
1521
+ };
1522
+ const handleRestore = () => {
1523
+ if (!variable.key) {
1524
+ return;
1525
+ }
1526
+ restoreVariable(variable.key).then((key) => {
1527
+ setValue(variablePropTypeUtil.create(key));
1528
+ closeInfotip();
1529
+ });
1530
+ };
1531
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, null, showInfotip && /* @__PURE__ */ React19.createElement(Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React19.createElement(
1532
+ Infotip,
1533
+ {
1534
+ color: "warning",
1535
+ placement: "right-start",
1536
+ open: showInfotip,
1537
+ disableHoverListener: true,
1538
+ onClose: closeInfotip,
1539
+ content: /* @__PURE__ */ React19.createElement(
1540
+ DeletedVariableAlert,
1541
+ {
1542
+ onClose: closeInfotip,
1543
+ onUnlink: unlinkVariable,
1544
+ onRestore: isV331Active ? handleRestore : void 0,
1545
+ label: variable.label
1546
+ }
1547
+ ),
1548
+ slotProps: {
1549
+ popper: {
1550
+ modifiers: [
1551
+ {
1552
+ name: "offset",
1553
+ options: { offset: [0, 24] }
1554
+ }
1555
+ ]
1556
+ }
1557
+ }
1558
+ },
1559
+ /* @__PURE__ */ React19.createElement(DeletedTag, { label: variable.label, onClick: toggleInfotip })
1560
+ ));
1561
+ };
1562
+
1563
+ // src/controls/color-variable-control.tsx
1564
+ var ColorVariableControl = () => {
1565
+ const { value: variableValue } = useBoundProp9(colorVariablePropTypeUtil);
1566
+ const assignedVariable = useVariable(variableValue);
1567
+ if (!assignedVariable) {
1568
+ throw new Error(`Global color variable ${variableValue} not found`);
1569
+ }
1570
+ const isVariableDeleted = assignedVariable?.deleted;
1571
+ if (isVariableDeleted) {
1572
+ return /* @__PURE__ */ React20.createElement(
1573
+ DeletedVariable,
1574
+ {
1575
+ variable: assignedVariable,
1576
+ variablePropTypeUtil: colorVariablePropTypeUtil,
1577
+ fallbackPropTypeUtil: colorPropTypeUtil
1578
+ }
1579
+ );
1580
+ }
1581
+ return /* @__PURE__ */ React20.createElement(
1582
+ AssignedVariable,
1583
+ {
1584
+ variable: assignedVariable,
1585
+ variablePropTypeUtil: colorVariablePropTypeUtil,
1586
+ fallbackPropTypeUtil: colorPropTypeUtil,
1587
+ additionalStartIcon: /* @__PURE__ */ React20.createElement(ColorIndicator, { size: "inherit", value: assignedVariable.value, component: "span" })
1588
+ }
1589
+ );
1590
+ };
1591
+
1220
1592
  // src/hooks/use-prop-color-variable-action.tsx
1221
- import * as React14 from "react";
1222
- import { useBoundProp as useBoundProp6 } from "@elementor/editor-editing-panel";
1593
+ import * as React21 from "react";
1594
+ import { useBoundProp as useBoundProp10 } from "@elementor/editor-editing-panel";
1223
1595
  import { ColorFilterIcon as ColorFilterIcon4 } from "@elementor/icons";
1224
- import { __ as __11 } from "@wordpress/i18n";
1596
+ import { __ as __19 } from "@wordpress/i18n";
1225
1597
 
1226
1598
  // src/utils.ts
1227
1599
  var hasAssignedColorVariable = (propValue) => {
@@ -1239,38 +1611,90 @@ var supportsFontVariables = (propType) => {
1239
1611
 
1240
1612
  // src/hooks/use-prop-color-variable-action.tsx
1241
1613
  var usePropColorVariableAction = () => {
1242
- const { propType } = useBoundProp6();
1614
+ const { propType } = useBoundProp10();
1243
1615
  const visible = !!propType && supportsColorVariables(propType);
1244
1616
  return {
1245
1617
  visible,
1246
1618
  icon: ColorFilterIcon4,
1247
- title: __11("Variables", "elementor"),
1619
+ title: __19("Variables", "elementor"),
1248
1620
  content: ({ close: closePopover }) => {
1249
- return /* @__PURE__ */ React14.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1621
+ return /* @__PURE__ */ React21.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1250
1622
  }
1251
1623
  };
1252
1624
  };
1253
1625
 
1626
+ // src/repeater-injections.ts
1627
+ import { injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel } from "@elementor/editor-controls";
1628
+ import { backgroundColorOverlayPropTypeUtil, shadowPropTypeUtil } from "@elementor/editor-props";
1629
+
1630
+ // src/components/variables-repeater-item-slot.tsx
1631
+ import * as React22 from "react";
1632
+ var useColorVariable = (value) => {
1633
+ const variableId = value?.value?.color?.value;
1634
+ return useVariable(variableId || "");
1635
+ };
1636
+ var BackgroundRepeaterColorIndicator = ({ value }) => {
1637
+ const colorVariable = useColorVariable(value);
1638
+ return /* @__PURE__ */ React22.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1639
+ };
1640
+ var BackgroundRepeaterLabel = ({ value }) => {
1641
+ const colorVariable = useColorVariable(value);
1642
+ return /* @__PURE__ */ React22.createElement("span", null, colorVariable?.label);
1643
+ };
1644
+ var BoxShadowRepeaterColorIndicator = ({ value }) => {
1645
+ const colorVariable = useColorVariable(value);
1646
+ return /* @__PURE__ */ React22.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1647
+ };
1648
+
1649
+ // src/repeater-injections.ts
1650
+ function registerRepeaterInjections() {
1651
+ injectIntoRepeaterItemIcon({
1652
+ id: "color-variables-background-icon",
1653
+ component: BackgroundRepeaterColorIndicator,
1654
+ condition: ({ value: prop }) => {
1655
+ return hasAssignedColorVariable(backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
1656
+ }
1657
+ });
1658
+ injectIntoRepeaterItemIcon({
1659
+ id: "color-variables-icon",
1660
+ component: BoxShadowRepeaterColorIndicator,
1661
+ condition: ({ value: prop }) => {
1662
+ return hasAssignedColorVariable(shadowPropTypeUtil.extract(prop)?.color);
1663
+ }
1664
+ });
1665
+ injectIntoRepeaterItemLabel({
1666
+ id: "color-variables-label",
1667
+ component: BackgroundRepeaterLabel,
1668
+ condition: ({ value: prop }) => {
1669
+ return hasAssignedColorVariable(backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
1670
+ }
1671
+ });
1672
+ }
1673
+
1254
1674
  // src/transformers/variable-transformer.ts
1255
1675
  import { createTransformer } from "@elementor/editor-canvas";
1256
- var variableTransformer = createTransformer((value) => {
1257
- if (!value.trim()) {
1676
+ var variableTransformer = createTransformer((id) => {
1677
+ const variables = service.variables();
1678
+ let name = id;
1679
+ let fallbackValue = "";
1680
+ if (variables[id]) {
1681
+ fallbackValue = variables[id].value;
1682
+ if (!variables[id]?.deleted) {
1683
+ name = variables[id].label;
1684
+ }
1685
+ }
1686
+ if (!name.trim()) {
1258
1687
  return null;
1259
1688
  }
1260
- return `var(--${value})`;
1689
+ if (!fallbackValue.trim()) {
1690
+ return `var(--${name})`;
1691
+ }
1692
+ return `var(--${name}, ${fallbackValue})`;
1261
1693
  });
1262
1694
 
1263
1695
  // src/init-color-variables.ts
1264
1696
  var { registerPopoverAction } = controlActionsMenu;
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() {
1697
+ function initColorVariables() {
1274
1698
  registerControlReplacement({
1275
1699
  component: ColorVariableControl,
1276
1700
  condition: ({ value }) => hasAssignedColorVariable(value)
@@ -1279,34 +1703,8 @@ function registerControlsAndActions() {
1279
1703
  id: "color-variables",
1280
1704
  useProps: usePropColorVariableAction
1281
1705
  });
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() {
1303
1706
  styleTransformersRegistry.register(colorVariablePropTypeUtil.key, variableTransformer);
1304
- }
1305
- function initColorVariables() {
1306
- registerControlsAndActions();
1307
- registerRepeaterItemIcons();
1308
- registerRepeaterItemLabels();
1309
- registerStyleTransformers();
1707
+ registerRepeaterInjections();
1310
1708
  }
1311
1709
 
1312
1710
  // src/init-font-variables.ts
@@ -1314,73 +1712,50 @@ import { styleTransformersRegistry as styleTransformersRegistry2 } from "@elemen
1314
1712
  import { controlActionsMenu as controlActionsMenu2, registerControlReplacement as registerControlReplacement2 } from "@elementor/editor-editing-panel";
1315
1713
 
1316
1714
  // src/controls/font-variable-control.tsx
1317
- import * as React15 from "react";
1318
- import { useId as useId3, useRef as useRef7 } from "react";
1319
- import { useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
1715
+ import * as React23 from "react";
1716
+ import { useBoundProp as useBoundProp11 } from "@elementor/editor-controls";
1320
1717
  import { stringPropTypeUtil } from "@elementor/editor-props";
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
1718
  var FontVariableControl = () => {
1324
- const { setValue: setFontFamily } = useBoundProp7();
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
- });
1332
- const selectedVariable = useVariable(variableValue);
1333
- if (!selectedVariable) {
1719
+ const { value: variableValue } = useBoundProp11(fontVariablePropTypeUtil);
1720
+ const assignedVariable = useVariable(variableValue);
1721
+ if (!assignedVariable) {
1334
1722
  throw new Error(`Global font variable ${variableValue} not found`);
1335
1723
  }
1336
- const unlinkVariable = () => {
1337
- setFontFamily(stringPropTypeUtil.create(selectedVariable.value));
1338
- };
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,
1724
+ const isVariableDeleted = assignedVariable?.deleted;
1725
+ if (isVariableDeleted) {
1726
+ return /* @__PURE__ */ React23.createElement(
1727
+ DeletedVariable,
1361
1728
  {
1362
- selectedVariable,
1363
- closePopover: popupState.close,
1364
- propTypeKey: fontVariablePropTypeUtil.key
1729
+ variable: assignedVariable,
1730
+ variablePropTypeUtil: fontVariablePropTypeUtil,
1731
+ fallbackPropTypeUtil: stringPropTypeUtil
1365
1732
  }
1366
- )
1367
- ));
1733
+ );
1734
+ }
1735
+ return /* @__PURE__ */ React23.createElement(
1736
+ AssignedVariable,
1737
+ {
1738
+ variable: assignedVariable,
1739
+ variablePropTypeUtil: fontVariablePropTypeUtil,
1740
+ fallbackPropTypeUtil: stringPropTypeUtil
1741
+ }
1742
+ );
1368
1743
  };
1369
1744
 
1370
1745
  // src/hooks/use-prop-font-variable-action.tsx
1371
- import * as React16 from "react";
1372
- import { useBoundProp as useBoundProp8 } from "@elementor/editor-editing-panel";
1373
- import { ColorFilterIcon as ColorFilterIcon6 } from "@elementor/icons";
1374
- import { __ as __12 } from "@wordpress/i18n";
1746
+ import * as React24 from "react";
1747
+ import { useBoundProp as useBoundProp12 } from "@elementor/editor-editing-panel";
1748
+ import { ColorFilterIcon as ColorFilterIcon5 } from "@elementor/icons";
1749
+ import { __ as __20 } from "@wordpress/i18n";
1375
1750
  var usePropFontVariableAction = () => {
1376
- const { propType } = useBoundProp8();
1751
+ const { propType } = useBoundProp12();
1377
1752
  const visible = !!propType && supportsFontVariables(propType);
1378
1753
  return {
1379
1754
  visible,
1380
- icon: ColorFilterIcon6,
1381
- title: __12("Variables", "elementor"),
1755
+ icon: ColorFilterIcon5,
1756
+ title: __20("Variables", "elementor"),
1382
1757
  content: ({ close: closePopover }) => {
1383
- return /* @__PURE__ */ React16.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1758
+ return /* @__PURE__ */ React24.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1384
1759
  }
1385
1760
  };
1386
1761
  };
@@ -1400,8 +1775,8 @@ function initFontVariables() {
1400
1775
  }
1401
1776
 
1402
1777
  // src/renderers/style-variables-renderer.tsx
1403
- import * as React17 from "react";
1404
- import { useEffect, useState as useState8 } from "react";
1778
+ import * as React25 from "react";
1779
+ import { useEffect, useState as useState12 } from "react";
1405
1780
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
1406
1781
  import { Portal } from "@elementor/ui";
1407
1782
 
@@ -1422,13 +1797,13 @@ function StyleVariablesRenderer() {
1422
1797
  }
1423
1798
  const cssVariables = convertToCssVariables(styleVariables);
1424
1799
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
1425
- return /* @__PURE__ */ React17.createElement(Portal, { container }, /* @__PURE__ */ React17.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
1800
+ return /* @__PURE__ */ React25.createElement(Portal, { container }, /* @__PURE__ */ React25.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
1426
1801
  }
1427
1802
  function usePortalContainer() {
1428
1803
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
1429
1804
  }
1430
1805
  function useStyleVariables() {
1431
- const [variables, setVariables] = useState8({});
1806
+ const [variables, setVariables] = useState12({});
1432
1807
  useEffect(() => {
1433
1808
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
1434
1809
  return () => {
@@ -1437,8 +1812,14 @@ function useStyleVariables() {
1437
1812
  }, []);
1438
1813
  return variables;
1439
1814
  }
1815
+ function cssVariableDeclaration(key, variable) {
1816
+ const variableName = variable?.deleted ? key : variable.label;
1817
+ const value = variable.value;
1818
+ return `--${variableName}:${value};`;
1819
+ }
1440
1820
  function convertToCssVariables(variables) {
1441
- return Object.entries(variables).map(([key, value]) => `--${key}:${value};`).join("");
1821
+ const listOfVariables = Object.entries(variables);
1822
+ return listOfVariables.map(([key, variable]) => cssVariableDeclaration(key, variable)).join("");
1442
1823
  }
1443
1824
 
1444
1825
  // src/init.ts