@elementor/editor-variables 0.10.0 → 0.11.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
@@ -26,9 +26,190 @@ import { Box, Divider, ListItemIcon, ListItemText, MenuList } from "@elementor/u
26
26
  // src/hooks/use-prop-variables.ts
27
27
  import { useMemo } from "react";
28
28
 
29
+ // src/api.ts
30
+ import { httpService } from "@elementor/http-client";
31
+ var BASE_PATH = "elementor/v1/variables";
32
+ var apiClient = {
33
+ list: () => {
34
+ return httpService().get(BASE_PATH + "/list");
35
+ },
36
+ create: (type, label, value) => {
37
+ return httpService().post(BASE_PATH + "/create", {
38
+ type,
39
+ label,
40
+ value
41
+ });
42
+ },
43
+ update: (id, label, value) => {
44
+ return httpService().put(BASE_PATH + "/update", {
45
+ id,
46
+ label,
47
+ value
48
+ });
49
+ },
50
+ delete: (id) => {
51
+ return httpService().post(BASE_PATH + "/delete", { id });
52
+ },
53
+ restore: (id) => {
54
+ return httpService().post(BASE_PATH + "/restore", { id });
55
+ }
56
+ };
57
+
58
+ // src/storage.ts
59
+ var STORAGE_KEY = "elementor-global-variables";
60
+ var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
61
+ var OP_RW = "RW";
62
+ var OP_RO = "RO";
63
+ var Storage = class {
64
+ state;
65
+ constructor() {
66
+ this.state = {
67
+ watermark: -1,
68
+ variables: {}
69
+ };
70
+ }
71
+ load() {
72
+ this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
73
+ this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
74
+ return this.state.variables;
75
+ }
76
+ fill(variables, watermark) {
77
+ this.state.watermark = watermark;
78
+ this.state.variables = variables;
79
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
80
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
81
+ }
82
+ add(id, variable) {
83
+ this.load();
84
+ this.state.variables[id] = variable;
85
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
86
+ }
87
+ update(id, variable) {
88
+ this.load();
89
+ this.state.variables[id] = variable;
90
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
91
+ }
92
+ watermark(watermark) {
93
+ this.state.watermark = watermark;
94
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
95
+ }
96
+ watermarkDiff(operation, newWatermark) {
97
+ const diff = newWatermark - this.state.watermark;
98
+ if (OP_RW === operation) {
99
+ return 1 !== diff;
100
+ }
101
+ if (OP_RO === operation) {
102
+ return 0 !== diff;
103
+ }
104
+ return false;
105
+ }
106
+ };
107
+
108
+ // src/service.ts
109
+ var storage = new Storage();
110
+ var service = {
111
+ variables: () => {
112
+ return storage.load();
113
+ },
114
+ init: () => {
115
+ service.load();
116
+ },
117
+ load: () => {
118
+ return apiClient.list().then((response) => {
119
+ const { success, data: payload } = response.data;
120
+ if (!success) {
121
+ throw new Error("Unexpected response from server");
122
+ }
123
+ return payload;
124
+ }).then((data) => {
125
+ const { variables, watermark } = data;
126
+ storage.fill(variables, watermark);
127
+ return variables;
128
+ });
129
+ },
130
+ create: ({ type, label, value }) => {
131
+ return apiClient.create(type, label, value).then((response) => {
132
+ const { success, data: payload } = response.data;
133
+ if (!success) {
134
+ throw new Error("Unexpected response from server");
135
+ }
136
+ return payload;
137
+ }).then((data) => {
138
+ const { variable, watermark } = data;
139
+ handleWatermark(OP_RW, watermark);
140
+ const { id: variableId, ...createdVariable } = variable;
141
+ storage.add(variableId, createdVariable);
142
+ return {
143
+ id: variableId,
144
+ variable: createdVariable
145
+ };
146
+ });
147
+ },
148
+ update: (id, { label, value }) => {
149
+ return apiClient.update(id, label, value).then((response) => {
150
+ const { success, data: payload } = response.data;
151
+ if (!success) {
152
+ throw new Error("Unexpected response from server");
153
+ }
154
+ return payload;
155
+ }).then((data) => {
156
+ const { variable, watermark } = data;
157
+ handleWatermark(OP_RW, watermark);
158
+ const { id: variableId, ...updatedVariable } = variable;
159
+ storage.update(variableId, updatedVariable);
160
+ return {
161
+ id: variableId,
162
+ variable: updatedVariable
163
+ };
164
+ });
165
+ },
166
+ delete: (id) => {
167
+ return apiClient.delete(id).then((response) => {
168
+ const { success, data: payload } = response.data;
169
+ if (!success) {
170
+ throw new Error("Unexpected response from server");
171
+ }
172
+ return payload;
173
+ }).then((data) => {
174
+ const { variable, watermark } = data;
175
+ handleWatermark(OP_RW, watermark);
176
+ const { id: variableId, ...deletedVariable } = variable;
177
+ storage.update(variableId, deletedVariable);
178
+ return {
179
+ id: variableId,
180
+ variable: deletedVariable
181
+ };
182
+ });
183
+ },
184
+ restore: (id) => {
185
+ return apiClient.restore(id).then((response) => {
186
+ const { success, data: payload } = response.data;
187
+ if (!success) {
188
+ throw new Error("Unexpected response from server");
189
+ }
190
+ return payload;
191
+ }).then((data) => {
192
+ const { variable, watermark } = data;
193
+ handleWatermark(OP_RW, watermark);
194
+ const { id: variableId, ...restoredVariable } = variable;
195
+ storage.update(variableId, restoredVariable);
196
+ return {
197
+ id: variableId,
198
+ variable: restoredVariable
199
+ };
200
+ });
201
+ }
202
+ };
203
+ var handleWatermark = (operation, newWatermark) => {
204
+ if (storage.watermarkDiff(operation, newWatermark)) {
205
+ setTimeout(() => service.load(), 500);
206
+ }
207
+ storage.watermark(newWatermark);
208
+ };
209
+
29
210
  // src/create-style-variables-repository.ts
