@elementor/editor-variables 0.16.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.
package/dist/index.mjs CHANGED
@@ -6,8 +6,8 @@ import { styleTransformersRegistry } from "@elementor/editor-canvas";
6
6
  import { controlActionsMenu, registerControlReplacement } from "@elementor/editor-editing-panel";
7
7
 
8
8
  // src/controls/color-variable-control.tsx
9
- import * as React19 from "react";
10
- import { useBoundProp as useBoundProp8 } from "@elementor/editor-controls";
9
+ import * as React20 from "react";
10
+ import { useBoundProp as useBoundProp9 } from "@elementor/editor-controls";
11
11
  import { colorPropTypeUtil } from "@elementor/editor-props";
12
12
 
13
13
  // src/components/ui/color-indicator.tsx
@@ -43,15 +43,18 @@ var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.strin
43
43
  import * as React3 from "react";
44
44
  import { useState as useState3 } from "react";
45
45
  import { PopoverContent, useBoundProp } from "@elementor/editor-controls";
46
- import { PopoverScrollableContent } from "@elementor/editor-editing-panel";
46
+ import { PopoverBody } from "@elementor/editor-editing-panel";
47
47
  import { PopoverHeader } from "@elementor/editor-ui";
48
48
  import { ArrowLeftIcon, BrushIcon } from "@elementor/icons";
49
- import { Button, CardActions, Divider, IconButton } from "@elementor/ui";
50
- import { __ as __4 } from "@wordpress/i18n";
49
+ import { Button, CardActions, Divider, FormHelperText as FormHelperText3, IconButton } from "@elementor/ui";
50
+ import { __ as __5 } from "@wordpress/i18n";
51
51
 
52
52
  // src/hooks/use-prop-variables.ts
53
53
  import { useMemo } from "react";
54
54
 
55
+ // src/service.ts
56
+ import { __ } from "@wordpress/i18n";
57
+
55
58
  // src/api.ts
56
59
  import { httpService } from "@elementor/http-client";
57
60
  var BASE_PATH = "elementor/v1/variables";
@@ -134,6 +137,12 @@ var Storage = class {
134
137
  }
135
138
  };
136
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
+
137
146
  // src/create-style-variables-repository.ts
138
147
  var createStyleVariablesRepository = () => {
139
148
  const variables = {};
@@ -150,19 +159,46 @@ var createStyleVariablesRepository = () => {
150
159
  subscription({ ...variables });
151
160
  }
152
161
  };
153
- const shouldUpdate = (key, newValue) => {
154
- 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;
155
179
  };
156
180
  const applyUpdates = (updatedVars) => {
157
181
  let hasChanges = false;
158
- for (const [key, { value }] of Object.entries(updatedVars)) {
159
- if (shouldUpdate(key, value)) {
160
- 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
+ }
161
188
  hasChanges = true;
162
189
  }
163
190
  }
164
191
  return hasChanges;
165
192
  };
193
+ const fontEnqueue = (value) => {
194
+ if (!value) {
195
+ return;
196
+ }
197
+ try {
198
+ enqueueFont(value);
199
+ } catch {
200
+ }
201
+ };
166
202
  const update = (updatedVars) => {
167
203
  if (applyUpdates(updatedVars)) {
168
204
  notify();
@@ -204,7 +240,8 @@ var service = {
204
240
  return apiClient.create(type, label, value).then((response) => {
205
241
  const { success, data: payload } = response.data;
206
242
  if (!success) {
207
- throw new Error("Unexpected response from server");
243
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
244
+ throw new Error(errorMessage);
208
245
  }
209
246
  return payload;
210
247
  }).then((data) => {
@@ -219,13 +256,17 @@ var service = {
219
256
  id: variableId,
220
257
  variable: createdVariable
221
258
  };
259
+ }).catch((error) => {
260
+ const message = getErrorMessage(error.response);
261
+ throw message ? new Error(message) : error;
222
262
  });
223
263
  },
224
264
  update: (id, { label, value }) => {
225
265
  return apiClient.update(id, label, value).then((response) => {
226
266
  const { success, data: payload } = response.data;
227
267
  if (!success) {
228
- throw new Error("Unexpected response from server");
268
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
269
+ throw new Error(errorMessage);
229
270
  }
230
271
  return payload;
231
272
  }).then((data) => {
@@ -240,6 +281,9 @@ var service = {
240
281
  id: variableId,
241
282
  variable: updatedVariable
242
283
  };
284
+ }).catch((error) => {
285
+ const message = getErrorMessage(error.response);
286
+ throw message ? new Error(message) : error;
243
287
  });
244
288
  },
245
289
  delete: (id) => {
@@ -291,6 +335,12 @@ var handleWatermark = (operation, newWatermark) => {
291
335
  }
292
336
  storage.watermark(newWatermark);
293
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
+ };
294
344
 
295
345
  // src/hooks/use-prop-variables.ts
296
346
  var useVariable = (key) => {
@@ -341,43 +391,48 @@ var deleteVariable = (deleteId) => {
341
391
  return id;
342
392
  });
343
393
  };
394
+ var restoreVariable = (restoreId) => {
395
+ return service.restore(restoreId).then(({ id }) => {
396
+ return id;
397
+ });
398
+ };
344
399
 
345
400
  // src/components/fields/color-field.tsx
346
401
  import * as React from "react";
347
402
  import { useRef, useState } from "react";
348
403
  import { FormHelperText, FormLabel, Grid, UnstableColorField } from "@elementor/ui";
349
- import { __ as __2 } from "@wordpress/i18n";
404
+ import { __ as __3 } from "@wordpress/i18n";
350
405
 
351
406
  // src/utils/validations.ts
352
- import { __ } from "@wordpress/i18n";
407
+ import { __ as __2 } from "@wordpress/i18n";
353
408
  var VARIABLE_LABEL_MAX_LENGTH = 50;
354
409
  var validateLabel = (name) => {
355
410
  if (!name.trim()) {
356
- return __("Missing variable name.", "elementor");
411
+ return __2("Give your variable a name.", "elementor");
357
412
  }
358
413
  const allowedChars = /^[a-zA-Z0-9_-]+$/;
359
414
  if (!allowedChars.test(name)) {
360
- return __("Names can only use letters, numbers, dashes (-) and underscores (_).", "elementor");
415
+ return __2("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor");
361
416
  }
362
417
  const hasAlphanumeric = /[a-zA-Z0-9]/;
363
418
  if (!hasAlphanumeric.test(name)) {
364
- return __("Names have to include at least one non-special character.", "elementor");
419
+ return __2("Names have to include at least one non-special character.", "elementor");
365
420
  }
366
421
  if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
367
- return __("Variable names can contain up to 50 characters.", "elementor");
422
+ return __2("Keep names up to 50 characters.", "elementor");
368
423
  }
369
424
  return "";
370
425
  };
