@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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @elementor/editor-variables
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0a89db7: creating a new variable on the server
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [f7a59df]
12
+ - Updated dependencies [4b762e0]
13
+ - @elementor/editor-controls@0.35.0
14
+ - @elementor/editor-editing-panel@1.43.1
15
+
3
16
  ## 0.10.0
4
17
 
5
18
  ### Minor Changes
package/dist/index.js CHANGED
@@ -62,9 +62,190 @@ var import_ui3 = require("@elementor/ui");
62
62
  // src/hooks/use-prop-variables.ts
63
63
  var import_react = require("react");
64
64
 
65
+ // src/api.ts
66
+ var import_http_client = require("@elementor/http-client");
67
+ var BASE_PATH = "elementor/v1/variables";
68
+ var apiClient = {
69
+ list: () => {
70
+ return (0, import_http_client.httpService)().get(BASE_PATH + "/list");
71
+ },
72
+ create: (type, label, value) => {
73
+ return (0, import_http_client.httpService)().post(BASE_PATH + "/create", {
74
+ type,
75
+ label,
76
+ value
77
+ });
78
+ },
79
+ update: (id, label, value) => {
80
+ return (0, import_http_client.httpService)().put(BASE_PATH + "/update", {
81
+ id,
82
+ label,
83
+ value
84
+ });
85
+ },
86
+ delete: (id) => {
87
+ return (0, import_http_client.httpService)().post(BASE_PATH + "/delete", { id });
88
+ },
89
+ restore: (id) => {
90
+ return (0, import_http_client.httpService)().post(BASE_PATH + "/restore", { id });
91
+ }
92
+ };
93
+
94
+ // src/storage.ts
95
+ var STORAGE_KEY = "elementor-global-variables";
96
+ var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
97
+ var OP_RW = "RW";
98
+ var OP_RO = "RO";
99
+ var Storage = class {
100
+ state;
101
+ constructor() {
102
+ this.state = {
103
+ watermark: -1,
104
+ variables: {}
105
+ };
106
+ }
107
+ load() {
108
+ this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
109
+ this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
110
+ return this.state.variables;
111
+ }
112
+ fill(variables, watermark) {
113
+ this.state.watermark = watermark;
114
+ this.state.variables = variables;
115
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
116
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
117
+ }
118
+ add(id, variable) {
119
+ this.load();
120
+ this.state.variables[id] = variable;
121
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
122
+ }
123
+ update(id, variable) {
124
+ this.load();
125
+ this.state.variables[id] = variable;
126
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
127
+ }
128
+ watermark(watermark) {
129
+ this.state.watermark = watermark;
130
+ localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
131
+ }
132
+ watermarkDiff(operation, newWatermark) {
133
+ const diff = newWatermark - this.state.watermark;
134
+ if (OP_RW === operation) {
135
+ return 1 !== diff;
136
+ }
137
+ if (OP_RO === operation) {
138
+ return 0 !== diff;
139
+ }
140
+ return false;
141
+ }
142
+ };
143
+
144
+ // src/service.ts
145
+ var storage = new Storage();
146
+ var service = {
147
+ variables: () => {
148
+ return storage.load();
149
+ },
150
+ init: () => {
151
+ service.load();
152
+ },
153
+ load: () => {
154
+ return apiClient.list().then((response) => {
155
+ const { success, data: payload } = response.data;
156
+ if (!success) {
157
+ throw new Error("Unexpected response from server");
158
+ }
159
+ return payload;
160
+ }).then((data) => {
161
+ const { variables, watermark } = data;
162
+ storage.fill(variables, watermark);
163
+ return variables;
164
+ });
165
+ },
166
+ create: ({ type, label, value }) => {
167
+ return apiClient.create(type, label, value).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, ...createdVariable } = variable;
177
+ storage.add(variableId, createdVariable);
178
+ return {
179
+ id: variableId,
180
+ variable: createdVariable
181
+ };
182
+ });
183
+ },
184
+ update: (id, { label, value }) => {
185
+ return apiClient.update(id, label, value).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, ...updatedVariable } = variable;
195
+ storage.update(variableId, updatedVariable);
196
+ return {
197
+ id: variableId,
198
+ variable: updatedVariable
199
+ };
200
+ });
201
+ },
202
+ delete: (id) => {
203
+ return apiClient.delete(id).then((response) => {
204
+ const { success, data: payload } = response.data;
205
+ if (!success) {
206
+ throw new Error("Unexpected response from server");
207
+ }
208
+ return payload;
209
+ }).then((data) => {
210
+ const { variable, watermark } = data;
211
+ handleWatermark(OP_RW, watermark);
212
+ const { id: variableId, ...deletedVariable } = variable;
213
+ storage.update(variableId, deletedVariable);
214
+ return {
215
+ id: variableId,
216
+ variable: deletedVariable
217
+ };
218
+ });
219
+ },
220
+ restore: (id) => {
221
+ return apiClient.restore(id).then((response) => {
222
+ const { success, data: payload } = response.data;
223
+ if (!success) {
224
+ throw new Error("Unexpected response from server");
225
+ }
226
+ return payload;
227
+ }).then((data) => {
228
+ const { variable, watermark } = data;
229
+ handleWatermark(OP_RW, watermark);
230
+ const { id: variableId, ...restoredVariable } = variable;
231
+ storage.update(variableId, restoredVariable);
232
+ return {
233
+ id: variableId,
234
+ variable: restoredVariable
235
+ };
236
+ });
237
+ }
238
+ };
239
+ var handleWatermark = (operation, newWatermark) => {
240
+ if (storage.watermarkDiff(operation, newWatermark)) {
241
+ setTimeout(() => service.load(), 500);
242
+ }
243
+ storage.watermark(newWatermark);
244
+ };
245
+
65
246
  // src/create-style-variables-repository.ts