30
211
  var createStyleVariablesRepository = () => {
31
- const variables2 = {};
212
+ const variables = {};
32
213
  let subscription;
33
214
  const subscribe = (cb) => {
34
215
  subscription = cb;
@@ -39,17 +220,17 @@ var createStyleVariablesRepository = () => {
39
220
  };
40
221
  const notify = () => {
41
222
  if (typeof subscription === "function") {
42
- subscription({ ...variables2 });
223
+ subscription({ ...variables });
43
224
  }
44
225
  };
45
226
  const shouldUpdate = (key, newValue) => {
46
- return !(key in variables2) || variables2[key] !== newValue;
227
+ return !(key in variables) || variables[key] !== newValue;
47
228
  };
48
229
  const applyUpdates = (updatedVars) => {
49
230
  let hasChanges = false;
50
231
  for (const [key, { value }] of Object.entries(updatedVars)) {
51
232
  if (shouldUpdate(key, value)) {
52
- variables2[key] = value;
233
+ variables[key] = value;
53
234
  hasChanges = true;
54
235
  }
55
236
  }
@@ -74,6 +255,7 @@ var usePropVariables = (propKey) => {
74
255
  return useMemo(() => normalizeVariables(propKey), [propKey]);
75
256
  };
76
257
  var useVariable = (key) => {
258
+ const variables = service.variables();
77
259
  if (!variables?.[key]) {
78
260
  return null;
79
261
  }
@@ -83,24 +265,21 @@ var useVariable = (key) => {
83
265
  };
84
266
  };
85
267
  var normalizeVariables = (propKey) => {
268
+ const variables = service.variables();
269
+ styleVariablesRepository.update(variables);
86
270
  return Object.entries(variables).filter(([, { type }]) => type === propKey).map(([key, { label, value }]) => ({
87
271
  key,
88
272
  label,
89
273
  value
90
274
  }));
91
275
  };
92
- var createVariable = (variable) => {
93
- const id = generateId();
94
- variables[id] = variable;
95
- styleVariablesRepository.update({
96
- [id]: variable
276
+ var createVariable = (newVariable) => {
277
+ return service.create(newVariable).then(({ id, variable }) => {
278
+ styleVariablesRepository.update({
279
+ [id]: variable
280
+ });
281
+ return id;
97
282
  });
98
- return id;
99
- };
100
- var variables = window?.ElementorV4Variables || {};
101
- var generateId = (prefix = "e-gv") => {
102
- const randomHex = Math.random().toString(16).slice(2, 9);
103
- return `${prefix}${randomHex}`;
104
283
  };
105
284
 
106
285
  // src/prop-types/color-variable-prop-type.ts
@@ -122,12 +301,12 @@ var StyledMenuItem = styled2(MenuItem)(() => ({
122
301
  // src/components/color-variables-selection.tsx
123
302
  var ColorVariablesSelection = ({ onSelect }) => {
124
303
  const { value: variable, setValue: setVariable } = useBoundProp(colorVariablePropTypeUtil);
125
- const variables2 = usePropVariables(colorVariablePropTypeUtil.key);
304
+ const variables = usePropVariables(colorVariablePropTypeUtil.key);
126
305
  const handleSetColorVariable = (key) => {
127
306
  setVariable(key);
128
307
  onSelect?.();
129
308
  };
130
- return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(MenuList, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
309
+ return /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(MenuList, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
131
310
  StyledMenuItem,
132
311
  {
133
312
  key,
@@ -217,13 +396,14 @@ var ColorVariableCreation = ({ popupState }) => {
217
396
  popupState.close();
218
397
  };
219
398
  const handleCreate = () => {
220
- const key = createVariable({
399
+ createVariable({
221
400
  value: color,
222
401
  label,
223
402
  type: colorVariablePropTypeUtil.key
403
+ }).then((key) => {
404
+ setVariable(key);
405
+ closePopover();
224
406
  });
225
- setVariable(key);
226
- closePopover();
227
407
  };
228
408
  const isInValidForm = () => {
229
409
  return !color?.trim() || !label?.trim();
@@ -290,6 +470,7 @@ var VariablesSelectionPopover = ({
290
470
  };
291
471
  const anchorRef = useRef2(null);
292
472
  const { label } = selectedVariable;
473
+ const colorCreationEnabled = colorVariablePropTypeUtil.key === selectedVariable.type;
293
474
  return /* @__PURE__ */ React3.createElement(Box3, { ref: anchorRef }, /* @__PURE__ */ React3.createElement(
294
475
  Tag,
295
476
  {
@@ -309,7 +490,7 @@ var VariablesSelectionPopover = ({
309
490
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
310
491
  transformOrigin: { vertical: "top", horizontal: "right" }
311
492
  },
312
- /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React3.createElement(Typography2, { variant: "subtitle2" }, __2("Variables", "elementor")), /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", sx: { ml: "auto" } }, /* @__PURE__ */ React3.createElement(
493
+ /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React3.createElement(ColorFilterIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React3.createElement(Typography2, { variant: "subtitle2" }, __2("Variables", "elementor")), /* @__PURE__ */ React3.createElement(Stack2, { direction: "row", sx: { ml: "auto" } }, colorCreationEnabled && /* @__PURE__ */ React3.createElement(
313
494
  IconButton,
314
495
  {
315
496
  ...bindTrigger(creationPopupState),
@@ -319,7 +500,7 @@ var VariablesSelectionPopover = ({
319
500
  /* @__PURE__ */ React3.createElement(PlusIcon, { fontSize: "tiny" })
320
501
  ), /* @__PURE__ */ React3.createElement(CloseButton2, { slotProps: { icon: { fontSize: "tiny" } }, onClick: closePopover }))),
321
502
  children?.({ closePopover })
322
- ), /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
503
+ ), colorCreationEnabled && /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
323
504
  };
324
505
 
325
506
  // src/controls/color-variables-selection-control.tsx
@@ -421,12 +602,12 @@ import { EditIcon as EditIcon2, TextIcon } from "@elementor/icons";
421
602
  import { Box as Box4, Divider as Divider3, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, MenuList as MenuList2 } from "@elementor/ui";
422
603
  var FontVariablesSelection = ({ onSelect }) => {
423
604
  const { value: variable, setValue: setVariable } = useBoundProp5(fontVariablePropTypeUtil);
424
- const variables2 = usePropVariables(fontVariablePropTypeUtil.key);
605
+ const variables = usePropVariables(fontVariablePropTypeUtil.key);
425
606
  const handleSetVariable = (key) => {
426
607
  setVariable(key);
427
608
  onSelect?.();
428
609
  };
429
- return /* @__PURE__ */ React6.createElement(Fragment2, null, /* @__PURE__ */ React6.createElement(Divider3, null), /* @__PURE__ */ React6.createElement(Box4, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
610
+ return /* @__PURE__ */ React6.createElement(Fragment2, null, /* @__PURE__ */ React6.createElement(Divider3, null), /* @__PURE__ */ React6.createElement(Box4, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(MenuList2, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
430
611
  StyledMenuItem,
431
612
  {
432
613
  key,
@@ -536,200 +717,19 @@ function usePortalContainer() {
536
717
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
537
718
  }
538
719
  function useStyleVariables() {
539
- const [variables2, setVariables] = useState2({});
720
+ const [variables, setVariables] = useState2({});
540
721
  useEffect(() => {
541
722
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
542
723
  return () => {
543
724
  unsubscribe();
544
725
  };
545
726
  }, []);
546
- return variables2;
727
+ return variables;
547
728
  }
548
- function convertToCssVariables(variables2) {
549
- return Object.entries(variables2).map(([key, value]) => `--${key}:${value};`).join("");
729
+ function convertToCssVariables(variables) {
730
+ return Object.entries(variables).map(([key, value]) => `--${key}:${value};`).join("");
550
731
  }
551
732
 
552
- // src/api.ts
553
- import { httpService } from "@elementor/http-client";
554
- var BASE_PATH = "elementor/v1/variables";
555
- var apiClient = {
556
- list: () => {
557
- return httpService().get(BASE_PATH + "/list");
558
- },
559
- create: (type, label, value) => {
560
- return httpService().post(BASE_PATH + "/create", {
561
- type,
562
- label,
563
- value
564
- });
565
- },
566
- update: (id, label, value) => {
567
- return httpService().put(BASE_PATH + "/update", {
568
- id,
569
- label,
570
- value
571
- });
572
- },
573
- delete: (id) => {
574
- return httpService().post(BASE_PATH + "/delete", { id });
575
- },
576
- restore: (id) => {
577
- return httpService().post(BASE_PATH + "/restore", { id });
578
- }
579
- };
580
-
581
- // src/storage.ts
582
- var STORAGE_KEY = "elementor-global-variables";
583
- var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
584
- var OP_RW = "RW";
585
- var OP_RO = "RO";
586
- var Storage = class {
587
- state;
588
- constructor() {
589
- this.state = {
590
- watermark: -1,
591
- variables: {}
592
- };
593
- }
594
- load() {
595
- this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
596
- this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
597
- return this.state.variables;
598
- }
599
- fill(variables2, watermark) {
600
- this.state.watermark = watermark;
601
- this.state.variables = variables2;
602
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
603
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
604
- }
605
- add(id, variable) {
606
- this.load();
607
- this.state.variables[id] = variable;
608
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
609
- }
610
- update(id, variable) {
611
- this.load();
612
- this.state.variables[id] = variable;
613
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
614
- }
615
- watermark(watermark) {
616
- this.state.watermark = watermark;
617
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
618
- }
619
- watermarkDiff(operation, newWatermark) {
620
- const diff = newWatermark - this.state.watermark;
621
- if (OP_RW === operation) {
622
- return 1 !== diff;
623
- }
624
- if (OP_RO === operation) {
625
- return 0 !== diff;
626
- }
627
- return false;
628
- }
629
- };
630
-
631
- // src/service.ts
632
- var storage = new Storage();
633
- var service = {
634
- variables: () => {
635
- return storage.load();
636
- },
637
- init: () => {
638
- service.load();
639
- },
640
- load: () => {
641
- return apiClient.list().then((response) => {
642
- const { success, data: payload } = response.data;
643
- if (!success) {
644
- throw new Error("Unexpected response from server");
645
- }
646
- return payload;
647
- }).then((data) => {
648
- const { variables: variables2, watermark } = data;
649
- storage.fill(variables2, watermark);
650
- return variables2;
651
- });
652
- },
653
- create: ({ type, label, value }) => {
654
- return apiClient.create(type, label, value).then((response) => {
655
- const { success, data: payload } = response.data;
656
- if (!success) {
657
- throw new Error("Unexpected response from server");
658
- }
659
- return payload;
660
- }).then((data) => {
661
- const { variable, watermark } = data;
662
- handleWatermark(OP_RW, watermark);
663
- const { id: variableId, ...createdVariable } = variable;
664
- storage.add(variableId, createdVariable);
665
- return {
666
- id: variableId,
667
- variable: createdVariable
668
- };
669
- });
670
- },
671
- update: (id, { label, value }) => {
672
- return apiClient.update(id, label, value).then((response) => {
673
- const { success, data: payload } = response.data;
674
- if (!success) {
675
- throw new Error("Unexpected response from server");
676
- }
677
- return payload;
678
- }).then((data) => {
679
- const { variable, watermark } = data;
680
- handleWatermark(OP_RW, watermark);
681
- const { id: variableId, ...updatedVariable } = variable;
682
- storage.update(variableId, updatedVariable);
683
- return {
684
- id: variableId,
685
- variable: updatedVariable
686
- };
687
- });
688
- },
689
- delete: (id) => {
690
- return apiClient.delete(id).then((response) => {
691
- const { success, data: payload } = response.data;
692
- if (!success) {
693
- throw new Error("Unexpected response from server");
694
- }
695
- return payload;
696
- }).then((data) => {
697
- const { variable, watermark } = data;
698
- handleWatermark(OP_RW, watermark);
699
- const { id: variableId, ...deletedVariable } = variable;
700
- storage.update(variableId, deletedVariable);
701
- return {
702
- id: variableId,
703
- variable: deletedVariable
704
- };
705
- });
706
- },
707
- restore: (id) => {
708
- return apiClient.restore(id).then((response) => {
709
- const { success, data: payload } = response.data;
710
- if (!success) {
711
- throw new Error("Unexpected response from server");
712
- }
713
- return payload;
714
- }).then((data) => {
715
- const { variable, watermark } = data;
716
- handleWatermark(OP_RW, watermark);
717
- const { id: variableId, ...restoredVariable } = variable;
718
- storage.update(variableId, restoredVariable);
719
- return {
720
- id: variableId,
721
- variable: restoredVariable
722
- };
723
- });
724
- }
725
- };
726
- var handleWatermark = (operation, newWatermark) => {
727
- if (storage.watermarkDiff(operation, newWatermark)) {
728
- setTimeout(() => service.load(), 500);
729
- }
730
- storage.watermark(newWatermark);
731
- };
732
-
733
733
  // src/init.ts
734
734
  function init() {
735
735
  initColorVariables();