371
426
  var labelHint = (name) => {
372
427
  const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
373
428
  if (hintThreshold < name.length) {
374
- return __("Variable names can contain up to 50 characters.", "elementor");
429
+ return __2("Keep names up to 50 characters.", "elementor");
375
430
  }
376
431
  return "";
377
432
  };
378
433
  var validateValue = (value) => {
379
434
  if (!value.trim()) {
380
- return __("Missing variable value.", "elementor");
435
+ return __2("Add a value to complete your variable.", "elementor");
381
436
  }
382
437
  return "";
383
438
  };
@@ -401,7 +456,7 @@ var ColorField = ({ value, onChange }) => {
401
456
  setErrorMessage(errorMsg);
402
457
  onChange(errorMsg ? "" : newValue);
403
458
  };
404
- 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" }, __2("Value", "elementor"))), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
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(
405
460
  UnstableColorField,
406
461
  {
407
462
  size: "tiny",
@@ -424,7 +479,7 @@ var ColorField = ({ value, onChange }) => {
424
479
  import * as React2 from "react";
425
480
  import { useId, useState as useState2 } from "react";
426
481
  import { FormHelperText as FormHelperText2, FormLabel as FormLabel2, Grid as Grid2, TextField } from "@elementor/ui";
427
- import { __ as __3 } from "@wordpress/i18n";
482
+ import { __ as __4 } from "@wordpress/i18n";
428
483
  var LabelField = ({ value, onChange }) => {
429
484
  const [label, setLabel] = useState2(value);
430
485
  const [errorMessage, setErrorMessage] = useState2("");
@@ -438,7 +493,7 @@ var LabelField = ({ value, onChange }) => {
438
493
  onChange(errorMsg ? "" : newValue);
439
494
  };
440
495
  const id = useId();
441
- 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" }, __3("Name", "elementor"))), /* @__PURE__ */ React2.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React2.createElement(
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(
442
497
  TextField,
443
498
  {
444
499
  id,
@@ -458,9 +513,11 @@ var ColorVariableCreation = ({ onGoBack, onClose }) => {
458
513
  const { setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
459
514
  const [color, setColor] = useState3("");
460
515
  const [label, setLabel] = useState3("");
516
+ const [errorMessage, setErrorMessage] = useState3("");
461
517
  const resetFields = () => {
462
518
  setColor("");
463
519
  setLabel("");
520
+ setErrorMessage("");
464
521
  };
465
522
  const closePopover = () => {
466
523
  resetFields();
@@ -474,31 +531,51 @@ var ColorVariableCreation = ({ onGoBack, onClose }) => {
474
531
  }).then((key) => {
475
532
  setVariable(key);
476
533
  closePopover();
534
+ }).catch((error) => {
535
+ setErrorMessage(error.message);
477
536
  });
478
537
  };
479
538
  const hasEmptyValue = () => {
480
539
  return "" === color.trim() || "" === label.trim();
481
540
  };
482
541
  const isSubmitDisabled = hasEmptyValue();
483
- return /* @__PURE__ */ React3.createElement(PopoverScrollableContent, { height: "auto" }, /* @__PURE__ */ React3.createElement(
542
+ return /* @__PURE__ */ React3.createElement(PopoverBody, { height: "auto" }, /* @__PURE__ */ React3.createElement(
484
543
  PopoverHeader,
485
544
  {
486
- icon: /* @__PURE__ */ React3.createElement(React3.Fragment, null, onGoBack && /* @__PURE__ */ React3.createElement(IconButton, { size: SIZE, "aria-label": __4("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React3.createElement(ArrowLeftIcon, { fontSize: SIZE })), /* @__PURE__ */ React3.createElement(BrushIcon, { fontSize: SIZE })),
487
- title: __4("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"),
488
547
  onClose: closePopover
489
548
  }
490
- ), /* @__PURE__ */ React3.createElement(Divider, null), /* @__PURE__ */ React3.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React3.createElement(LabelField, { value: label, onChange: setLabel }), /* @__PURE__ */ React3.createElement(ColorField, { value: color, onChange: setColor })), /* @__PURE__ */ React3.createElement(CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React3.createElement(Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreate }, __4("Create", "elementor"))));
549
+ ), /* @__PURE__ */ React3.createElement(Divider, null), /* @__PURE__ */ React3.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React3.createElement(
550
+ LabelField,
551
+ {
552
+ value: label,
553
+ onChange: (value) => {
554
+ setLabel(value);
555
+ setErrorMessage("");
556
+ }
557
+ }
558
+ ), /* @__PURE__ */ React3.createElement(
559
+ ColorField,
560
+ {
561
+ value: color,
562
+ onChange: (value) => {
563
+ setColor(value);
564
+ setErrorMessage("");
565
+ }
566
+ }
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"))));
491
568
  };
492
569
 
493
570
  // src/components/color-variable-edit.tsx
494
571
  import * as React5 from "react";
495
572
  import { useState as useState4 } from "react";
496
573
  import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
497
- import { PopoverScrollableContent as PopoverScrollableContent2 } from "@elementor/editor-editing-panel";
574
+ import { PopoverBody as PopoverBody2 } from "@elementor/editor-editing-panel";
498
575
  import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
499
576
  import { ArrowLeftIcon as ArrowLeftIcon2, BrushIcon as BrushIcon2, TrashIcon } from "@elementor/icons";
500
- import { Button as Button3, CardActions as CardActions2, Divider as Divider2, IconButton as IconButton2 } from "@elementor/ui";
501
- import { __ as __6 } from "@wordpress/i18n";
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";
502
579
 
503
580
  // src/components/ui/delete-confirmation-dialog.tsx
504
581
  import * as React4 from "react";
@@ -512,7 +589,7 @@ import {
512
589
  DialogTitle,
513
590
  Typography
514
591
  } from "@elementor/ui";
515
- import { __ as __5 } from "@wordpress/i18n";
592
+ import { __ as __6 } from "@wordpress/i18n";
516
593
  var TITLE_ID = "delete-variable-dialog";
517
594
  var DeleteConfirmationDialog = ({
518
595
  open,
@@ -520,10 +597,7 @@ var DeleteConfirmationDialog = ({
520
597
  closeDialog,
521
598
  onConfirm
522
599
  }) => {
523
- 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" }), __5("Delete Variable", "elementor")), /* @__PURE__ */ React4.createElement(DialogContent, null, /* @__PURE__ */ React4.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __5("You are about to delete", "elementor"), /* @__PURE__ */ React4.createElement(Typography, { variant: "subtitle2", component: "span" }, "\xA0", label, "\xA0"), __5(
524
- "Variable. Note that its value is still being used anywhere on your site where it was connected to the variable.",
525
- "elementor"
526
- ))), /* @__PURE__ */ React4.createElement(DialogActions, null, /* @__PURE__ */ React4.createElement(Button2, { color: "secondary", onClick: closeDialog }, __5("Cancel", "elementor")), /* @__PURE__ */ React4.createElement(Button2, { variant: "contained", color: "error", onClick: onConfirm }, __5("Delete", "elementor"))));
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"))));
527
601
  };
528
602
 
529
603
  // src/components/color-variable-edit.tsx
@@ -531,6 +605,7 @@ var SIZE2 = "tiny";
531
605
  var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
532
606
  const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp2(colorVariablePropTypeUtil);
533
607
  const [deleteConfirmation, setDeleteConfirmation] = useState4(false);
608
+ const [errorMessage, setErrorMessage] = useState4("");
534
609
  const variable = useVariable(editId);
535
610
  if (!variable) {
536
611
  throw new Error(`Global color variable not found`);
@@ -544,6 +619,8 @@ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
544
619
  }).then(() => {
545
620
  maybeTriggerBoundPropChange();
546
621
  onSubmit?.();
622
+ }).catch((error) => {
623
+ setErrorMessage(error.message);
547
624
  });
548
625
  };
549
626
  const handleDelete = () => {
@@ -570,7 +647,7 @@ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
570
647
  {
571
648
  key: "delete",
572
649
  size: SIZE2,
573
- "aria-label": __6("Delete", "elementor"),
650
+ "aria-label": __7("Delete", "elementor"),
574
651
  onClick: handleDeleteConfirmation
575
652
  },
576
653
  /* @__PURE__ */ React5.createElement(TrashIcon, { fontSize: SIZE2 })
@@ -583,23 +660,41 @@ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
583
660
  return color === variable.value && label === variable.label;
584
661
  };
585
662
  const isSubmitDisabled = noValueChanged() || hasEmptyValues();
586
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(PopoverScrollableContent2, { height: "auto" }, /* @__PURE__ */ React5.createElement(
663
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(PopoverBody2, { height: "auto" }, /* @__PURE__ */ React5.createElement(
587
664
  PopoverHeader2,
588
665
  {
589
- title: __6("Edit variable", "elementor"),
666
+ title: __7("Edit variable", "elementor"),
590
667
  onClose,
591
668
  icon: /* @__PURE__ */ React5.createElement(React5.Fragment, null, onGoBack && /* @__PURE__ */ React5.createElement(
592
669
  IconButton2,
593
670
  {
594
671
  size: SIZE2,
595
- "aria-label": __6("Go Back", "elementor"),
672
+ "aria-label": __7("Go Back", "elementor"),
596
673
  onClick: onGoBack
597
674
  },
598
675
  /* @__PURE__ */ React5.createElement(ArrowLeftIcon2, { fontSize: SIZE2 })
599
676
  ), /* @__PURE__ */ React5.createElement(BrushIcon2, { fontSize: SIZE2 })),
600
677
  actions
601
678
  }
602
- ), /* @__PURE__ */ React5.createElement(Divider2, null), /* @__PURE__ */ React5.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React5.createElement(LabelField, { value: label, onChange: setLabel }), /* @__PURE__ */ React5.createElement(ColorField, { value: color, onChange: setColor })), /* @__PURE__ */ React5.createElement(CardActions2, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React5.createElement(Button3, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __6("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React5.createElement(
679
+ ), /* @__PURE__ */ React5.createElement(Divider2, null), /* @__PURE__ */ React5.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React5.createElement(
680
+ LabelField,
681
+ {
682
+ value: label,
683
+ onChange: (value) => {
684
+ setLabel(value);
685
+ setErrorMessage("");
686
+ }
687
+ }
688
+ ), /* @__PURE__ */ React5.createElement(
689
+ ColorField,
690
+ {
691
+ value: color,
692
+ onChange: (value) => {
693
+ setColor(value);
694
+ setErrorMessage("");
695
+ }
696
+ }
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(
603
698
  DeleteConfirmationDialog,
604
699
  {
605
700
  open: true,
@@ -614,18 +709,18 @@ var ColorVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
614
709
  import * as React9 from "react";
615
710
  import { useState as useState5 } from "react";
616
711
  import { useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
617
- import { PopoverScrollableContent as PopoverScrollableContent3 } from "@elementor/editor-editing-panel";
712
+ import { PopoverBody as PopoverBody3 } from "@elementor/editor-editing-panel";
618
713
  import { PopoverHeader as PopoverHeader3, PopoverMenuList, PopoverSearch } from "@elementor/editor-ui";
619
714
  import { BrushIcon as BrushIcon3, ColorFilterIcon, PlusIcon, SettingsIcon } from "@elementor/icons";
620
715
  import { Divider as Divider3, IconButton as IconButton4 } from "@elementor/ui";
621
- import { __ as __10 } from "@wordpress/i18n";
716
+ import { __ as __11 } from "@wordpress/i18n";
622
717
 
623
718
  // src/components/ui/menu-item-content.tsx
624
719
  import * as React6 from "react";
625
720
  import { EllipsisWithTooltip } from "@elementor/editor-ui";
626
721
  import { EditIcon } from "@elementor/icons";
627
722
  import { Box, IconButton as IconButton3, ListItemIcon, Typography as Typography2 } from "@elementor/ui";
628
- import { __ as __7 } from "@wordpress/i18n";
723
+ import { __ as __8 } from "@wordpress/i18n";
629
724
  var SIZE3 = "tiny";
630
725
  var MenuItemContent = ({ item }) => {
631
726
  const onEdit = item.onEdit;
@@ -670,7 +765,7 @@ var MenuItemContent = ({ item }) => {
670
765
  e.stopPropagation();
671
766
  onEdit(item.value);
672
767
  },
673
- "aria-label": __7("Edit", "elementor")
768
+ "aria-label": __8("Edit", "elementor")
674
769
  },
675
770
  /* @__PURE__ */ React6.createElement(EditIcon, { color: "action", fontSize: SIZE3 })
676
771
  ));
@@ -679,7 +774,7 @@ var MenuItemContent = ({ item }) => {
679
774
  // src/components/ui/no-search-results.tsx
680
775
  import * as React7 from "react";
681
776
  import { Link, Stack, Typography as Typography3 } from "@elementor/ui";
682
- import { __ as __8 } from "@wordpress/i18n";
777
+ import { __ as __9 } from "@wordpress/i18n";
683
778
  var NoSearchResults = ({ searchValue, onClear, icon }) => {
684
779
  return /* @__PURE__ */ React7.createElement(
685
780
  Stack,
@@ -693,15 +788,15 @@ var NoSearchResults = ({ searchValue, onClear, icon }) => {
693
788
  sx: { pb: 3.5 }
694
789
  },
695
790
  icon,
696
- /* @__PURE__ */ React7.createElement(Typography3, { align: "center", variant: "subtitle2" }, __8("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React7.createElement("br", null), "\u201C", searchValue, "\u201D."),
697
- /* @__PURE__ */ React7.createElement(Typography3, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, __8("Try something else.", "elementor"), /* @__PURE__ */ React7.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __8("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")))
698
793
  );
699
794
  };
700
795
 
701
796
  // src/components/ui/no-variables.tsx
702
797
  import * as React8 from "react";
703
798
  import { Button as Button4, Stack as Stack2, Typography as Typography4 } from "@elementor/ui";
704
- import { __ as __9 } from "@wordpress/i18n";
799
+ import { __ as __10 } from "@wordpress/i18n";
705
800
  var NoVariables = ({ icon, title, onAdd }) => /* @__PURE__ */ React8.createElement(
706
801
  Stack2,
707
802
  {
@@ -714,8 +809,8 @@ var NoVariables = ({ icon, title, onAdd }) => /* @__PURE__ */ React8.createEleme
714
809
  },
715
810
  icon,
716
811
  /* @__PURE__ */ React8.createElement(Typography4, { align: "center", variant: "subtitle2" }, title),
717
- /* @__PURE__ */ React8.createElement(Typography4, { align: "center", variant: "caption", maxWidth: "180px" }, __9("Variables are saved attributes that you can apply anywhere on your site.", "elementor")),
718
- onAdd && /* @__PURE__ */ React8.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __9("Create a variable", "elementor"))
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"))
719
814
  );
720
815
 
721
816
  // src/components/ui/styled-menu-list.tsx
@@ -789,10 +884,10 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
789
884
  const handleClearSearch = () => {
790
885
  setSearchValue("");
791
886
  };
792
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
887
+ return /* @__PURE__ */ React9.createElement(PopoverBody3, null, /* @__PURE__ */ React9.createElement(
793
888
  PopoverHeader3,
794
889
  {
795
- title: __10("Variables", "elementor"),
890
+ title: __11("Variables", "elementor"),
796
891
  icon: /* @__PURE__ */ React9.createElement(ColorFilterIcon, { fontSize: SIZE4 }),
797
892
  onClose: closePopover,
798
893
  actions
@@ -802,9 +897,9 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
802
897
  {
803
898
  value: searchValue,
804
899
  onSearch: handleSearch,
805
- placeholder: __10("Search", "elementor")
900
+ placeholder: __11("Search", "elementor")
806
901
  }
807
- ), /* @__PURE__ */ React9.createElement(Divider3, null), /* @__PURE__ */ React9.createElement(PopoverScrollableContent3, null, hasVariables && hasSearchResults && /* @__PURE__ */ React9.createElement(
902
+ ), /* @__PURE__ */ React9.createElement(Divider3, null), hasVariables && hasSearchResults && /* @__PURE__ */ React9.createElement(
808
903
  PopoverMenuList,
809
904
  {
810
905
  items,
@@ -826,22 +921,22 @@ var ColorVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
826
921
  ), !hasVariables && /* @__PURE__ */ React9.createElement(
827
922
  NoVariables,
828
923
  {
829
- title: __10("Create your first color variable", "elementor"),
924
+ title: __11("Create your first color variable", "elementor"),
830
925
  icon: /* @__PURE__ */ React9.createElement(BrushIcon3, { fontSize: "large" }),
831
926
  onAdd
832
927
  }
833
- )));
928
+ ));
834
929
  };
835
930
 
836
931
  // src/components/font-variable-creation.tsx
837
932
  import * as React11 from "react";
838
933
  import { useState as useState7 } from "react";
839
934
  import { PopoverContent as PopoverContent3, useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
840
- import { PopoverScrollableContent as PopoverScrollableContent4 } from "@elementor/editor-editing-panel";
935
+ import { PopoverBody as PopoverBody4 } from "@elementor/editor-editing-panel";
841
936
  import { PopoverHeader as PopoverHeader4 } from "@elementor/editor-ui";
842
937
  import { ArrowLeftIcon as ArrowLeftIcon3, TextIcon } from "@elementor/icons";
843
- import { Button as Button5, CardActions as CardActions3, Divider as Divider4, IconButton as IconButton5 } from "@elementor/ui";
844
- import { __ as __12 } from "@wordpress/i18n";
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";
845
940
 
846
941
  // src/components/fields/font-field.tsx
847
942
  import * as React10 from "react";
@@ -852,14 +947,14 @@ import { ChevronDownIcon } from "@elementor/icons";
852
947
  import {
853
948
  bindPopover,
854
949
  bindTrigger,
855
- FormHelperText as FormHelperText3,
950
+ FormHelperText as FormHelperText5,
856
951
  FormLabel as FormLabel3,
857
952
  Grid as Grid3,
858
953
  Popover,
859
954
  UnstableTag,
860
955
  usePopupState
861
956
  } from "@elementor/ui";
862
- import { __ as __11 } from "@wordpress/i18n";
957
+ import { __ as __12 } from "@wordpress/i18n";
863
958
  var FontField = ({ value, onChange }) => {
864
959
  const [fontFamily, setFontFamily] = useState6(value);
865
960
  const [errorMessage, setErrorMessage] = useState6("");
@@ -878,7 +973,7 @@ var FontField = ({ value, onChange }) => {
878
973
  handleChange(newFontFamily);
879
974
  fontPopoverState.close();
880
975
  };
881
- 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" }, __11("Value", "elementor"))), /* @__PURE__ */ React10.createElement(Grid3, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(
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(
882
977
  UnstableTag,
883
978
  {
884
979
  variant: "outlined",
@@ -907,7 +1002,7 @@ var FontField = ({ value, onChange }) => {
907
1002
  sectionWidth
908
1003
  }
909
1004
  )
910
- ), errorMessage && /* @__PURE__ */ React10.createElement(FormHelperText3, { error: true }, errorMessage)));
1005
+ ), errorMessage && /* @__PURE__ */ React10.createElement(FormHelperText5, { error: true }, errorMessage)));
911
1006
  };
912
1007
 
913
1008
  // src/components/font-variable-creation.tsx
@@ -916,9 +1011,11 @@ var FontVariableCreation = ({ onClose, onGoBack }) => {
916
1011
  const { setValue: setVariable } = useBoundProp4(fontVariablePropTypeUtil);
917
1012
  const [fontFamily, setFontFamily] = useState7("");
918
1013
  const [label, setLabel] = useState7("");
1014
+ const [errorMessage, setErrorMessage] = useState7("");
919
1015
  const resetFields = () => {
920
1016
  setFontFamily("");
921
1017
  setLabel("");
1018
+ setErrorMessage("");
922
1019
  };
923
1020
  const closePopover = () => {
924
1021
  resetFields();
@@ -932,35 +1029,56 @@ var FontVariableCreation = ({ onClose, onGoBack }) => {
932
1029
  }).then((key) => {
933
1030
  setVariable(key);
934
1031
  closePopover();
1032
+ }).catch((error) => {
1033
+ setErrorMessage(error.message);
935
1034
  });
936
1035
  };
937
1036
  const hasEmptyValue = () => {
938
1037
  return "" === fontFamily.trim() || "" === label.trim();
939
1038
  };
940
1039
  const isSubmitDisabled = hasEmptyValue();
941
- return /* @__PURE__ */ React11.createElement(PopoverScrollableContent4, { height: "auto" }, /* @__PURE__ */ React11.createElement(
1040
+ return /* @__PURE__ */ React11.createElement(PopoverBody4, { height: "auto" }, /* @__PURE__ */ React11.createElement(
942
1041
  PopoverHeader4,
943
1042
  {
944
- icon: /* @__PURE__ */ React11.createElement(React11.Fragment, null, onGoBack && /* @__PURE__ */ React11.createElement(IconButton5, { size: SIZE5, "aria-label": __12("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React11.createElement(ArrowLeftIcon3, { fontSize: SIZE5 })), /* @__PURE__ */ React11.createElement(TextIcon, { fontSize: SIZE5 })),
945
- title: __12("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"),
946
1045
  onClose: closePopover
947
1046
  }
948
- ), /* @__PURE__ */ React11.createElement(Divider4, null), /* @__PURE__ */ React11.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React11.createElement(LabelField, { value: label, onChange: setLabel }), /* @__PURE__ */ React11.createElement(FontField, { value: fontFamily, onChange: setFontFamily })), /* @__PURE__ */ React11.createElement(CardActions3, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React11.createElement(Button5, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreate }, __12("Create", "elementor"))));
1047
+ ), /* @__PURE__ */ React11.createElement(Divider4, null), /* @__PURE__ */ React11.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React11.createElement(
1048
+ LabelField,
1049
+ {
1050
+ value: label,
1051
+ onChange: (value) => {
1052
+ setLabel(value);
1053
+ setErrorMessage("");
1054
+ }
1055
+ }
1056
+ ), /* @__PURE__ */ React11.createElement(
1057
+ FontField,
1058
+ {
1059
+ value: fontFamily,
1060
+ onChange: (value) => {
1061
+ setFontFamily(value);
1062
+ setErrorMessage("");
1063
+ }
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"))));
949
1066
  };
950
1067
 
951
1068
  // src/components/font-variable-edit.tsx
952
1069
  import * as React12 from "react";
953
1070
  import { useState as useState8 } from "react";
954
1071
  import { PopoverContent as PopoverContent4, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
955
- import { PopoverScrollableContent as PopoverScrollableContent5 } from "@elementor/editor-editing-panel";
1072
+ import { PopoverBody as PopoverBody5 } from "@elementor/editor-editing-panel";
956
1073
  import { PopoverHeader as PopoverHeader5 } from "@elementor/editor-ui";
957
1074
  import { ArrowLeftIcon as ArrowLeftIcon4, TextIcon as TextIcon2, TrashIcon as TrashIcon2 } from "@elementor/icons";
958
- import { Button as Button6, CardActions as CardActions4, Divider as Divider5, IconButton as IconButton6 } from "@elementor/ui";
959
- import { __ as __13 } from "@wordpress/i18n";
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";
960
1077
  var SIZE6 = "tiny";
961
1078
  var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
962
1079
  const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp5(fontVariablePropTypeUtil);
963
1080
  const [deleteConfirmation, setDeleteConfirmation] = useState8(false);
1081
+ const [errorMessage, setErrorMessage] = useState8("");
964
1082
  const variable = useVariable(editId);
965
1083
  if (!variable) {
966
1084
  throw new Error(`Global font variable "${editId}" not found`);
@@ -974,6 +1092,8 @@ var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
974
1092
  }).then(() => {
975
1093
  maybeTriggerBoundPropChange();
976
1094
  onSubmit?.();
1095
+ }).catch((error) => {
1096
+ setErrorMessage(error.message);
977
1097
  });
978
1098
  };
979
1099
  const handleDelete = () => {
@@ -1007,29 +1127,47 @@ var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1007
1127
  {
1008
1128
  key: "delete",
1009
1129
  size: SIZE6,
1010
- "aria-label": __13("Delete", "elementor"),
1130
+ "aria-label": __14("Delete", "elementor"),
1011
1131
  onClick: handleDeleteConfirmation
1012
1132
  },
1013
1133
  /* @__PURE__ */ React12.createElement(TrashIcon2, { fontSize: SIZE6 })
1014
1134
  )
1015
1135
  );
1016
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(PopoverScrollableContent5, { height: "auto" }, /* @__PURE__ */ React12.createElement(
1136
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(PopoverBody5, { height: "auto" }, /* @__PURE__ */ React12.createElement(
1017
1137
  PopoverHeader5,
1018
1138
  {
1019
1139
  icon: /* @__PURE__ */ React12.createElement(React12.Fragment, null, onGoBack && /* @__PURE__ */ React12.createElement(
1020
1140
  IconButton6,
1021
1141
  {
1022
1142
  size: SIZE6,
1023
- "aria-label": __13("Go Back", "elementor"),
1143
+ "aria-label": __14("Go Back", "elementor"),
1024
1144
  onClick: onGoBack
1025
1145
  },
1026
1146
  /* @__PURE__ */ React12.createElement(ArrowLeftIcon4, { fontSize: SIZE6 })
1027
1147
  ), /* @__PURE__ */ React12.createElement(TextIcon2, { fontSize: SIZE6 })),
1028
- title: __13("Edit variable", "elementor"),
1148
+ title: __14("Edit variable", "elementor"),
1029
1149
  onClose,
1030
1150
  actions
1031
1151
  }
1032
- ), /* @__PURE__ */ React12.createElement(Divider5, null), /* @__PURE__ */ React12.createElement(PopoverContent4, { p: 2 }, /* @__PURE__ */ React12.createElement(LabelField, { value: label, onChange: setLabel }), /* @__PURE__ */ React12.createElement(FontField, { value: fontFamily, onChange: setFontFamily })), /* @__PURE__ */ React12.createElement(CardActions4, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React12.createElement(Button6, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __13("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React12.createElement(
1152
+ ), /* @__PURE__ */ React12.createElement(Divider5, null), /* @__PURE__ */ React12.createElement(PopoverContent4, { p: 2 }, /* @__PURE__ */ React12.createElement(
1153
+ LabelField,
1154
+ {
1155
+ value: label,
1156
+ onChange: (value) => {
1157
+ setLabel(value);
1158
+ setErrorMessage("");
1159
+ }
1160
+ }
1161
+ ), /* @__PURE__ */ React12.createElement(
1162
+ FontField,
1163
+ {
1164
+ value: fontFamily,
1165
+ onChange: (value) => {
1166
+ setFontFamily(value);
1167
+ setErrorMessage("");
1168
+ }
1169
+ }
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(
1033
1171
  DeleteConfirmationDialog,
1034
1172
  {
1035
1173
  open: true,
@@ -1044,11 +1182,11 @@ var FontVariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1044
1182
  import * as React13 from "react";
1045
1183
  import { useState as useState9 } from "react";
1046
1184
  import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
1047
- import { PopoverScrollableContent as PopoverScrollableContent6 } from "@elementor/editor-editing-panel";
1185
+ import { PopoverBody as PopoverBody6 } from "@elementor/editor-editing-panel";
1048
1186
  import { PopoverHeader as PopoverHeader6, PopoverMenuList as PopoverMenuList2, PopoverSearch as PopoverSearch2 } from "@elementor/editor-ui";
1049
1187
  import { ColorFilterIcon as ColorFilterIcon2, PlusIcon as PlusIcon2, SettingsIcon as SettingsIcon2, TextIcon as TextIcon3 } from "@elementor/icons";
1050
1188
  import { Divider as Divider6, IconButton as IconButton7 } from "@elementor/ui";
1051
- import { __ as __14 } from "@wordpress/i18n";
1189
+ import { __ as __15 } from "@wordpress/i18n";
1052
1190
  var SIZE7 = "tiny";
1053
1191
  var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1054
1192
  const { value: variable, setValue: setVariable } = useBoundProp6(fontVariablePropTypeUtil);
@@ -1087,10 +1225,10 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1087
1225
  const handleClearSearch = () => {
1088
1226
  setSearchValue("");
1089
1227
  };
1090
- return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
1228
+ return /* @__PURE__ */ React13.createElement(PopoverBody6, null, /* @__PURE__ */ React13.createElement(
1091
1229
  PopoverHeader6,
1092
1230
  {
1093
- title: __14("Variables", "elementor"),
1231
+ title: __15("Variables", "elementor"),
1094
1232
  onClose: closePopover,
1095
1233
  icon: /* @__PURE__ */ React13.createElement(ColorFilterIcon2, { fontSize: SIZE7 }),
1096
1234
  actions
@@ -1100,9 +1238,9 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1100
1238
  {
1101
1239
  value: searchValue,
1102
1240
  onSearch: handleSearch,
1103
- placeholder: __14("Search", "elementor")
1241
+ placeholder: __15("Search", "elementor")
1104
1242
  }
1105
- ), /* @__PURE__ */ React13.createElement(Divider6, null), /* @__PURE__ */ React13.createElement(PopoverScrollableContent6, null, hasVariables && hasSearchResults && /* @__PURE__ */ React13.createElement(
1243
+ ), /* @__PURE__ */ React13.createElement(Divider6, null), hasVariables && hasSearchResults && /* @__PURE__ */ React13.createElement(
1106
1244
  PopoverMenuList2,
1107
1245
  {
1108
1246
  items,
@@ -1124,11 +1262,11 @@ var FontVariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1124
1262
  ), !hasVariables && /* @__PURE__ */ React13.createElement(
1125
1263
  NoVariables,
1126
1264
  {
1127
- title: __14("Create your first font variable", "elementor"),
1265
+ title: __15("Create your first font variable", "elementor"),
1128
1266
  icon: /* @__PURE__ */ React13.createElement(TextIcon3, { fontSize: "large" }),
1129
1267
  onAdd
1130
1268
  }
1131
- )));
1269
+ ));
1132
1270
  };
1133
1271
 
1134
1272
  // src/components/variable-selection-popover.tsx
@@ -1236,17 +1374,17 @@ function renderStage(props) {
1236
1374
  // src/components/ui/tags/assigned-tag.tsx
1237
1375
  import * as React15 from "react";
1238
1376
  import { DetachIcon } from "@elementor/icons";
1239
- import { Box as Box3, IconButton as IconButton8, Stack as Stack3, Typography as Typography5, UnstableTag as Tag } from "@elementor/ui";
1240
- import { __ as __15 } from "@wordpress/i18n";
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";
1241
1379
  var SIZE8 = "tiny";
1242
1380
  var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1243
1381
  const actions = [];
1244
1382
  if (onUnlink) {
1245
1383
  actions.push(
1246
- /* @__PURE__ */ React15.createElement(IconButton8, { key: "unlink", size: SIZE8, onClick: onUnlink, "aria-label": __15("Unlink", "elementor") }, /* @__PURE__ */ React15.createElement(DetachIcon, { fontSize: SIZE8 }))
1384
+ /* @__PURE__ */ React15.createElement(IconButton8, { key: "unlink", size: SIZE8, onClick: onUnlink, "aria-label": __16("Unlink", "elementor") }, /* @__PURE__ */ React15.createElement(DetachIcon, { fontSize: SIZE8 }))
1247
1385
  );
1248
1386
  }
1249
- return /* @__PURE__ */ React15.createElement(
1387
+ return /* @__PURE__ */ React15.createElement(Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React15.createElement(
1250
1388
  Tag,
1251
1389
  {
1252
1390
  fullWidth: true,
@@ -1256,7 +1394,7 @@ var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1256
1394
  actions,
1257
1395
  ...props
1258
1396
  }
1259
- );
1397
+ ));
1260
1398
  };
1261
1399
 
1262
1400
  // src/components/ui/variable/assigned-variable.tsx
@@ -1308,61 +1446,154 @@ var AssignedVariable = ({
1308
1446
  };
1309
1447
 
1310
1448
  // src/components/ui/variable/deleted-variable.tsx
1311
- import * as React18 from "react";
1312
- import { useRef as useRef5 } from "react";
1313
- import { Box as Box6 } from "@elementor/ui";
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";
1314
1454
 
1315
- // src/components/ui/tags/deleted-tag.tsx
1455
+ // src/components/ui/deleted-variable-alert.tsx
1316
1456
  import * as React17 from "react";
1317
- import { ColorFilterIcon as ColorFilterIcon4 } from "@elementor/icons";
1318
- import { Box as Box5, Typography as Typography6, UnstableTag as Tag2 } from "@elementor/ui";
1319
- import { __ as __16 } from "@wordpress/i18n";
1320
- var DeletedTag = ({ label }) => {
1321
- return /* @__PURE__ */ React17.createElement(
1322
- Tag2,
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,
1323
1464
  {
1324
- showActionsOnHover: true,
1325
- fullWidth: true,
1326
- label: /* @__PURE__ */ React17.createElement(Box5, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React17.createElement(Typography6, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
1327
- startIcon: /* @__PURE__ */ React17.createElement(ColorFilterIcon4, { fontSize: "tiny" }),
1328
- endAdornment: /* @__PURE__ */ React17.createElement(Typography6, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, "(", __16("deleted", "elementor"), ")")
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
1329
1508
  }
1330
1509
  );
1331
- };
1510
+ });
1332
1511
 
1333
1512
  // src/components/ui/variable/deleted-variable.tsx
1334
- var DeletedVariable = ({ variable }) => {
1335
- const anchorRef = useRef5(null);
1336
- return /* @__PURE__ */ React18.createElement(Box6, { ref: anchorRef }, /* @__PURE__ */ React18.createElement(DeletedTag, { label: variable.label }));
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
+ ));
1337
1561
  };
1338
1562
 
1339
1563
  // src/controls/color-variable-control.tsx
1340
1564
  var ColorVariableControl = () => {
1341
- const { value: variableValue } = useBoundProp8(colorVariablePropTypeUtil);
1565
+ const { value: variableValue } = useBoundProp9(colorVariablePropTypeUtil);
1342
1566
  const assignedVariable = useVariable(variableValue);
1343
1567
  if (!assignedVariable) {
1344
1568
  throw new Error(`Global color variable ${variableValue} not found`);
1345
1569
  }
1346
1570
  const isVariableDeleted = assignedVariable?.deleted;
1347
1571
  if (isVariableDeleted) {
1348
- return /* @__PURE__ */ React19.createElement(DeletedVariable, { variable: assignedVariable });
1572
+ return /* @__PURE__ */ React20.createElement(
1573
+ DeletedVariable,
1574
+ {
1575
+ variable: assignedVariable,
1576
+ variablePropTypeUtil: colorVariablePropTypeUtil,
1577
+ fallbackPropTypeUtil: colorPropTypeUtil
1578
+ }
1579
+ );
1349
1580
  }
1350
- return /* @__PURE__ */ React19.createElement(
1581
+ return /* @__PURE__ */ React20.createElement(
1351
1582
  AssignedVariable,
1352
1583
  {
1353
1584
  variable: assignedVariable,
1354
1585
  variablePropTypeUtil: colorVariablePropTypeUtil,
1355
1586
  fallbackPropTypeUtil: colorPropTypeUtil,
1356
- additionalStartIcon: /* @__PURE__ */ React19.createElement(ColorIndicator, { size: "inherit", value: assignedVariable.value, component: "span" })
1587
+ additionalStartIcon: /* @__PURE__ */ React20.createElement(ColorIndicator, { size: "inherit", value: assignedVariable.value, component: "span" })
1357
1588
  }
1358
1589
  );
1359
1590
  };
1360
1591
 
1361
1592
  // src/hooks/use-prop-color-variable-action.tsx
1362
- import * as React20 from "react";
1363
- import { useBoundProp as useBoundProp9 } from "@elementor/editor-editing-panel";
1364
- import { ColorFilterIcon as ColorFilterIcon5 } from "@elementor/icons";
1365
- import { __ as __17 } from "@wordpress/i18n";
1593
+ import * as React21 from "react";
1594
+ import { useBoundProp as useBoundProp10 } from "@elementor/editor-editing-panel";
1595
+ import { ColorFilterIcon as ColorFilterIcon4 } from "@elementor/icons";
1596
+ import { __ as __19 } from "@wordpress/i18n";
1366
1597
 
1367
1598
  // src/utils.ts
1368
1599
  var hasAssignedColorVariable = (propValue) => {
@@ -1380,14 +1611,14 @@ var supportsFontVariables = (propType) => {
1380
1611
 
1381
1612
  // src/hooks/use-prop-color-variable-action.tsx
1382
1613
  var usePropColorVariableAction = () => {
1383
- const { propType } = useBoundProp9();
1614
+ const { propType } = useBoundProp10();
1384
1615
  const visible = !!propType && supportsColorVariables(propType);
1385
1616
  return {
1386
1617
  visible,
1387
- icon: ColorFilterIcon5,
1388
- title: __17("Variables", "elementor"),
1618
+ icon: ColorFilterIcon4,
1619
+ title: __19("Variables", "elementor"),
1389
1620
  content: ({ close: closePopover }) => {
1390
- return /* @__PURE__ */ React20.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1621
+ return /* @__PURE__ */ React21.createElement(VariableSelectionPopover, { closePopover, propTypeKey: colorVariablePropTypeUtil.key });
1391
1622
  }
1392
1623
  };
1393
1624
  };
@@ -1397,22 +1628,22 @@ import { injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel } from "@elemen
1397
1628
  import { backgroundColorOverlayPropTypeUtil, shadowPropTypeUtil } from "@elementor/editor-props";
1398
1629
 
1399
1630
  // src/components/variables-repeater-item-slot.tsx
1400
- import * as React21 from "react";
1631
+ import * as React22 from "react";
1401
1632
  var useColorVariable = (value) => {
1402
1633
  const variableId = value?.value?.color?.value;
1403
1634
  return useVariable(variableId || "");
1404
1635
  };
1405
1636
  var BackgroundRepeaterColorIndicator = ({ value }) => {
1406
1637
  const colorVariable = useColorVariable(value);
1407
- return /* @__PURE__ */ React21.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1638
+ return /* @__PURE__ */ React22.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1408
1639
  };
1409
1640
  var BackgroundRepeaterLabel = ({ value }) => {
1410
1641
  const colorVariable = useColorVariable(value);
1411
- return /* @__PURE__ */ React21.createElement("span", null, colorVariable?.label);
1642
+ return /* @__PURE__ */ React22.createElement("span", null, colorVariable?.label);
1412
1643
  };
1413
1644
  var BoxShadowRepeaterColorIndicator = ({ value }) => {
1414
1645
  const colorVariable = useColorVariable(value);
1415
- return /* @__PURE__ */ React21.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1646
+ return /* @__PURE__ */ React22.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
1416
1647
  };
1417
1648
 
1418
1649
  // src/repeater-injections.ts
@@ -1442,11 +1673,23 @@ function registerRepeaterInjections() {
1442
1673
 
1443
1674
  // src/transformers/variable-transformer.ts
1444
1675
  import { createTransformer } from "@elementor/editor-canvas";
1445
- var variableTransformer = createTransformer((value) => {
1446
- 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()) {
1447
1687
  return null;
1448
1688
  }
1449
- return `var(--${value})`;
1689
+ if (!fallbackValue.trim()) {
1690
+ return `var(--${name})`;
1691
+ }
1692
+ return `var(--${name}, ${fallbackValue})`;
1450
1693
  });
1451
1694
 
1452
1695
  // src/init-color-variables.ts
@@ -1469,20 +1712,27 @@ import { styleTransformersRegistry as styleTransformersRegistry2 } from "@elemen
1469
1712
  import { controlActionsMenu as controlActionsMenu2, registerControlReplacement as registerControlReplacement2 } from "@elementor/editor-editing-panel";
1470
1713
 
1471
1714
  // src/controls/font-variable-control.tsx
1472
- import * as React22 from "react";
1473
- import { useBoundProp as useBoundProp10 } from "@elementor/editor-controls";
1715
+ import * as React23 from "react";
1716
+ import { useBoundProp as useBoundProp11 } from "@elementor/editor-controls";
1474
1717
  import { stringPropTypeUtil } from "@elementor/editor-props";
1475
1718
  var FontVariableControl = () => {
1476
- const { value: variableValue } = useBoundProp10(fontVariablePropTypeUtil);
1719
+ const { value: variableValue } = useBoundProp11(fontVariablePropTypeUtil);
1477
1720
  const assignedVariable = useVariable(variableValue);
1478
1721
  if (!assignedVariable) {
1479
1722
  throw new Error(`Global font variable ${variableValue} not found`);
1480
1723
  }
1481
1724
  const isVariableDeleted = assignedVariable?.deleted;
1482
1725
  if (isVariableDeleted) {
1483
- return /* @__PURE__ */ React22.createElement(DeletedVariable, { variable: assignedVariable });
1726
+ return /* @__PURE__ */ React23.createElement(
1727
+ DeletedVariable,
1728
+ {
1729
+ variable: assignedVariable,
1730
+ variablePropTypeUtil: fontVariablePropTypeUtil,
1731
+ fallbackPropTypeUtil: stringPropTypeUtil
1732
+ }
1733
+ );
1484
1734
  }
1485
- return /* @__PURE__ */ React22.createElement(
1735
+ return /* @__PURE__ */ React23.createElement(
1486
1736
  AssignedVariable,
1487
1737
  {
1488
1738
  variable: assignedVariable,
@@ -1493,19 +1743,19 @@ var FontVariableControl = () => {
1493
1743
  };
1494
1744
 
1495
1745
  // src/hooks/use-prop-font-variable-action.tsx
1496
- import * as React23 from "react";
1497
- import { useBoundProp as useBoundProp11 } from "@elementor/editor-editing-panel";
1498
- import { ColorFilterIcon as ColorFilterIcon6 } from "@elementor/icons";
1499
- import { __ as __18 } 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";
1500
1750
  var usePropFontVariableAction = () => {
1501
- const { propType } = useBoundProp11();
1751
+ const { propType } = useBoundProp12();
1502
1752
  const visible = !!propType && supportsFontVariables(propType);
1503
1753
  return {
1504
1754
  visible,
1505
- icon: ColorFilterIcon6,
1506
- title: __18("Variables", "elementor"),
1755
+ icon: ColorFilterIcon5,
1756
+ title: __20("Variables", "elementor"),
1507
1757
  content: ({ close: closePopover }) => {
1508
- return /* @__PURE__ */ React23.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1758
+ return /* @__PURE__ */ React24.createElement(VariableSelectionPopover, { closePopover, propTypeKey: fontVariablePropTypeUtil.key });
1509
1759
  }
1510
1760
  };
1511
1761
  };
@@ -1525,8 +1775,8 @@ function initFontVariables() {
1525
1775
  }
1526
1776
 
1527
1777
  // src/renderers/style-variables-renderer.tsx
1528
- import * as React24 from "react";
1529
- import { useEffect, useState as useState11 } from "react";
1778
+ import * as React25 from "react";
1779
+ import { useEffect, useState as useState12 } from "react";
1530
1780
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
1531
1781
  import { Portal } from "@elementor/ui";
1532
1782
 
@@ -1547,13 +1797,13 @@ function StyleVariablesRenderer() {
1547
1797
  }
1548
1798
  const cssVariables = convertToCssVariables(styleVariables);
1549
1799
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
1550
- return /* @__PURE__ */ React24.createElement(Portal, { container }, /* @__PURE__ */ React24.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));
1551
1801
  }
1552
1802
  function usePortalContainer() {
1553
1803
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
1554
1804
  }
1555
1805
  function useStyleVariables() {
1556
- const [variables, setVariables] = useState11({});
1806
+ const [variables, setVariables] = useState12({});
1557
1807
  useEffect(() => {
1558
1808
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
1559
1809
  return () => {
@@ -1562,8 +1812,14 @@ function useStyleVariables() {
1562
1812
  }, []);
1563
1813
  return variables;
1564
1814
  }
1815
+ function cssVariableDeclaration(key, variable) {
1816
+ const variableName = variable?.deleted ? key : variable.label;
1817
+ const value = variable.value;
1818
+ return `--${variableName}:${value};`;
1819
+ }
1565
1820
  function convertToCssVariables(variables) {
1566
- 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("");
1567
1823
  }
1568
1824
 
1569
1825
  // src/init.ts