66
247
  var createStyleVariablesRepository = () => {
67
- const variables2 = {};
248
+ const variables = {};
68
249
  let subscription;
69
250
  const subscribe = (cb) => {
70
251
  subscription = cb;
@@ -75,17 +256,17 @@ var createStyleVariablesRepository = () => {
75
256
  };
76
257
  const notify = () => {
77
258
  if (typeof subscription === "function") {
78
- subscription({ ...variables2 });
259
+ subscription({ ...variables });
79
260
  }
80
261
  };
81
262
  const shouldUpdate = (key, newValue) => {
82
- return !(key in variables2) || variables2[key] !== newValue;
263
+ return !(key in variables) || variables[key] !== newValue;
83
264
  };
84
265
  const applyUpdates = (updatedVars) => {
85
266
  let hasChanges = false;
86
267
  for (const [key, { value }] of Object.entries(updatedVars)) {
87
268
  if (shouldUpdate(key, value)) {
88
- variables2[key] = value;
269
+ variables[key] = value;
89
270
  hasChanges = true;
90
271
  }
91
272
  }
@@ -110,6 +291,7 @@ var usePropVariables = (propKey) => {
110
291
  return (0, import_react.useMemo)(() => normalizeVariables(propKey), [propKey]);
111
292
  };
112
293
  var useVariable = (key) => {
294
+ const variables = service.variables();
113
295
  if (!variables?.[key]) {
114
296
  return null;
115
297
  }
@@ -119,24 +301,21 @@ var useVariable = (key) => {
119
301
  };
120
302
  };
121
303
  var normalizeVariables = (propKey) => {
304
+ const variables = service.variables();
305
+ styleVariablesRepository.update(variables);
122
306
  return Object.entries(variables).filter(([, { type }]) => type === propKey).map(([key, { label, value }]) => ({
123
307
  key,
124
308
  label,
125
309
  value
126
310
  }));
127
311
  };
128
- var createVariable = (variable) => {
129
- const id = generateId();
130
- variables[id] = variable;
131
- styleVariablesRepository.update({
132
- [id]: variable
312
+ var createVariable = (newVariable) => {
313
+ return service.create(newVariable).then(({ id, variable }) => {
314
+ styleVariablesRepository.update({
315
+ [id]: variable
316
+ });
317
+ return id;
133
318
  });
134
- return id;
135
- };
136
- var variables = window?.ElementorV4Variables || {};
137
- var generateId = (prefix = "e-gv") => {
138
- const randomHex = Math.random().toString(16).slice(2, 9);
139
- return `${prefix}${randomHex}`;
140
319
  };
141
320
 
142
321
  // src/prop-types/color-variable-prop-type.ts
@@ -158,12 +337,12 @@ var StyledMenuItem = (0, import_ui2.styled)(import_ui2.MenuItem)(() => ({
158
337
  // src/components/color-variables-selection.tsx
159
338
  var ColorVariablesSelection = ({ onSelect }) => {
160
339
  const { value: variable, setValue: setVariable } = (0, import_editor_controls.useBoundProp)(colorVariablePropTypeUtil);
161
- const variables2 = usePropVariables(colorVariablePropTypeUtil.key);
340
+ const variables = usePropVariables(colorVariablePropTypeUtil.key);
162
341
  const handleSetColorVariable = (key) => {
163
342
  setVariable(key);
164
343
  onSelect?.();
165
344
  };
166
- return /* @__PURE__ */ React.createElement(import_react2.Fragment, null, /* @__PURE__ */ React.createElement(import_ui3.Divider, null), /* @__PURE__ */ React.createElement(import_ui3.Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(import_ui3.MenuList, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
345
+ return /* @__PURE__ */ React.createElement(import_react2.Fragment, null, /* @__PURE__ */ React.createElement(import_ui3.Divider, null), /* @__PURE__ */ React.createElement(import_ui3.Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React.createElement(import_ui3.MenuList, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React.createElement(
167
346
  StyledMenuItem,
168
347
  {
169
348
  key,
@@ -228,13 +407,14 @@ var ColorVariableCreation = ({ popupState }) => {
228
407
  popupState.close();
229
408
  };
230
409
  const handleCreate = () => {
231
- const key = createVariable({
410
+ createVariable({
232
411
  value: color,
233
412
  label,
234
413
  type: colorVariablePropTypeUtil.key
414
+ }).then((key) => {
415
+ setVariable(key);
416
+ closePopover();
235
417
  });
236
- setVariable(key);
237
- closePopover();
238
418
  };
239
419
  const isInValidForm = () => {
240
420
  return !color?.trim() || !label?.trim();
@@ -301,6 +481,7 @@ var VariablesSelectionPopover = ({
301
481
  };
302
482
  const anchorRef = (0, import_react4.useRef)(null);
303
483
  const { label } = selectedVariable;
484
+ const colorCreationEnabled = colorVariablePropTypeUtil.key === selectedVariable.type;
304
485
  return /* @__PURE__ */ React3.createElement(import_ui5.Box, { ref: anchorRef }, /* @__PURE__ */ React3.createElement(
305
486
  import_ui5.UnstableTag,
306
487
  {
@@ -320,7 +501,7 @@ var VariablesSelectionPopover = ({
320
501
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
321
502
  transformOrigin: { vertical: "top", horizontal: "right" }
322
503
  },
323
- /* @__PURE__ */ React3.createElement(import_ui5.Stack, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React3.createElement(import_icons3.ColorFilterIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React3.createElement(import_ui5.Typography, { variant: "subtitle2" }, (0, import_i18n2.__)("Variables", "elementor")), /* @__PURE__ */ React3.createElement(import_ui5.Stack, { direction: "row", sx: { ml: "auto" } }, /* @__PURE__ */ React3.createElement(
504
+ /* @__PURE__ */ React3.createElement(import_ui5.Stack, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React3.createElement(import_icons3.ColorFilterIcon, { fontSize: "tiny", sx: { mr: 0.5 } }), /* @__PURE__ */ React3.createElement(import_ui5.Typography, { variant: "subtitle2" }, (0, import_i18n2.__)("Variables", "elementor")), /* @__PURE__ */ React3.createElement(import_ui5.Stack, { direction: "row", sx: { ml: "auto" } }, colorCreationEnabled && /* @__PURE__ */ React3.createElement(
324
505
  import_ui5.IconButton,
325
506
  {
326
507
  ...(0, import_ui5.bindTrigger)(creationPopupState),
@@ -330,7 +511,7 @@ var VariablesSelectionPopover = ({
330
511
  /* @__PURE__ */ React3.createElement(import_icons3.PlusIcon, { fontSize: "tiny" })
331
512
  ), /* @__PURE__ */ React3.createElement(import_ui5.CloseButton, { slotProps: { icon: { fontSize: "tiny" } }, onClick: closePopover }))),
332
513
  children?.({ closePopover })
333
- ), /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
514
+ ), colorCreationEnabled && /* @__PURE__ */ React3.createElement(ColorVariableCreation, { popupState: creationPopupState }));
334
515
  };
335
516
 
336
517
  // src/controls/color-variables-selection-control.tsx
@@ -432,12 +613,12 @@ var import_icons5 = require("@elementor/icons");
432
613
  var import_ui6 = require("@elementor/ui");
433
614
  var FontVariablesSelection = ({ onSelect }) => {
434
615
  const { value: variable, setValue: setVariable } = (0, import_editor_controls4.useBoundProp)(fontVariablePropTypeUtil);
435
- const variables2 = usePropVariables(fontVariablePropTypeUtil.key);
616
+ const variables = usePropVariables(fontVariablePropTypeUtil.key);
436
617
  const handleSetVariable = (key) => {
437
618
  setVariable(key);
438
619
  onSelect?.();
439
620
  };
440
- return /* @__PURE__ */ React6.createElement(import_react5.Fragment, null, /* @__PURE__ */ React6.createElement(import_ui6.Divider, null), /* @__PURE__ */ React6.createElement(import_ui6.Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(import_ui6.MenuList, { role: "listbox", tabIndex: 0 }, variables2.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
621
+ return /* @__PURE__ */ React6.createElement(import_react5.Fragment, null, /* @__PURE__ */ React6.createElement(import_ui6.Divider, null), /* @__PURE__ */ React6.createElement(import_ui6.Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, /* @__PURE__ */ React6.createElement(import_ui6.MenuList, { role: "listbox", tabIndex: 0 }, variables.map(({ value, label, key }) => /* @__PURE__ */ React6.createElement(
441
622
  StyledMenuItem,
442
623
  {
443
624
  key,
@@ -547,200 +728,19 @@ function usePortalContainer() {
547
728
  return (0, import_editor_v1_adapters.__privateUseListenTo)((0, import_editor_v1_adapters.commandEndEvent)("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
548
729
  }
549
730
  function useStyleVariables() {
550
- const [variables2, setVariables] = (0, import_react6.useState)({});
731
+ const [variables, setVariables] = (0, import_react6.useState)({});
551
732
  (0, import_react6.useEffect)(() => {
552
733
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
553
734
  return () => {
554
735
  unsubscribe();
555
736
  };
556
737
  }, []);
557
- return variables2;
738
+ return variables;
558
739
  }
559
- function convertToCssVariables(variables2) {
560
- return Object.entries(variables2).map(([key, value]) => `--${key}:${value};`).join("");
740
+ function convertToCssVariables(variables) {
741
+ return Object.entries(variables).map(([key, value]) => `--${key}:${value};`).join("");
561
742
  }
562
743
 
563
- // src/api.ts
564
- var import_http_client = require("@elementor/http-client");
565
- var BASE_PATH = "elementor/v1/variables";
566
- var apiClient = {
567
- list: () => {
568
- return (0, import_http_client.httpService)().get(BASE_PATH + "/list");
569
- },
570
- create: (type, label, value) => {
571
- return (0, import_http_client.httpService)().post(BASE_PATH + "/create", {
572
- type,
573
- label,
574
- value
575
- });
576
- },
577
- update: (id, label, value) => {
578
- return (0, import_http_client.httpService)().put(BASE_PATH + "/update", {
579
- id,
580
- label,
581
- value
582
- });
583
- },
584
- delete: (id) => {
585
- return (0, import_http_client.httpService)().post(BASE_PATH + "/delete", { id });
586
- },
587
- restore: (id) => {
588
- return (0, import_http_client.httpService)().post(BASE_PATH + "/restore", { id });
589
- }
590
- };
591
-
592
- // src/storage.ts
593
- var STORAGE_KEY = "elementor-global-variables";
594
- var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
595
- var OP_RW = "RW";
596
- var OP_RO = "RO";
597
- var Storage = class {
598
- state;
599
- constructor() {
600
- this.state = {
601
- watermark: -1,
602
- variables: {}
603
- };
604
- }
605
- load() {
606
- this.state.watermark = parseInt(localStorage.getItem(STORAGE_WATERMARK_KEY) || "-1");
607
- this.state.variables = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
608
- return this.state.variables;
609
- }
610
- fill(variables2, watermark) {
611
- this.state.watermark = watermark;
612
- this.state.variables = variables2;
613
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
614
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
615
- }
616
- add(id, variable) {
617
- this.load();
618
- this.state.variables[id] = variable;
619
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
620
- }
621
- update(id, variable) {
622
- this.load();
623
- this.state.variables[id] = variable;
624
- localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
625
- }
626
- watermark(watermark) {
627
- this.state.watermark = watermark;
628
- localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
629
- }
630
- watermarkDiff(operation, newWatermark) {
631
- const diff = newWatermark - this.state.watermark;
632
- if (OP_RW === operation) {
633
- return 1 !== diff;
634
- }
635
- if (OP_RO === operation) {
636
- return 0 !== diff;
637
- }
638
- return false;
639
- }
640
- };
641
-
642
- // src/service.ts
643
- var storage = new Storage();
644
- var service = {
645
- variables: () => {
646
- return storage.load();
647
- },
648
- init: () => {
649
- service.load();
650
- },
651
- load: () => {
652
- return apiClient.list().then((response) => {
653
- const { success, data: payload } = response.data;
654
- if (!success) {
655
- throw new Error("Unexpected response from server");
656
- }
657
- return payload;
658
- }).then((data) => {
659
- const { variables: variables2, watermark } = data;
660
- storage.fill(variables2, watermark);
661
- return variables2;
662
- });
663
- },
664
- create: ({ type, label, value }) => {
665
- return apiClient.create(type, label, value).then((response) => {
666
- const { success, data: payload } = response.data;
667
- if (!success) {
668
- throw new Error("Unexpected response from server");
669
- }
670
- return payload;
671
- }).then((data) => {
672
- const { variable, watermark } = data;
673
- handleWatermark(OP_RW, watermark);
674
- const { id: variableId, ...createdVariable } = variable;
675
- storage.add(variableId, createdVariable);
676
- return {
677
- id: variableId,
678
- variable: createdVariable
679
- };
680
- });
681
- },
682
- update: (id, { label, value }) => {
683
- return apiClient.update(id, label, value).then((response) => {
684
- const { success, data: payload } = response.data;
685
- if (!success) {
686
- throw new Error("Unexpected response from server");
687
- }
688
- return payload;
689
- }).then((data) => {
690
- const { variable, watermark } = data;
691
- handleWatermark(OP_RW, watermark);
692
- const { id: variableId, ...updatedVariable } = variable;
693
- storage.update(variableId, updatedVariable);
694
- return {
695
- id: variableId,
696
- variable: updatedVariable
697
- };
698
- });
699
- },
700
- delete: (id) => {
701
- return apiClient.delete(id).then((response) => {
702
- const { success, data: payload } = response.data;
703
- if (!success) {
704
- throw new Error("Unexpected response from server");
705
- }
706
- return payload;
707
- }).then((data) => {
708
- const { variable, watermark } = data;
709
- handleWatermark(OP_RW, watermark);
710
- const { id: variableId, ...deletedVariable } = variable;
711
- storage.update(variableId, deletedVariable);
712
- return {
713
- id: variableId,
714
- variable: deletedVariable
715
- };
716
- });
717
- },
718
- restore: (id) => {
719
- return apiClient.restore(id).then((response) => {
720
- const { success, data: payload } = response.data;
721
- if (!success) {
722
- throw new Error("Unexpected response from server");
723
- }
724
- return payload;
725
- }).then((data) => {
726
- const { variable, watermark } = data;
727
- handleWatermark(OP_RW, watermark);
728
- const { id: variableId, ...restoredVariable } = variable;
729
- storage.update(variableId, restoredVariable);
730
- return {
731
- id: variableId,
732
- variable: restoredVariable
733
- };
734
- });
735
- }
736
- };
737
- var handleWatermark = (operation, newWatermark) => {
738
- if (storage.watermarkDiff(operation, newWatermark)) {
739
- setTimeout(() => service.load(), 500);
740
- }
741
- storage.watermark(newWatermark);
742
- };
743
-
744
744
  // src/init.ts
745
745
  function init() {
746
746
  initColorVariables();