@elementor/editor-editing-panel 0.14.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/index.d.mts +29 -1
  3. package/dist/index.d.ts +29 -1
  4. package/dist/index.js +939 -302
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +944 -294
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +9 -8
  9. package/src/components/editing-panel.tsx +1 -1
  10. package/src/components/settings-tab.tsx +6 -17
  11. package/src/components/style-sections/position-section/position-section.tsx +15 -0
  12. package/src/components/style-sections/position-section/z-index-control.tsx +16 -0
  13. package/src/components/style-sections/size-section.tsx +14 -18
  14. package/src/components/style-sections/spacing-section/linked-dimensions-control.tsx +140 -0
  15. package/src/components/style-sections/spacing-section/spacing-section.tsx +22 -0
  16. package/src/components/style-sections/typography-section/font-size-control.tsx +16 -0
  17. package/src/components/style-sections/typography-section/font-weight-control.tsx +24 -0
  18. package/src/components/style-sections/typography-section/letter-spacing-control.tsx +16 -0
  19. package/src/components/style-sections/typography-section/text-color-control.tsx +16 -0
  20. package/src/{controls/control-types → components/style-sections/typography-section}/text-style-control.tsx +16 -14
  21. package/src/components/style-sections/typography-section/transform-control.tsx +23 -0
  22. package/src/components/style-sections/typography-section/typography-section.tsx +34 -0
  23. package/src/components/style-sections/typography-section/word-spacing-control.tsx +16 -0
  24. package/src/components/style-tab.tsx +30 -6
  25. package/src/contexts/element-context.tsx +5 -3
  26. package/src/contexts/style-context.tsx +8 -2
  27. package/src/controls/components/control-container.tsx +18 -0
  28. package/src/controls/components/control-toggle-button-group.tsx +59 -0
  29. package/src/controls/components/text-field-inner-selection.tsx +79 -0
  30. package/src/controls/control-replacement.ts +26 -0
  31. package/src/controls/control-types/color-control.tsx +24 -0
  32. package/src/controls/control-types/image-control.tsx +3 -18
  33. package/src/controls/control-types/number-control.tsx +25 -0
  34. package/src/controls/control-types/size-control.tsx +22 -34
  35. package/src/controls/control-types/text-area-control.tsx +1 -1
  36. package/src/controls/control-types/toggle-control.tsx +25 -0
  37. package/src/controls/control.tsx +50 -0
  38. package/src/controls/{get-control-by-type.ts → controls-registry.tsx} +13 -9
  39. package/src/controls/hooks/use-style-control.ts +2 -1
  40. package/src/controls/settings-control.tsx +8 -21
  41. package/src/dynamics/components/dynamic-selection-control.tsx +180 -0
  42. package/src/dynamics/components/dynamic-selection.tsx +144 -0
  43. package/src/dynamics/dynamic-control.tsx +42 -0
  44. package/src/dynamics/hooks/use-dynamic-tag.ts +10 -0
  45. package/src/dynamics/hooks/use-prop-dynamic-tags.ts +36 -0
  46. package/src/dynamics/init.ts +10 -0
  47. package/src/dynamics/sync/get-atomic-dynamic-tags.ts +14 -0
  48. package/src/dynamics/sync/get-elementor-config.ts +7 -0
  49. package/src/dynamics/types.ts +32 -0
  50. package/src/dynamics/utils.ts +9 -0
  51. package/src/hooks/use-element-type.ts +5 -0
  52. package/src/index.ts +3 -0
  53. package/src/init.ts +4 -0
  54. package/src/props/is-transformable.ts +14 -0
  55. package/src/sync/types.ts +2 -1
  56. package/src/sync/update-style.ts +2 -2
  57. package/src/types.ts +17 -0
  58. package/LICENSE +0 -674
  59. package/src/components/style-sections/typography-section.tsx +0 -15
package/dist/index.js CHANGED
@@ -5,6 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
8
12
  var __copyProps = (to, from, except, desc) => {
9
13
  if (from && typeof from === "object" || typeof from === "function") {
10
14
  for (let key of __getOwnPropNames(from))
@@ -21,13 +25,47 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ replaceControl: () => replaceControl,
34
+ useControl: () => useControl
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+
38
+ // src/controls/control-replacement.ts
39
+ var controlReplacement;
40
+ var replaceControl = ({ component, condition }) => {
41
+ controlReplacement = { component, condition };
42
+ };
43
+ var getControlReplacement = ({ value }) => {
44
+ let shouldReplace = false;
45
+ try {
46
+ shouldReplace = !!controlReplacement?.condition({ value });
47
+ } catch {
48
+ }
49
+ return shouldReplace ? controlReplacement?.component : void 0;
50
+ };
51
+
52
+ // src/controls/control-context.tsx
53
+ var import_react = require("react");
54
+ var ControlContext = (0, import_react.createContext)(null);
55
+ function useControl(defaultValue) {
56
+ const controlContext = (0, import_react.useContext)(ControlContext);
57
+ if (!controlContext) {
58
+ throw new Error("useControl must be used within a ControlContext");
59
+ }
60
+ return { ...controlContext, value: controlContext.value ?? defaultValue };
61
+ }
24
62
 
25
63
  // src/panel.ts
26
64
  var import_editor_panels2 = require("@elementor/editor-panels");
27
65
 
28
66
  // src/components/editing-panel.tsx
29
- var React19 = __toESM(require("react"));
30
- var import_i18n7 = require("@wordpress/i18n");
67
+ var React36 = __toESM(require("react"));
68
+ var import_i18n17 = require("@wordpress/i18n");
31
69
 
32
70
  // src/hooks/use-selected-elements.ts
33
71
  var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
@@ -78,9 +116,13 @@ function useElementType(type) {
78
116
  if (!elementType?.atomic_controls) {
79
117
  return null;
80
118
  }
119
+ if (!elementType?.atomic_props_schema) {
120
+ return null;
121
+ }
81
122
  return {
82
123
  key: type,
83
124
  controls: elementType.atomic_controls,
125
+ propsSchema: elementType.atomic_props_schema,
84
126
  title: elementType.title
85
127
  };
86
128
  },
@@ -93,13 +135,13 @@ var import_editor_panels = require("@elementor/editor-panels");
93
135
 
94
136
  // src/contexts/element-context.tsx
95
137
  var React = __toESM(require("react"));
96
- var import_react = require("react");
97
- var Context = (0, import_react.createContext)(null);
98
- function ElementContext({ children, element }) {
99
- return /* @__PURE__ */ React.createElement(Context.Provider, { value: { element } }, children);
138
+ var import_react2 = require("react");
139
+ var Context = (0, import_react2.createContext)(null);
140
+ function ElementContext({ children, element, elementType }) {
141
+ return /* @__PURE__ */ React.createElement(Context.Provider, { value: { element, elementType } }, children);
100
142
  }
101
143
  function useElementContext() {
102
- const context = (0, import_react.useContext)(Context);
144
+ const context = (0, import_react2.useContext)(Context);
103
145
  if (!context) {
104
146
  throw new Error("useElementContext must be used within a ElementContextProvider");
105
147
  }
@@ -107,30 +149,16 @@ function useElementContext() {
107
149
  }
108
150
 
109
151
  // src/components/editing-panel-tabs.tsx
110
- var import_ui15 = require("@elementor/ui");
111
- var React18 = __toESM(require("react"));
112
- var import_i18n6 = require("@wordpress/i18n");
152
+ var import_ui22 = require("@elementor/ui");
153
+ var React35 = __toESM(require("react"));
154
+ var import_i18n16 = require("@wordpress/i18n");
113
155
 
114
156
  // src/components/settings-tab.tsx
115
- var React9 = __toESM(require("react"));
116
- var import_ui8 = require("@elementor/ui");
117
-
118
- // src/controls/settings-control.tsx
119
- var React3 = __toESM(require("react"));
120
-
121
- // src/controls/control-context.tsx
122
- var import_react2 = require("react");
123
- var ControlContext = (0, import_react2.createContext)(null);
124
- function useControl(defaultValue) {
125
- const controlContext = (0, import_react2.useContext)(ControlContext);
126
- if (!controlContext) {
127
- throw new Error("useControl must be used within a ControlContext");
128
- }
129
- return { ...controlContext, value: controlContext.value ?? defaultValue };
130
- }
157
+ var React13 = __toESM(require("react"));
158
+ var import_ui10 = require("@elementor/ui");
131
159
 
132
160
  // src/controls/settings-control.tsx
133
- var import_ui2 = require("@elementor/ui");
161
+ var React4 = __toESM(require("react"));
134
162
 
135
163
  // src/hooks/use-widget-settings.ts
136
164
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
@@ -174,10 +202,28 @@ var ControlLabel = ({ children }) => {
174
202
  return /* @__PURE__ */ React2.createElement(import_ui.Typography, { component: "label", variant: "caption", color: "text.secondary" }, children);
175
203
  };
176
204
 
205
+ // src/controls/components/control-container.tsx
206
+ var React3 = __toESM(require("react"));
207
+ var import_ui2 = require("@elementor/ui");
208
+ var StyledStack = (0, import_ui2.styled)(import_ui2.Stack)(({ theme, gap, direction }) => ({
209
+ "> :only-child": {
210
+ width: "100%"
211
+ },
212
+ "&:where( :has( > :nth-child( 2 ):last-child ) ) > :where( * )": {
213
+ width: direction === "column" ? "100%" : `calc( 50% - ${theme.spacing(gap / 2)})`
214
+ },
215
+ "&:where( :has( > :nth-child( 3 ):last-child ) ) > :where( * )": {
216
+ width: direction === "column" ? "100%" : `calc( 33.3333% - ${theme.spacing(gap * 2)} / 3)`
217
+ }
218
+ }));
219
+ var ControlContainer = (props) => /* @__PURE__ */ React3.createElement(StyledStack, { gap: 1, direction: "row", alignItems: "center", justifyContent: "space-between", ...props });
220
+
177
221
  // src/controls/settings-control.tsx
178
222
  var SettingsControlProvider = ({ bind, children }) => {
179
- const { element } = useElementContext();
180
- const value = useWidgetSettings({ id: element.id, bind });
223
+ const { element, elementType } = useElementContext();
224
+ const defaultValue = elementType.propsSchema[bind]?.type.default;
225
+ const settingsValue = useWidgetSettings({ id: element.id, bind });
226
+ const value = settingsValue ?? defaultValue ?? null;
181
227
  const setValue = (newValue) => {
182
228
  updateSettings({
183
229
  id: element.id,
@@ -186,97 +232,36 @@ var SettingsControlProvider = ({ bind, children }) => {
186
232
  }
187
233
  });
188
234
  };
189
- return /* @__PURE__ */ React3.createElement(ControlContext.Provider, { value: { setValue, value, bind } }, children);
235
+ return /* @__PURE__ */ React4.createElement(ControlContext.Provider, { value: { setValue, value, bind } }, children);
190
236
  };
191
- var SettingsControl = ({ children, bind }) => /* @__PURE__ */ React3.createElement(SettingsControlProvider, { bind }, /* @__PURE__ */ React3.createElement(StyledStack, { direction: "row", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap" }, children));
192
- var StyledStack = (0, import_ui2.styled)(import_ui2.Stack)(({ theme }) => {
193
- const gap = theme.spacing(1);
194
- return {
195
- gap,
196
- "& > *": {
197
- width: `calc(50% - ${gap} / 2)`
198
- },
199
- "& > label": {
200
- flexShrink: 0
201
- }
202
- };
203
- });
237
+ var SettingsControl = ({ children, bind }) => /* @__PURE__ */ React4.createElement(SettingsControlProvider, { bind }, /* @__PURE__ */ React4.createElement(ControlContainer, { flexWrap: "wrap" }, children));
204
238
  SettingsControl.Label = ControlLabel;
205
239
 
206
240
  // src/components/accordion-section.tsx
207
- var React4 = __toESM(require("react"));
241
+ var React5 = __toESM(require("react"));
208
242
  var import_react3 = require("react");
209
243
  var import_ui3 = require("@elementor/ui");
210
244
  var AccordionSection = ({ title, children }) => {
211
245
  const uid = (0, import_react3.useId)();
212
246
  const labelId = `label-${uid}`;
213
247
  const contentId = `content-${uid}`;
214
- return /* @__PURE__ */ React4.createElement(import_ui3.Accordion, { disableGutters: true, defaultExpanded: true }, /* @__PURE__ */ React4.createElement(import_ui3.AccordionSummary, { "aria-controls": contentId, id: labelId }, /* @__PURE__ */ React4.createElement(import_ui3.AccordionSummaryText, { primaryTypographyProps: { variant: "caption" } }, title)), /* @__PURE__ */ React4.createElement(import_ui3.AccordionDetails, { id: contentId, "aria-labelledby": labelId }, /* @__PURE__ */ React4.createElement(import_ui3.Stack, { gap: 2.5 }, children)));
215
- };
216
-
217
- // src/controls/control-types/select-control.tsx
218
- var React5 = __toESM(require("react"));
219
- var import_ui4 = require("@elementor/ui");
220
- var SelectControl = ({ options }) => {
221
- const { value, setValue } = useControl();
222
- const handleChange = (event) => {
223
- setValue(event.target.value);
224
- };
225
- return /* @__PURE__ */ React5.createElement(import_ui4.Select, { size: "tiny", value: value ?? "", onChange: handleChange }, options.map(({ label, ...props }) => /* @__PURE__ */ React5.createElement(import_ui4.MenuItem, { key: props.value, ...props }, label)));
226
- };
227
-
228
- // src/controls/control-types/text-area-control.tsx
229
- var React6 = __toESM(require("react"));
230
- var import_ui5 = require("@elementor/ui");
231
- var TextAreaControl = ({ placeholder }) => {
232
- const { value, setValue } = useControl("");
233
- const handleChange = (event) => {
234
- setValue(event.target.value);
235
- };
236
- return /* @__PURE__ */ React6.createElement(
237
- import_ui5.TextField,
238
- {
239
- size: "tiny",
240
- multiline: true,
241
- fullWidth: true,
242
- rows: 5,
243
- value,
244
- onChange: handleChange,
245
- placeholder
246
- }
247
- );
248
+ return /* @__PURE__ */ React5.createElement(import_ui3.Accordion, { disableGutters: true, defaultExpanded: true }, /* @__PURE__ */ React5.createElement(import_ui3.AccordionSummary, { "aria-controls": contentId, id: labelId }, /* @__PURE__ */ React5.createElement(import_ui3.AccordionSummaryText, { primaryTypographyProps: { variant: "caption" } }, title)), /* @__PURE__ */ React5.createElement(import_ui3.AccordionDetails, { id: contentId, "aria-labelledby": labelId }, /* @__PURE__ */ React5.createElement(import_ui3.Stack, { gap: 2.5 }, children)));
248
249
  };
249
250
 
250
- // src/controls/control-types/text-control.tsx
251
- var React7 = __toESM(require("react"));
252
- var import_ui6 = require("@elementor/ui");
253
- var TextControl = ({ placeholder }) => {
254
- const { value, setValue } = useControl("");
255
- const handleChange = (event) => setValue(event.target.value);
256
- return /* @__PURE__ */ React7.createElement(import_ui6.TextField, { type: "text", size: "tiny", value, onChange: handleChange, placeholder });
257
- };
251
+ // src/controls/control.tsx
252
+ var React12 = __toESM(require("react"));
253
+ var import_utils = require("@elementor/utils");
258
254
 
259
255
  // src/controls/control-types/image-control.tsx
260
- var React8 = __toESM(require("react"));
261
- var import_ui7 = require("@elementor/ui");
256
+ var React6 = __toESM(require("react"));
257
+ var import_ui4 = require("@elementor/ui");
262
258
  var import_icons = require("@elementor/icons");
263
259
  var import_i18n = require("@wordpress/i18n");
264
260
  var import_wp_media = require("@elementor/wp-media");
265
- var defaultState = {
266
- $$type: "image",
267
- value: {
268
- url: "/wp-content/plugins/elementor/assets/images/placeholder.png"
269
- }
270
- };
271
261
  var ImageControl = () => {
272
- const { value, setValue } = useControl(defaultState);
262
+ const { value, setValue } = useControl();
273
263
  const { data: attachment } = (0, import_wp_media.useWpMediaAttachment)(value?.value?.attachmentId);
274
- const getImageSrc = () => {
275
- if (attachment?.url) {
276
- return attachment.url;
277
- }
278
- return value?.value?.url ?? defaultState.value.url;
279
- };
264
+ const src = attachment?.url ?? value?.value?.url;
280
265
  const { open } = (0, import_wp_media.useWpMediaFrame)({
281
266
  types: ["image"],
282
267
  multiple: false,
@@ -290,8 +275,8 @@ var ImageControl = () => {
290
275
  });
291
276
  }
292
277
  });
293
- return /* @__PURE__ */ React8.createElement(import_ui7.Card, { variant: "outlined" }, /* @__PURE__ */ React8.createElement(import_ui7.CardMedia, { image: getImageSrc(), sx: { height: 150 } }), /* @__PURE__ */ React8.createElement(import_ui7.CardOverlay, null, /* @__PURE__ */ React8.createElement(
294
- import_ui7.Button,
278
+ return /* @__PURE__ */ React6.createElement(import_ui4.Card, { variant: "outlined" }, /* @__PURE__ */ React6.createElement(import_ui4.CardMedia, { image: src, sx: { height: 150 } }), /* @__PURE__ */ React6.createElement(import_ui4.CardOverlay, null, /* @__PURE__ */ React6.createElement(
279
+ import_ui4.Button,
295
280
  {
296
281
  color: "inherit",
297
282
  size: "small",
@@ -301,13 +286,13 @@ var ImageControl = () => {
301
286
  }
302
287
  },
303
288
  (0, import_i18n.__)("Select Image", "elementor")
304
- ), /* @__PURE__ */ React8.createElement(
305
- import_ui7.Button,
289
+ ), /* @__PURE__ */ React6.createElement(
290
+ import_ui4.Button,
306
291
  {
307
292
  color: "inherit",
308
293
  size: "small",
309
294
  variant: "text",
310
- startIcon: /* @__PURE__ */ React8.createElement(import_icons.UploadIcon, null),
295
+ startIcon: /* @__PURE__ */ React6.createElement(import_icons.UploadIcon, null),
311
296
  onClick: () => {
312
297
  open({ mode: "upload" });
313
298
  }
@@ -316,32 +301,220 @@ var ImageControl = () => {
316
301
  )));
317
302
  };
318
303
 
319
- // src/controls/get-control-by-type.ts
304
+ // src/controls/control-types/text-control.tsx
305
+ var React7 = __toESM(require("react"));
306
+ var import_ui5 = require("@elementor/ui");
307
+ var TextControl = ({ placeholder }) => {
308
+ const { value, setValue } = useControl("");
309
+ const handleChange = (event) => setValue(event.target.value);
310
+ return /* @__PURE__ */ React7.createElement(import_ui5.TextField, { type: "text", size: "tiny", value, onChange: handleChange, placeholder });
311
+ };
312
+
313
+ // src/controls/control-types/text-area-control.tsx
314
+ var React8 = __toESM(require("react"));
315
+ var import_ui6 = require("@elementor/ui");
316
+ var TextAreaControl = ({ placeholder }) => {
317
+ const { value, setValue } = useControl();
318
+ const handleChange = (event) => {
319
+ setValue(event.target.value);
320
+ };
321
+ return /* @__PURE__ */ React8.createElement(
322
+ import_ui6.TextField,
323
+ {
324
+ size: "tiny",
325
+ multiline: true,
326
+ fullWidth: true,
327
+ rows: 5,
328
+ value,
329
+ onChange: handleChange,
330
+ placeholder
331
+ }
332
+ );
333
+ };
334
+
335
+ // src/controls/control-types/size-control.tsx
336
+ var React10 = __toESM(require("react"));
337
+ var import_ui8 = require("@elementor/ui");
338
+
339
+ // src/controls/hooks/use-sync-external-state.tsx
340
+ var import_react4 = require("react");
341
+ var useSyncExternalState = ({
342
+ external,
343
+ setExternal,
344
+ persistWhen,
345
+ fallback
346
+ }) => {
347
+ function toExternal(internalValue) {
348
+ if (persistWhen(internalValue)) {
349
+ return internalValue;
350
+ }
351
+ return void 0;
352
+ }
353
+ function toInternal(externalValue, internalValue) {
354
+ if (!externalValue) {
355
+ return fallback(internalValue);
356
+ }
357
+ return externalValue;
358
+ }
359
+ const [internal, setInternal] = (0, import_react4.useState)(toInternal(external, void 0));
360
+ (0, import_react4.useEffect)(() => {
361
+ setInternal((prevInternal) => toInternal(external, prevInternal));
362
+ }, [external]);
363
+ const setInternalValue = (setter) => {
364
+ const setterFn = typeof setter === "function" ? setter : () => setter;
365
+ const updated = setterFn(internal);
366
+ setInternal(updated);
367
+ setExternal(toExternal(updated));
368
+ };
369
+ return [internal, setInternalValue];
370
+ };
371
+
372
+ // src/controls/components/text-field-inner-selection.tsx
373
+ var React9 = __toESM(require("react"));
374
+ var import_ui7 = require("@elementor/ui");
375
+ var import_react5 = require("react");
376
+ var TextFieldInnerSelection = ({
377
+ placeholder,
378
+ type,
379
+ value,
380
+ onChange,
381
+ endAdornment,
382
+ startAdornment
383
+ }) => {
384
+ return /* @__PURE__ */ React9.createElement(
385
+ import_ui7.TextField,
386
+ {
387
+ size: "tiny",
388
+ type,
389
+ value,
390
+ onChange,
391
+ placeholder,
392
+ InputProps: {
393
+ endAdornment,
394
+ startAdornment
395
+ }
396
+ }
397
+ );
398
+ };
399
+ var SelectionEndAdornment = ({
400
+ options: options2,
401
+ onClick,
402
+ value
403
+ }) => {
404
+ const popupState = (0, import_ui7.usePopupState)({
405
+ variant: "popover",
406
+ popupId: (0, import_react5.useId)()
407
+ });
408
+ const handleMenuItemClick = (index) => {
409
+ onClick(options2[index]);
410
+ popupState.close();
411
+ };
412
+ return /* @__PURE__ */ React9.createElement(import_ui7.InputAdornment, { position: "end" }, /* @__PURE__ */ React9.createElement(
413
+ import_ui7.Button,
414
+ {
415
+ size: "small",
416
+ color: "inherit",
417
+ sx: { font: "inherit", minWidth: "initial" },
418
+ ...(0, import_ui7.bindTrigger)(popupState)
419
+ },
420
+ value.toUpperCase()
421
+ ), /* @__PURE__ */ React9.createElement(import_ui7.Menu, { MenuListProps: { dense: true }, ...(0, import_ui7.bindMenu)(popupState) }, options2.map((option, index) => /* @__PURE__ */ React9.createElement(import_ui7.MenuItem, { key: option, onClick: () => handleMenuItemClick(index) }, option.toUpperCase()))));
422
+ };
423
+
424
+ // src/controls/control-types/size-control.tsx
425
+ var defaultUnits = ["px", "%", "em", "rem", "vw"];
426
+ var SizeControl = ({ units = defaultUnits, placeholder, startIcon }) => {
427
+ const { value, setValue } = useControl();
428
+ const [state, setState] = useSyncExternalState({
429
+ external: value,
430
+ setExternal: setValue,
431
+ persistWhen: (controlValue) => !!controlValue?.value.size || controlValue?.value.size === 0,
432
+ fallback: (controlValue) => ({
433
+ $$type: "size",
434
+ value: { unit: controlValue?.value.unit || "px", size: NaN }
435
+ })
436
+ });
437
+ const handleUnitChange = (unit) => {
438
+ setState((prev) => ({
439
+ ...prev,
440
+ value: {
441
+ ...prev.value,
442
+ unit
443
+ }
444
+ }));
445
+ };
446
+ const handleSizeChange = (event) => {
447
+ const { value: size } = event.target;
448
+ setState((prev) => ({
449
+ ...prev,
450
+ value: {
451
+ ...prev.value,
452
+ size: size || size === "0" ? parseFloat(size) : NaN
453
+ }
454
+ }));
455
+ };
456
+ return /* @__PURE__ */ React10.createElement(
457
+ TextFieldInnerSelection,
458
+ {
459
+ endAdornment: /* @__PURE__ */ React10.createElement(SelectionEndAdornment, { options: units, onClick: handleUnitChange, value: state.value.unit }),
460
+ placeholder,
461
+ startAdornment: startIcon ?? /* @__PURE__ */ React10.createElement(import_ui8.InputAdornment, { position: "start" }, startIcon),
462
+ type: "number",
463
+ value: Number.isNaN(state.value.size) ? "" : state.value.size,
464
+ onChange: handleSizeChange
465
+ }
466
+ );
467
+ };
468
+
469
+ // src/controls/control-types/select-control.tsx
470
+ var React11 = __toESM(require("react"));
471
+ var import_ui9 = require("@elementor/ui");
472
+ var SelectControl = ({ options: options2 }) => {
473
+ const { value, setValue } = useControl();
474
+ const handleChange = (event) => {
475
+ setValue(event.target.value);
476
+ };
477
+ return /* @__PURE__ */ React11.createElement(import_ui9.Select, { size: "tiny", value: value ?? "", onChange: handleChange }, options2.map(({ label, ...props }) => /* @__PURE__ */ React11.createElement(import_ui9.MenuItem, { key: props.value, ...props }, label)));
478
+ };
479
+
480
+ // src/controls/controls-registry.tsx
320
481
  var controlTypes = {
321
482
  image: ImageControl,
322
- select: SelectControl,
323
483
  text: TextControl,
324
- textarea: TextAreaControl
484
+ textarea: TextAreaControl,
485
+ size: SizeControl,
486
+ select: SelectControl
325
487
  };
326
- var getControlByType = (type) => {
327
- return controlTypes[type] ?? null;
488
+ var getControlByType = (type) => controlTypes[type];
489
+
490
+ // src/controls/control.tsx
491
+ var ControlTypeError = (0, import_utils.createError)({
492
+ code: "CONTROL_TYPE_NOT_FOUND",
493
+ message: `Control type not found.`
494
+ });
495
+ var Control = ({ props, type }) => {
496
+ const { value } = useControl();
497
+ const ControlByType = getControlByType(type);
498
+ if (!ControlByType) {
499
+ throw new ControlTypeError({
500
+ context: { type }
501
+ });
502
+ }
503
+ const ControlComponent = getControlReplacement({ value }) || ControlByType;
504
+ return /* @__PURE__ */ React12.createElement(ControlComponent, { ...props });
328
505
  };
329
506
 
330
507
  // src/components/settings-tab.tsx
331
508
  var SettingsTab = () => {
332
- const { element } = useElementContext();
333
- const elementType = useElementType(element?.type);
334
- if (!elementType) {
335
- return null;
336
- }
337
- return /* @__PURE__ */ React9.createElement(import_ui8.Stack, null, elementType.controls.map(({ type, value }, index) => {
509
+ const { elementType } = useElementContext();
510
+ return /* @__PURE__ */ React13.createElement(import_ui10.Stack, null, elementType.controls.map(({ type, value }, index) => {
338
511
  if (type === "control") {
339
- return /* @__PURE__ */ React9.createElement(Control, { key: value.bind, control: value });
512
+ return /* @__PURE__ */ React13.createElement(Control2, { key: value.bind, control: value });
340
513
  }
341
514
  if (type === "section") {
342
- return /* @__PURE__ */ React9.createElement(AccordionSection, { key: type + "." + index, title: value.label }, value.items?.map((item) => {
515
+ return /* @__PURE__ */ React13.createElement(AccordionSection, { key: type + "." + index, title: value.label }, value.items?.map((item) => {
343
516
  if (item.type === "control") {
344
- return /* @__PURE__ */ React9.createElement(Control, { key: item.value.bind, control: item.value });
517
+ return /* @__PURE__ */ React13.createElement(Control2, { key: item.value.bind, control: item.value });
345
518
  }
346
519
  return null;
347
520
  }));
@@ -349,34 +522,28 @@ var SettingsTab = () => {
349
522
  return null;
350
523
  }));
351
524
  };
352
- var Control = ({ control }) => {
353
- const ControlComponent = getControlByType(control.type);
354
- if (!ControlComponent) {
525
+ var Control2 = ({ control }) => {
526
+ if (!getControlByType(control.type)) {
355
527
  return null;
356
528
  }
357
- return /* @__PURE__ */ React9.createElement(SettingsControl, { bind: control.bind }, control.label ? /* @__PURE__ */ React9.createElement(SettingsControl.Label, null, control.label) : null, /* @__PURE__ */ React9.createElement(
358
- ControlComponent,
359
- {
360
- ...control.props
361
- }
362
- ));
529
+ return /* @__PURE__ */ React13.createElement(SettingsControl, { bind: control.bind }, control.label ? /* @__PURE__ */ React13.createElement(SettingsControl.Label, null, control.label) : null, /* @__PURE__ */ React13.createElement(Control, { type: control.type, props: control.props }));
363
530
  };
364
531
 
365
532
  // src/components/style-tab.tsx
366
- var React17 = __toESM(require("react"));
533
+ var React34 = __toESM(require("react"));
367
534
 
368
535
  // src/contexts/style-context.tsx
369
- var React10 = __toESM(require("react"));
370
- var import_react4 = require("react");
536
+ var React14 = __toESM(require("react"));
537
+ var import_react6 = require("react");
371
538
  var import_editor_responsive = require("@elementor/editor-responsive");
372
- var Context2 = (0, import_react4.createContext)(null);
373
- function StyleContext({ children, selectedStyleDef }) {
539
+ var Context2 = (0, import_react6.createContext)(null);
540
+ function StyleContext({ children, selectedStyleDef, selectedClassesProp }) {
374
541
  const breakpoint = (0, import_editor_responsive.useActiveBreakpoint)();
375
542
  const selectedMeta = { breakpoint, state: null };
376
- return /* @__PURE__ */ React10.createElement(Context2.Provider, { value: { selectedStyleDef, selectedMeta } }, children);
543
+ return /* @__PURE__ */ React14.createElement(Context2.Provider, { value: { selectedStyleDef, selectedMeta, selectedClassesProp } }, children);
377
544
  }
378
545
  function useStyleContext() {
379
- const context = (0, import_react4.useContext)(Context2);
546
+ const context = (0, import_react6.useContext)(Context2);
380
547
  if (!context) {
381
548
  throw new Error("UseStyleContext must be used within a StyleContextProvider");
382
549
  }
@@ -404,13 +571,13 @@ var useElementStyles = (elementID) => {
404
571
  };
405
572
 
406
573
  // src/components/style-tab.tsx
407
- var import_ui14 = require("@elementor/ui");
574
+ var import_ui21 = require("@elementor/ui");
408
575
 
409
576
  // src/components/style-sections/size-section.tsx
410
- var React14 = __toESM(require("react"));
577
+ var React16 = __toESM(require("react"));
411
578
 
412
579
  // src/controls/style-control.tsx
413
- var React11 = __toESM(require("react"));
580
+ var React15 = __toESM(require("react"));
414
581
 
415
582
  // src/hooks/use-element-style-prop.ts
416
583
  var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
@@ -444,7 +611,7 @@ function getVariantByMeta(styleDef, meta) {
444
611
 
445
612
  // src/sync/update-style.ts
446
613
  var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
447
- var updateStyle = ({ elementID, styleDefID, meta, props, bind = "classes" }) => {
614
+ var updateStyle = ({ elementID, styleDefID, meta, props, bind }) => {
448
615
  const container = getContainer(elementID);
449
616
  (0, import_editor_v1_adapters7.__privateRunCommand)("document/atomic-widgets/styles", {
450
617
  container,
@@ -458,7 +625,7 @@ var updateStyle = ({ elementID, styleDefID, meta, props, bind = "classes" }) =>
458
625
  // src/controls/hooks/use-style-control.ts
459
626
  var useStyleControl = (propName) => {
460
627
  const { element } = useElementContext();
461
- const { selectedStyleDef, selectedMeta } = useStyleContext();
628
+ const { selectedStyleDef, selectedMeta, selectedClassesProp } = useStyleContext();
462
629
  const value = useElementStyleProp({
463
630
  elementID: element.id,
464
631
  styleDefID: selectedStyleDef?.id,
@@ -470,7 +637,8 @@ var useStyleControl = (propName) => {
470
637
  elementID: element.id,
471
638
  styleDefID: selectedStyleDef?.id,
472
639
  props: { [propName]: newValue },
473
- meta: selectedMeta
640
+ meta: selectedMeta,
641
+ bind: selectedClassesProp
474
642
  });
475
643
  };
476
644
  return [value, setValue];
@@ -479,168 +647,44 @@ var useStyleControl = (propName) => {
479
647
  // src/controls/style-control.tsx
480
648
  var StyleControl = ({ bind, children }) => {
481
649
  const [value, setValue] = useStyleControl(bind);
482
- return /* @__PURE__ */ React11.createElement(ControlContext.Provider, { value: { bind, value, setValue } }, children);
650
+ return /* @__PURE__ */ React15.createElement(ControlContext.Provider, { value: { bind, value, setValue } }, children);
483
651
  };
484
652
  StyleControl.Label = ControlLabel;
485
653
 
486
- // src/components/collapsible-content.tsx
487
- var React12 = __toESM(require("react"));
488
- var import_react5 = require("react");
489
- var import_icons2 = require("@elementor/icons");
490
- var import_ui9 = require("@elementor/ui");
491
- var import_i18n2 = require("@wordpress/i18n");
492
- var CollapsibleContent = ({ children, defaultOpen = false }) => {
493
- const [open, setOpen] = (0, import_react5.useState)(defaultOpen);
494
- const handleToggle = () => {
495
- setOpen((prevOpen) => !prevOpen);
496
- };
497
- return /* @__PURE__ */ React12.createElement(import_ui9.Stack, { sx: { py: 0.5 } }, /* @__PURE__ */ React12.createElement(
498
- import_ui9.Button,
499
- {
500
- fullWidth: true,
501
- size: "small",
502
- color: "secondary",
503
- variant: "outlined",
504
- onClick: handleToggle,
505
- endIcon: /* @__PURE__ */ React12.createElement(ChevronIcon, { open })
506
- },
507
- open ? (0, import_i18n2.__)("Show less", "elementor") : (0, import_i18n2.__)("Show more", "elementor")
508
- ), /* @__PURE__ */ React12.createElement(import_ui9.Collapse, { in: open, timeout: "auto" }, children));
509
- };
510
- var ChevronIcon = (0, import_ui9.styled)(import_icons2.ChevronDownIcon, {
511
- shouldForwardProp: (prop) => prop !== "open"
512
- })(({ theme, open }) => ({
513
- transform: open ? "rotate(180deg)" : "rotate(0)",
514
- transition: theme.transitions.create("transform", {
515
- duration: theme.transitions.duration.standard
516
- })
517
- }));
518
-
519
- // src/controls/control-types/size-control.tsx
520
- var React13 = __toESM(require("react"));
521
- var import_ui10 = require("@elementor/ui");
522
-
523
- // src/controls/hooks/use-sync-external-state.tsx
524
- var import_react6 = require("react");
525
- var useSyncExternalState = ({
526
- external,
527
- setExternal,
528
- persistWhen,
529
- fallback
530
- }) => {
531
- function toExternal(internalValue) {
532
- if (persistWhen(internalValue)) {
533
- return internalValue;
534
- }
535
- return void 0;
536
- }
537
- function toInternal(externalValue, internalValue) {
538
- if (!externalValue) {
539
- return fallback(internalValue);
540
- }
541
- return externalValue;
542
- }
543
- const [internal, setInternal] = (0, import_react6.useState)(toInternal(external, void 0));
544
- (0, import_react6.useEffect)(() => {
545
- setInternal((prevInternal) => toInternal(external, prevInternal));
546
- }, [external]);
547
- const setInternalValue = (setter) => {
548
- const setterFn = typeof setter === "function" ? setter : () => setter;
549
- const updated = setterFn(internal);
550
- setInternal(updated);
551
- setExternal(toExternal(updated));
552
- };
553
- return [internal, setInternalValue];
554
- };
555
-
556
- // src/controls/control-types/size-control.tsx
557
- var SizeControl = ({ units: units2, placeholder }) => {
558
- const { value, setValue } = useControl();
559
- const [state, setState] = useSyncExternalState({
560
- external: value,
561
- setExternal: setValue,
562
- persistWhen: (controlValue) => !!controlValue?.value.size || controlValue?.value.size === 0,
563
- fallback: (controlValue) => ({
564
- $$type: "size",
565
- value: { unit: controlValue?.value.unit || "px", size: NaN }
566
- })
567
- });
568
- const handleUnitChange = (event) => {
569
- const unit = event.target.value;
570
- setState((prev) => ({
571
- ...prev,
572
- value: {
573
- ...prev.value,
574
- unit
575
- }
576
- }));
577
- };
578
- const handleSizeChange = (event) => {
579
- const { value: size } = event.target;
580
- setState((prev) => ({
581
- ...prev,
582
- value: {
583
- ...prev.value,
584
- size: size || size === "0" ? parseFloat(size) : NaN
585
- }
586
- }));
587
- };
588
- return /* @__PURE__ */ React13.createElement(import_ui10.Stack, { direction: "row" }, /* @__PURE__ */ React13.createElement(
589
- import_ui10.TextField,
590
- {
591
- size: "tiny",
592
- type: "number",
593
- value: Number.isNaN(state.value.size) ? "" : state.value.size,
594
- onChange: handleSizeChange,
595
- placeholder
596
- }
597
- ), /* @__PURE__ */ React13.createElement(
598
- import_ui10.Select,
599
- {
600
- size: "tiny",
601
- value: state.value.unit,
602
- onChange: handleUnitChange,
603
- MenuProps: {
604
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
605
- transformOrigin: { vertical: "top", horizontal: "right" }
606
- }
607
- },
608
- units2.map((unit) => /* @__PURE__ */ React13.createElement(import_ui10.MenuItem, { key: unit, value: unit }, unit.toUpperCase()))
609
- ));
610
- };
611
-
612
654
  // src/components/style-sections/size-section.tsx
613
655
  var import_ui11 = require("@elementor/ui");
614
- var import_i18n3 = require("@wordpress/i18n");
656
+ var import_i18n2 = require("@wordpress/i18n");
615
657
  var SizeSection = () => {
616
- return /* @__PURE__ */ React14.createElement(AccordionSection, { title: (0, import_i18n3.__)("Size", "elementor") }, /* @__PURE__ */ React14.createElement(import_ui11.Stack, { gap: 1.5 }, /* @__PURE__ */ React14.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "width", label: (0, import_i18n3.__)("Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "height", label: (0, import_i18n3.__)("Height", "elementor") })), /* @__PURE__ */ React14.createElement(CollapsibleContent, null, /* @__PURE__ */ React14.createElement(import_ui11.Stack, { gap: 1.5, sx: { pt: 1.5 } }, /* @__PURE__ */ React14.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "minWidth", label: (0, import_i18n3.__)("Min. Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "minHeight", label: (0, import_i18n3.__)("Min. Height", "elementor") })), /* @__PURE__ */ React14.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "maxWidth", label: (0, import_i18n3.__)("Max. Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "maxHeight", label: (0, import_i18n3.__)("Max. Height", "elementor") }))))));
658
+ return /* @__PURE__ */ React16.createElement(AccordionSection, { title: (0, import_i18n2.__)("Size", "elementor") }, /* @__PURE__ */ React16.createElement(import_ui11.Stack, { gap: 1.5 }, /* @__PURE__ */ React16.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "width", label: (0, import_i18n2.__)("Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "height", label: (0, import_i18n2.__)("Height", "elementor") })), /* @__PURE__ */ React16.createElement(import_ui11.Stack, { gap: 1.5, sx: { pt: 1.5 } }, /* @__PURE__ */ React16.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "minWidth", label: (0, import_i18n2.__)("Min. Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "minHeight", label: (0, import_i18n2.__)("Min. Height", "elementor") })), /* @__PURE__ */ React16.createElement(import_ui11.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "maxWidth", label: (0, import_i18n2.__)("Max. Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "maxHeight", label: (0, import_i18n2.__)("Max. Height", "elementor") })))));
617
659
  };
618
- var units = ["px", "%", "em", "rem", "vw"];
619
- var Control2 = ({ label, bind }) => {
620
- return /* @__PURE__ */ React14.createElement(StyleControl, { bind }, /* @__PURE__ */ React14.createElement(import_ui11.Stack, { gap: 1, sx: { flex: "0 1 50%" } }, /* @__PURE__ */ React14.createElement(StyleControl.Label, null, label), /* @__PURE__ */ React14.createElement(SizeControl, { units })));
660
+ var Control3 = ({ label, bind }) => {
661
+ return /* @__PURE__ */ React16.createElement(StyleControl, { bind }, /* @__PURE__ */ React16.createElement(ControlContainer, { direction: "column" }, /* @__PURE__ */ React16.createElement(StyleControl.Label, null, label), /* @__PURE__ */ React16.createElement(Control, { type: "size" })));
621
662
  };
622
663
 
623
- // src/components/style-sections/typography-section.tsx
624
- var React16 = __toESM(require("react"));
625
- var import_ui13 = require("@elementor/ui");
664
+ // src/components/style-sections/typography-section/typography-section.tsx
665
+ var React28 = __toESM(require("react"));
666
+ var import_ui16 = require("@elementor/ui");
626
667
 
627
- // src/controls/control-types/text-style-control.tsx
628
- var React15 = __toESM(require("react"));
668
+ // src/components/style-sections/typography-section/text-style-control.tsx
669
+ var React17 = __toESM(require("react"));
629
670
  var import_ui12 = require("@elementor/ui");
630
- var import_i18n4 = require("@wordpress/i18n");
671
+ var import_icons2 = require("@elementor/icons");
672
+ var import_i18n3 = require("@wordpress/i18n");
673
+ var buttonSize = "tiny";
631
674
  var TextStyleControl = () => {
632
675
  const [fontStyle, setFontStyle] = useStyleControl("fontStyle");
633
676
  const [textDecoration, setTextDecoration] = useStyleControl("textDecoration");
634
677
  const formats = [fontStyle, ...(textDecoration || "").split(" ")];
635
- return /* @__PURE__ */ React15.createElement(import_ui12.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center" }, /* @__PURE__ */ React15.createElement(ControlLabel, null, (0, import_i18n4.__)("Style", "elementor")), /* @__PURE__ */ React15.createElement(import_ui12.ToggleButtonGroup, { value: formats }, /* @__PURE__ */ React15.createElement(
678
+ return /* @__PURE__ */ React17.createElement(ControlContainer, null, /* @__PURE__ */ React17.createElement(ControlLabel, null, (0, import_i18n3.__)("Style", "elementor")), /* @__PURE__ */ React17.createElement(import_ui12.ToggleButtonGroup, { value: formats }, /* @__PURE__ */ React17.createElement(
636
679
  ToggleButton,
637
680
  {
638
681
  value: "italic",
639
682
  onChange: (v) => setFontStyle(fontStyle === v ? null : v),
640
- "aria-label": "italic"
683
+ "aria-label": "italic",
684
+ sx: { marginLeft: "auto" }
641
685
  },
642
- /* @__PURE__ */ React15.createElement("span", { style: { fontStyle: "italic", fontSize: "12px" } }, "I")
643
- ), /* @__PURE__ */ React15.createElement(
686
+ /* @__PURE__ */ React17.createElement(import_icons2.ItalicIcon, { fontSize: buttonSize })
687
+ ), /* @__PURE__ */ React17.createElement(
644
688
  ShorthandControl,
645
689
  {
646
690
  value: "line-through",
@@ -648,8 +692,8 @@ var TextStyleControl = () => {
648
692
  updateValues: setTextDecoration,
649
693
  "aria-label": "line-through"
650
694
  },
651
- /* @__PURE__ */ React15.createElement("span", { style: { textDecoration: "line-through", fontSize: "12px" } }, "S")
652
- ), /* @__PURE__ */ React15.createElement(
695
+ /* @__PURE__ */ React17.createElement(import_icons2.StrikethroughIcon, { fontSize: buttonSize })
696
+ ), /* @__PURE__ */ React17.createElement(
653
697
  ShorthandControl,
654
698
  {
655
699
  value: "underline",
@@ -657,7 +701,7 @@ var TextStyleControl = () => {
657
701
  updateValues: setTextDecoration,
658
702
  "aria-label": "underline"
659
703
  },
660
- /* @__PURE__ */ React15.createElement("span", { style: { textDecoration: "underline", fontSize: "12px" } }, "U")
704
+ /* @__PURE__ */ React17.createElement(import_icons2.UnderlineIcon, { fontSize: buttonSize })
661
705
  )));
662
706
  };
663
707
  var ShorthandControl = ({
@@ -676,33 +720,347 @@ var ShorthandControl = ({
676
720
  updateValues([...valuesArr, newValue].join(" "));
677
721
  }
678
722
  };
679
- return /* @__PURE__ */ React15.createElement(ToggleButton, { value, onChange: toggleValue, selected, "aria-label": ariaLabel }, children);
723
+ return /* @__PURE__ */ React17.createElement(ToggleButton, { value, onChange: toggleValue, selected, "aria-label": ariaLabel }, children);
680
724
  };
681
725
  var ToggleButton = ({ onChange, ...props }) => {
682
726
  const handleChange = (_e, newValue) => {
683
727
  onChange(newValue);
684
728
  };
685
- return /* @__PURE__ */ React15.createElement(import_ui12.ToggleButton, { ...props, onChange: handleChange, size: "tiny", sx: { px: 1.5 } });
729
+ return /* @__PURE__ */ React17.createElement(import_ui12.ToggleButton, { ...props, onChange: handleChange, size: buttonSize });
730
+ };
731
+
732
+ // src/components/style-sections/typography-section/typography-section.tsx
733
+ var import_i18n11 = require("@wordpress/i18n");
734
+
735
+ // src/components/style-sections/typography-section/font-size-control.tsx
736
+ var React18 = __toESM(require("react"));
737
+ var import_i18n4 = require("@wordpress/i18n");
738
+ var FontSizeControl = () => {
739
+ return /* @__PURE__ */ React18.createElement(StyleControl, { bind: "font-size" }, /* @__PURE__ */ React18.createElement(ControlContainer, null, /* @__PURE__ */ React18.createElement(StyleControl.Label, null, (0, import_i18n4.__)("Font Size", "elementor")), /* @__PURE__ */ React18.createElement(SizeControl, null)));
686
740
  };
687
741
 
688
- // src/components/style-sections/typography-section.tsx
742
+ // src/components/style-sections/typography-section/font-weight-control.tsx
743
+ var React19 = __toESM(require("react"));
689
744
  var import_i18n5 = require("@wordpress/i18n");
745
+ var fontWeightOptions = [
746
+ { label: (0, import_i18n5.__)("Light - 400", "elementor"), value: 400 },
747
+ { label: (0, import_i18n5.__)("Regular - 500", "elementor"), value: 500 },
748
+ { label: (0, import_i18n5.__)("Semi Bold - 600", "elementor"), value: 600 },
749
+ { label: (0, import_i18n5.__)("Bold - 700", "elementor"), value: 700 },
750
+ { label: (0, import_i18n5.__)("Black - 900", "elementor"), value: 900 }
751
+ ];
752
+ var FontWeightControl = () => {
753
+ return /* @__PURE__ */ React19.createElement(StyleControl, { bind: "fontWeight" }, /* @__PURE__ */ React19.createElement(ControlContainer, null, /* @__PURE__ */ React19.createElement(StyleControl.Label, null, (0, import_i18n5.__)("Font Weight", "elementor")), /* @__PURE__ */ React19.createElement(SelectControl, { options: fontWeightOptions })));
754
+ };
755
+
756
+ // src/components/style-sections/typography-section/text-color-control.tsx
757
+ var React21 = __toESM(require("react"));
758
+ var import_i18n6 = require("@wordpress/i18n");
759
+
760
+ // src/controls/control-types/color-control.tsx
761
+ var React20 = __toESM(require("react"));
762
+ var import_ui13 = require("@elementor/ui");
763
+ var ColorControl = () => {
764
+ const { value, setValue } = useControl();
765
+ const handleChange = debounce((selectedColor) => {
766
+ setValue(selectedColor);
767
+ });
768
+ return /* @__PURE__ */ React20.createElement(import_ui13.UnstableColorPicker, { value, onChange: handleChange });
769
+ };
770
+ var debounce = (func, wait = 300) => {
771
+ let timer;
772
+ return (...args) => {
773
+ clearTimeout(timer);
774
+ timer = setTimeout(() => func(...args), wait);
775
+ };
776
+ };
777
+
778
+ // src/components/style-sections/typography-section/text-color-control.tsx
779
+ var TextColorControl = () => {
780
+ return /* @__PURE__ */ React21.createElement(StyleControl, { bind: "color" }, /* @__PURE__ */ React21.createElement(ControlContainer, null, /* @__PURE__ */ React21.createElement(StyleControl.Label, null, (0, import_i18n6.__)("Text Color", "elementor")), /* @__PURE__ */ React21.createElement(ColorControl, null)));
781
+ };
782
+
783
+ // src/components/style-sections/typography-section/letter-spacing-control.tsx
784
+ var React22 = __toESM(require("react"));
785
+ var import_i18n7 = require("@wordpress/i18n");
786
+ var LetterSpacingControl = () => {
787
+ return /* @__PURE__ */ React22.createElement(StyleControl, { bind: "letter-spacing" }, /* @__PURE__ */ React22.createElement(ControlContainer, null, /* @__PURE__ */ React22.createElement(StyleControl.Label, null, (0, import_i18n7.__)("Letter Spacing", "elementor")), /* @__PURE__ */ React22.createElement(SizeControl, null)));
788
+ };
789
+
790
+ // src/components/style-sections/typography-section/word-spacing-control.tsx
791
+ var React23 = __toESM(require("react"));
792
+ var import_i18n8 = require("@wordpress/i18n");
793
+ var WordSpacingControl = () => {
794
+ return /* @__PURE__ */ React23.createElement(StyleControl, { bind: "word-spacing" }, /* @__PURE__ */ React23.createElement(ControlContainer, null, /* @__PURE__ */ React23.createElement(StyleControl.Label, null, (0, import_i18n8.__)("Word Spacing", "elementor")), /* @__PURE__ */ React23.createElement(SizeControl, null)));
795
+ };
796
+
797
+ // src/components/collapsible-content.tsx
798
+ var React24 = __toESM(require("react"));
799
+ var import_react7 = require("react");
800
+ var import_icons3 = require("@elementor/icons");
801
+ var import_ui14 = require("@elementor/ui");
802
+ var import_i18n9 = require("@wordpress/i18n");
803
+ var CollapsibleContent = ({ children, defaultOpen = false }) => {
804
+ const [open, setOpen] = (0, import_react7.useState)(defaultOpen);
805
+ const handleToggle = () => {
806
+ setOpen((prevOpen) => !prevOpen);
807
+ };
808
+ return /* @__PURE__ */ React24.createElement(import_ui14.Stack, { sx: { py: 0.5 } }, /* @__PURE__ */ React24.createElement(
809
+ import_ui14.Button,
810
+ {
811
+ fullWidth: true,
812
+ size: "small",
813
+ color: "secondary",
814
+ variant: "outlined",
815
+ onClick: handleToggle,
816
+ endIcon: /* @__PURE__ */ React24.createElement(ChevronIcon, { open })
817
+ },
818
+ open ? (0, import_i18n9.__)("Show less", "elementor") : (0, import_i18n9.__)("Show more", "elementor")
819
+ ), /* @__PURE__ */ React24.createElement(import_ui14.Collapse, { in: open, timeout: "auto" }, children));
820
+ };
821
+ var ChevronIcon = (0, import_ui14.styled)(import_icons3.ChevronDownIcon, {
822
+ shouldForwardProp: (prop) => prop !== "open"
823
+ })(({ theme, open }) => ({
824
+ transform: open ? "rotate(180deg)" : "rotate(0)",
825
+ transition: theme.transitions.create("transform", {
826
+ duration: theme.transitions.duration.standard
827
+ })
828
+ }));
829
+
830
+ // src/components/style-sections/typography-section/transform-control.tsx
831
+ var React27 = __toESM(require("react"));
832
+ var import_i18n10 = require("@wordpress/i18n");
833
+
834
+ // src/controls/control-types/toggle-control.tsx
835
+ var React26 = __toESM(require("react"));
836
+
837
+ // src/controls/components/control-toggle-button-group.tsx
838
+ var React25 = __toESM(require("react"));
839
+ var import_ui15 = require("@elementor/ui");
840
+ var StyledToggleButtonGroup = (0, import_ui15.styled)(import_ui15.ToggleButtonGroup)`
841
+ ${({ justify }) => `justify-content: ${justify};`}
842
+ `;
843
+ var ControlToggleButtonGroup = ({
844
+ justify = "end",
845
+ size = "tiny",
846
+ value,
847
+ onChange,
848
+ items,
849
+ exclusive = false
850
+ }) => {
851
+ const handleChange = (_, newValue) => {
852
+ onChange(newValue);
853
+ };
854
+ return /* @__PURE__ */ React25.createElement(StyledToggleButtonGroup, { justify, value, onChange: handleChange, exclusive }, items.map(({ label, value: buttonValue, icon: Icon }) => /* @__PURE__ */ React25.createElement(import_ui15.ToggleButton, { key: buttonValue, value: buttonValue, "aria-label": label, size }, /* @__PURE__ */ React25.createElement(Icon, { fontSize: size }))));
855
+ };
856
+
857
+ // src/controls/control-types/toggle-control.tsx
858
+ var ToggleControl = ({ options: options2 }) => {
859
+ const { value, setValue } = useControl();
860
+ const handleToggle = (option) => {
861
+ setValue(option || void 0);
862
+ };
863
+ return /* @__PURE__ */ React26.createElement(
864
+ ControlToggleButtonGroup,
865
+ {
866
+ items: options2,
867
+ value: value || null,
868
+ onChange: handleToggle,
869
+ exclusive: true
870
+ }
871
+ );
872
+ };
873
+
874
+ // src/components/style-sections/typography-section/transform-control.tsx
875
+ var import_icons4 = require("@elementor/icons");
876
+ var options = [
877
+ { value: "capitalize", label: (0, import_i18n10.__)("Capitalize", "elementor"), icon: import_icons4.LetterCaseIcon },
878
+ { value: "uppercase", label: (0, import_i18n10.__)("Uppercase", "elementor"), icon: import_icons4.LetterCaseUpperIcon },
879
+ { value: "lowercase", label: (0, import_i18n10.__)("Lowercase", "elementor"), icon: import_icons4.LetterCaseLowerIcon }
880
+ ];
881
+ var TransformControl = () => {
882
+ return /* @__PURE__ */ React27.createElement(ControlContainer, null, /* @__PURE__ */ React27.createElement(StyleControl.Label, null, (0, import_i18n10.__)("Transform", "elementor")), /* @__PURE__ */ React27.createElement(StyleControl, { bind: "text-transform" }, /* @__PURE__ */ React27.createElement(ToggleControl, { options })));
883
+ };
884
+
885
+ // src/components/style-sections/typography-section/typography-section.tsx
690
886
  var TypographySection = () => {
691
- return /* @__PURE__ */ React16.createElement(AccordionSection, { title: (0, import_i18n5.__)("Typography", "elementor") }, /* @__PURE__ */ React16.createElement(import_ui13.Stack, { gap: 1.5 }, /* @__PURE__ */ React16.createElement(TextStyleControl, null)));
887
+ return /* @__PURE__ */ React28.createElement(AccordionSection, { title: (0, import_i18n11.__)("Typography", "elementor") }, /* @__PURE__ */ React28.createElement(import_ui16.Stack, { gap: 1.5 }, /* @__PURE__ */ React28.createElement(FontWeightControl, null), /* @__PURE__ */ React28.createElement(FontSizeControl, null), /* @__PURE__ */ React28.createElement(import_ui16.Divider, null), /* @__PURE__ */ React28.createElement(TextColorControl, null), /* @__PURE__ */ React28.createElement(CollapsibleContent, null, /* @__PURE__ */ React28.createElement(import_ui16.Stack, { gap: 1.5, sx: { pt: 1.5 } }, /* @__PURE__ */ React28.createElement(LetterSpacingControl, null), /* @__PURE__ */ React28.createElement(WordSpacingControl, null), /* @__PURE__ */ React28.createElement(import_ui16.Divider, null), /* @__PURE__ */ React28.createElement(TextStyleControl, null), /* @__PURE__ */ React28.createElement(TransformControl, null)))));
888
+ };
889
+
890
+ // src/components/style-sections/position-section/position-section.tsx
891
+ var React31 = __toESM(require("react"));
892
+ var import_ui18 = require("@elementor/ui");
893
+
894
+ // src/components/style-sections/position-section/z-index-control.tsx
895
+ var React30 = __toESM(require("react"));
896
+ var import_i18n12 = require("@wordpress/i18n");
897
+
898
+ // src/controls/control-types/number-control.tsx
899
+ var React29 = __toESM(require("react"));
900
+ var import_ui17 = require("@elementor/ui");
901
+ var isEmptyOrNaN = (value) => value === void 0 || value === "" || Number.isNaN(Number(value));
902
+ var NumberControl = ({ placeholder }) => {
903
+ const { value, setValue } = useControl();
904
+ const handleChange = (event) => {
905
+ const eventValue = event.target.value;
906
+ setValue(isEmptyOrNaN(eventValue) ? void 0 : Number(eventValue));
907
+ };
908
+ return /* @__PURE__ */ React29.createElement(
909
+ import_ui17.TextField,
910
+ {
911
+ size: "tiny",
912
+ type: "number",
913
+ value: isEmptyOrNaN(value) ? "" : value,
914
+ onChange: handleChange,
915
+ placeholder
916
+ }
917
+ );
918
+ };
919
+
920
+ // src/components/style-sections/position-section/z-index-control.tsx
921
+ var ZIndexControl = () => {
922
+ return /* @__PURE__ */ React30.createElement(StyleControl, { bind: "zIndex" }, /* @__PURE__ */ React30.createElement(ControlContainer, null, /* @__PURE__ */ React30.createElement(StyleControl.Label, null, (0, import_i18n12.__)("Z-Index", "elementor")), /* @__PURE__ */ React30.createElement(NumberControl, null)));
923
+ };
924
+
925
+ // src/components/style-sections/position-section/position-section.tsx
926
+ var import_i18n13 = require("@wordpress/i18n");
927
+ var PositionSection = () => {
928
+ return /* @__PURE__ */ React31.createElement(AccordionSection, { title: (0, import_i18n13.__)("Position", "elementor") }, /* @__PURE__ */ React31.createElement(import_ui18.Stack, { gap: 1.5 }, /* @__PURE__ */ React31.createElement(ZIndexControl, null)));
929
+ };
930
+
931
+ // src/components/style-sections/spacing-section/spacing-section.tsx
932
+ var React33 = __toESM(require("react"));
933
+ var import_ui20 = require("@elementor/ui");
934
+ var import_i18n15 = require("@wordpress/i18n");
935
+
936
+ // src/components/style-sections/spacing-section/linked-dimensions-control.tsx
937
+ var React32 = __toESM(require("react"));
938
+ var import_ui19 = require("@elementor/ui");
939
+ var import_icons5 = require("@elementor/icons");
940
+ var import_i18n14 = require("@wordpress/i18n");
941
+ var LinkedDimensionsControl = ({ label }) => {
942
+ const { value, setValue } = useControl();
943
+ const { top, right, bottom, left, isLinked = false } = value?.value || {};
944
+ const setLinkedValue = (position, newValue) => {
945
+ const updatedValue = {
946
+ isLinked,
947
+ top: isLinked ? newValue : top,
948
+ right: isLinked ? newValue : right,
949
+ bottom: isLinked ? newValue : bottom,
950
+ left: isLinked ? newValue : left,
951
+ [position]: newValue
952
+ };
953
+ setValue({
954
+ $$type: "linked-dimensions",
955
+ value: updatedValue
956
+ });
957
+ };
958
+ const toggleLinked = () => {
959
+ const updatedValue = {
960
+ isLinked: !isLinked,
961
+ top,
962
+ right: !isLinked ? top : right,
963
+ bottom: !isLinked ? top : bottom,
964
+ left: !isLinked ? top : left
965
+ };
966
+ setValue({
967
+ $$type: "linked-dimensions",
968
+ value: updatedValue
969
+ });
970
+ };
971
+ const LinkedIcon = isLinked ? import_icons5.LinkIcon : import_icons5.DetachIcon;
972
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(import_ui19.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React32.createElement(ControlLabel, null, label), /* @__PURE__ */ React32.createElement(
973
+ import_ui19.ToggleButton,
974
+ {
975
+ "aria-label": (0, import_i18n14.__)("Link Inputs", "elementor"),
976
+ size: "tiny",
977
+ value: "check",
978
+ selected: isLinked,
979
+ sx: { marginLeft: "auto" },
980
+ onChange: toggleLinked
981
+ },
982
+ /* @__PURE__ */ React32.createElement(LinkedIcon, { fontSize: "tiny" })
983
+ )), /* @__PURE__ */ React32.createElement(import_ui19.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React32.createElement(ControlContainer, { direction: "column" }, /* @__PURE__ */ React32.createElement(ControlLabel, null, (0, import_i18n14.__)("Top", "elementor")), /* @__PURE__ */ React32.createElement(
984
+ Control4,
985
+ {
986
+ bind: "top",
987
+ value: top,
988
+ setValue: setLinkedValue,
989
+ startIcon: /* @__PURE__ */ React32.createElement(import_icons5.SideTopIcon, { fontSize: "tiny" })
990
+ }
991
+ )), /* @__PURE__ */ React32.createElement(ControlContainer, { direction: "column" }, /* @__PURE__ */ React32.createElement(ControlLabel, null, (0, import_i18n14.__)("Right", "elementor")), /* @__PURE__ */ React32.createElement(
992
+ Control4,
993
+ {
994
+ bind: "right",
995
+ value: right,
996
+ setValue: setLinkedValue,
997
+ startIcon: /* @__PURE__ */ React32.createElement(import_icons5.SideRightIcon, { fontSize: "tiny" })
998
+ }
999
+ ))), /* @__PURE__ */ React32.createElement(import_ui19.Stack, { direction: "row", gap: 2 }, /* @__PURE__ */ React32.createElement(ControlContainer, { direction: "column" }, /* @__PURE__ */ React32.createElement(ControlLabel, null, (0, import_i18n14.__)("Bottom", "elementor")), /* @__PURE__ */ React32.createElement(
1000
+ Control4,
1001
+ {
1002
+ bind: "bottom",
1003
+ value: bottom,
1004
+ setValue: setLinkedValue,
1005
+ startIcon: /* @__PURE__ */ React32.createElement(import_icons5.SideBottomIcon, { fontSize: "tiny" })
1006
+ }
1007
+ )), /* @__PURE__ */ React32.createElement(ControlContainer, { direction: "column" }, /* @__PURE__ */ React32.createElement(ControlLabel, null, (0, import_i18n14.__)("Left", "elementor")), /* @__PURE__ */ React32.createElement(
1008
+ Control4,
1009
+ {
1010
+ bind: "left",
1011
+ value: left,
1012
+ setValue: setLinkedValue,
1013
+ startIcon: /* @__PURE__ */ React32.createElement(import_icons5.SideLeftIcon, { fontSize: "tiny" })
1014
+ }
1015
+ ))));
1016
+ };
1017
+ var Control4 = ({
1018
+ bind,
1019
+ startIcon,
1020
+ value,
1021
+ setValue
1022
+ }) => /* @__PURE__ */ React32.createElement(
1023
+ ControlContext.Provider,
1024
+ {
1025
+ value: {
1026
+ bind,
1027
+ setValue: (newValue) => setValue(bind, newValue),
1028
+ value
1029
+ }
1030
+ },
1031
+ /* @__PURE__ */ React32.createElement(SizeControl, { startIcon })
1032
+ );
1033
+
1034
+ // src/components/style-sections/spacing-section/spacing-section.tsx
1035
+ var SpacingSection = () => {
1036
+ return /* @__PURE__ */ React33.createElement(AccordionSection, { title: (0, import_i18n15.__)("Spacing", "elementor") }, /* @__PURE__ */ React33.createElement(import_ui20.Stack, { gap: 1.5 }, /* @__PURE__ */ React33.createElement(StyleControl, { bind: "padding" }, /* @__PURE__ */ React33.createElement(LinkedDimensionsControl, { label: (0, import_i18n15.__)("Padding", "elementor") })), /* @__PURE__ */ React33.createElement(import_ui20.Divider, null), /* @__PURE__ */ React33.createElement(StyleControl, { bind: "margin" }, /* @__PURE__ */ React33.createElement(LinkedDimensionsControl, { label: (0, import_i18n15.__)("Margin", "elementor") }))));
692
1037
  };
693
1038
 
694
1039
  // src/components/style-tab.tsx
1040
+ var CLASSES_PROP_KEY = "classes";
695
1041
  var StyleTab = () => {
1042
+ const styleDefinition = useStyleDefinition();
1043
+ const classesProp = useClassesProp();
1044
+ return /* @__PURE__ */ React34.createElement(StyleContext, { selectedStyleDef: styleDefinition, selectedClassesProp: classesProp }, /* @__PURE__ */ React34.createElement(import_ui21.Stack, null, /* @__PURE__ */ React34.createElement(SizeSection, null), /* @__PURE__ */ React34.createElement(PositionSection, null), /* @__PURE__ */ React34.createElement(TypographySection, null), /* @__PURE__ */ React34.createElement(SpacingSection, null)));
1045
+ };
1046
+ function useClassesProp() {
1047
+ const { elementType } = useElementContext();
1048
+ const prop = Object.entries(elementType.propsSchema).find(([, { type }]) => type.key === CLASSES_PROP_KEY);
1049
+ if (!prop) {
1050
+ throw new Error("Element does not have a classes prop");
1051
+ }
1052
+ return prop[0];
1053
+ }
1054
+ function useStyleDefinition() {
696
1055
  const { element } = useElementContext();
697
1056
  const elementStyles = useElementStyles(element.id);
698
- const [selectedStyleDef = null] = Object.values(elementStyles || {});
699
- return /* @__PURE__ */ React17.createElement(StyleContext, { selectedStyleDef }, /* @__PURE__ */ React17.createElement(import_ui14.Stack, null, /* @__PURE__ */ React17.createElement(SizeSection, null), /* @__PURE__ */ React17.createElement(TypographySection, null)));
700
- };
1057
+ return Object.values(elementStyles || {})[0] ?? null;
1058
+ }
701
1059
 
702
1060
  // src/components/editing-panel-tabs.tsx
703
1061
  var EditingPanelTabs = () => {
704
- const { getTabProps, getTabPanelProps, getTabsProps } = (0, import_ui15.useTabs)("settings");
705
- return /* @__PURE__ */ React18.createElement(import_ui15.Stack, { direction: "column", sx: { width: "100%" } }, /* @__PURE__ */ React18.createElement(import_ui15.Tabs, { variant: "fullWidth", indicatorColor: "secondary", textColor: "inherit", ...getTabsProps() }, /* @__PURE__ */ React18.createElement(import_ui15.Tab, { label: (0, import_i18n6.__)("General", "elementor"), ...getTabProps("settings") }), /* @__PURE__ */ React18.createElement(import_ui15.Tab, { label: (0, import_i18n6.__)("Style", "elementor"), ...getTabProps("style") })), /* @__PURE__ */ React18.createElement(import_ui15.TabPanel, { ...getTabPanelProps("settings"), disablePadding: true }, /* @__PURE__ */ React18.createElement(SettingsTab, null)), /* @__PURE__ */ React18.createElement(import_ui15.TabPanel, { ...getTabPanelProps("style"), disablePadding: true }, /* @__PURE__ */ React18.createElement(StyleTab, null)));
1062
+ const { getTabProps, getTabPanelProps, getTabsProps } = (0, import_ui22.useTabs)("settings");
1063
+ return /* @__PURE__ */ React35.createElement(import_ui22.Stack, { direction: "column", sx: { width: "100%" } }, /* @__PURE__ */ React35.createElement(import_ui22.Tabs, { variant: "fullWidth", indicatorColor: "secondary", textColor: "inherit", ...getTabsProps() }, /* @__PURE__ */ React35.createElement(import_ui22.Tab, { label: (0, import_i18n16.__)("General", "elementor"), ...getTabProps("settings") }), /* @__PURE__ */ React35.createElement(import_ui22.Tab, { label: (0, import_i18n16.__)("Style", "elementor"), ...getTabProps("style") })), /* @__PURE__ */ React35.createElement(import_ui22.TabPanel, { ...getTabPanelProps("settings"), disablePadding: true }, /* @__PURE__ */ React35.createElement(SettingsTab, null)), /* @__PURE__ */ React35.createElement(import_ui22.TabPanel, { ...getTabPanelProps("style"), disablePadding: true }, /* @__PURE__ */ React35.createElement(StyleTab, null)));
706
1064
  };
707
1065
 
708
1066
  // src/components/editing-panel.tsx
@@ -713,8 +1071,8 @@ var EditingPanel = () => {
713
1071
  if (elements.length !== 1 || !elementType) {
714
1072
  return null;
715
1073
  }
716
- const panelTitle = (0, import_i18n7.__)("Edit %s", "elementor").replace("%s", elementType.title);
717
- return /* @__PURE__ */ React19.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React19.createElement(import_editor_panels.PanelHeaderTitle, null, panelTitle)), /* @__PURE__ */ React19.createElement(import_editor_panels.PanelBody, null, /* @__PURE__ */ React19.createElement(ElementContext, { element: selectedElement }, /* @__PURE__ */ React19.createElement(EditingPanelTabs, null))));
1074
+ const panelTitle = (0, import_i18n17.__)("Edit %s", "elementor").replace("%s", elementType.title);
1075
+ return /* @__PURE__ */ React36.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React36.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React36.createElement(import_editor_panels.PanelHeaderTitle, null, panelTitle)), /* @__PURE__ */ React36.createElement(import_editor_panels.PanelBody, null, /* @__PURE__ */ React36.createElement(ElementContext, { element: selectedElement, elementType }, /* @__PURE__ */ React36.createElement(EditingPanelTabs, null))));
718
1076
  };
719
1077
 
720
1078
  // src/panel.ts
@@ -737,11 +1095,11 @@ var shouldUseV2Panel = () => {
737
1095
  };
738
1096
 
739
1097
  // src/hooks/use-open-editor-panel.ts
740
- var import_react7 = require("react");
1098
+ var import_react8 = require("react");
741
1099
  var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
742
1100
  var useOpenEditorPanel = () => {
743
1101
  const { open } = usePanelActions();
744
- (0, import_react7.useEffect)(() => {
1102
+ (0, import_react8.useEffect)(() => {
745
1103
  return (0, import_editor_v1_adapters8.__privateListenTo)((0, import_editor_v1_adapters8.commandStartEvent)("panel/editor/open"), () => {
746
1104
  if (shouldUseV2Panel()) {
747
1105
  open();
@@ -759,13 +1117,287 @@ var EditingPanelHooks = () => {
759
1117
  // src/init.ts
760
1118
  var import_editor_panels3 = require("@elementor/editor-panels");
761
1119
  var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
762
- function init() {
1120
+
1121
+ // src/dynamics/components/dynamic-selection-control.tsx
1122
+ var React39 = __toESM(require("react"));
1123
+ var import_react12 = require("react");
1124
+
1125
+ // src/dynamics/dynamic-control.tsx
1126
+ var React37 = __toESM(require("react"));
1127
+
1128
+ // src/dynamics/hooks/use-prop-dynamic-tags.ts
1129
+ var import_react9 = require("react");
1130
+
1131
+ // src/dynamics/sync/get-elementor-config.ts
1132
+ var getElementorConfig = () => {
1133
+ const extendedWindow = window;
1134
+ return extendedWindow.elementor?.config ?? {};
1135
+ };
1136
+
1137
+ // src/dynamics/sync/get-atomic-dynamic-tags.ts
1138
+ var getAtomicDynamicTags = () => {
1139
+ const { atomicDynamicTags } = getElementorConfig();
1140
+ if (!atomicDynamicTags) {
1141
+ return null;
1142
+ }
1143
+ return {
1144
+ tags: atomicDynamicTags.tags,
1145
+ groups: atomicDynamicTags.groups
1146
+ };
1147
+ };
1148
+
1149
+ // src/props/is-transformable.ts
1150
+ var import_schema = require("@elementor/schema");
1151
+ var transformableSchema = import_schema.z.object({
1152
+ $$type: import_schema.z.string(),
1153
+ value: import_schema.z.any()
1154
+ });
1155
+ var isTransformable = (value) => {
1156
+ return transformableSchema.safeParse(value).success;
1157
+ };
1158
+
1159
+ // src/dynamics/utils.ts
1160
+ var isDynamicType = (prop) => prop.key === "dynamic";
1161
+ var isDynamicPropValue = (prop) => {
1162
+ return isTransformable(prop) && prop.$$type === "dynamic";
1163
+ };
1164
+
1165
+ // src/dynamics/hooks/use-prop-dynamic-tags.ts
1166
+ var usePropDynamicTags = (propName) => {
1167
+ let categories = [];
1168
+ const { elementType } = useElementContext();
1169
+ const propSchema = elementType.propsSchema?.[propName];
1170
+ if (propSchema) {
1171
+ const propDynamicType = propSchema.additional_types.find(isDynamicType);
1172
+ categories = propDynamicType?.settings.categories || [];
1173
+ }
1174
+ return (0, import_react9.useMemo)(() => getDynamicTagsByCategories(categories), [categories.join()]);
1175
+ };
1176
+ var getDynamicTagsByCategories = (categories) => {
1177
+ const dynamicTags = getAtomicDynamicTags();
1178
+ if (!categories.length || !dynamicTags?.tags) {
1179
+ return [];
1180
+ }
1181
+ const _categories = new Set(categories);
1182
+ return Object.values(dynamicTags.tags).filter(
1183
+ (dynamicTag) => dynamicTag.categories.some((category) => _categories.has(category))
1184
+ );
1185
+ };
1186
+
1187
+ // src/dynamics/hooks/use-dynamic-tag.ts
1188
+ var import_react10 = require("react");
1189
+ var useDynamicTag = (propName, tagName) => {
1190
+ const dynamicTags = usePropDynamicTags(propName);
1191
+ return (0, import_react10.useMemo)(() => dynamicTags.find((tag) => tag.name === tagName) ?? null, [dynamicTags, tagName]);
1192
+ };
1193
+
1194
+ // src/dynamics/dynamic-control.tsx
1195
+ var DynamicControl = ({ bind, children }) => {
1196
+ const { value, setValue, bind: propName } = useControl();
1197
+ const { name = "", settings } = value?.value ?? {};
1198
+ const dynamicTag = useDynamicTag(propName, name);
1199
+ if (!dynamicTag) {
1200
+ throw new Error(`Dynamic tag ${name} not found`);
1201
+ }
1202
+ const defaultValue = dynamicTag.props_schema[bind]?.type.default;
1203
+ const dynamicValue = settings?.[bind] ?? defaultValue;
1204
+ const setDynamicValue = (newValue) => {
1205
+ setValue({
1206
+ $$type: "dynamic",
1207
+ value: {
1208
+ name,
1209
+ settings: {
1210
+ ...settings,
1211
+ [bind]: newValue
1212
+ }
1213
+ }
1214
+ });
1215
+ };
1216
+ return /* @__PURE__ */ React37.createElement(ControlContext.Provider, { value: { setValue: setDynamicValue, value: dynamicValue, bind } }, children);
1217
+ };
1218
+
1219
+ // src/dynamics/components/dynamic-selection-control.tsx
1220
+ var import_icons7 = require("@elementor/icons");
1221
+
1222
+ // src/dynamics/components/dynamic-selection.tsx
1223
+ var React38 = __toESM(require("react"));
1224
+ var import_react11 = require("react");
1225
+ var import_icons6 = require("@elementor/icons");
1226
+ var import_ui23 = require("@elementor/ui");
1227
+ var import_i18n18 = require("@wordpress/i18n");
1228
+ var SIZE = "tiny";
1229
+ var DynamicSelection = ({ onSelect }) => {
1230
+ const [searchValue, setSearchValue] = (0, import_react11.useState)("");
1231
+ const { groups: dynamicGroups } = getAtomicDynamicTags() || {};
1232
+ const { bind, value: dynamicValue, setValue } = useControl();
1233
+ const options2 = useFilteredOptions(bind, searchValue);
1234
+ const handleSearch = (event) => {
1235
+ setSearchValue(event.target.value);
1236
+ };
1237
+ return /* @__PURE__ */ React38.createElement(import_ui23.Stack, null, /* @__PURE__ */ React38.createElement(import_ui23.Box, { px: 1.5, pb: 1 }, /* @__PURE__ */ React38.createElement(
1238
+ import_ui23.TextField,
1239
+ {
1240
+ fullWidth: true,
1241
+ size: SIZE,
1242
+ value: searchValue,
1243
+ onChange: handleSearch,
1244
+ placeholder: (0, import_i18n18.__)("Search dynamic tag", "elementor"),
1245
+ InputProps: {
1246
+ startAdornment: /* @__PURE__ */ React38.createElement(import_ui23.InputAdornment, { position: "start" }, /* @__PURE__ */ React38.createElement(import_icons6.SearchIcon, { fontSize: SIZE }))
1247
+ }
1248
+ }
1249
+ )), /* @__PURE__ */ React38.createElement(import_ui23.Divider, null), /* @__PURE__ */ React38.createElement(import_ui23.Box, { sx: { overflowY: "auto", height: 260, width: 220 } }, options2.length > 0 ? /* @__PURE__ */ React38.createElement(import_ui23.MenuList, { role: "listbox", tabIndex: 0 }, options2.map(([category, items], index) => /* @__PURE__ */ React38.createElement(import_react11.Fragment, { key: index }, /* @__PURE__ */ React38.createElement(import_ui23.ListSubheader, { sx: { typography: "caption", color: "text.tertiary" } }, dynamicGroups?.[category]?.title || category), items.map(({ value, label: tagLabel }) => {
1250
+ const isSelected = value === dynamicValue?.value?.name;
1251
+ return /* @__PURE__ */ React38.createElement(
1252
+ import_ui23.MenuItem,
1253
+ {
1254
+ key: value,
1255
+ selected: isSelected,
1256
+ autoFocus: isSelected,
1257
+ sx: { typography: "caption" },
1258
+ onClick: () => {
1259
+ setValue({ $$type: "dynamic", value: { name: value } });
1260
+ onSelect?.();
1261
+ }
1262
+ },
1263
+ tagLabel
1264
+ );
1265
+ })))) : /* @__PURE__ */ React38.createElement(import_ui23.Stack, { alignItems: "center", p: 2.5, gap: 1.5 }, /* @__PURE__ */ React38.createElement(import_icons6.PhotoIcon, { fontSize: "large" }), /* @__PURE__ */ React38.createElement(import_ui23.Typography, { align: "center", variant: "caption", color: "text.secondary" }, (0, import_i18n18.__)("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React38.createElement("br", null), "\u201C", searchValue, "\u201D."), /* @__PURE__ */ React38.createElement(import_ui23.Typography, { align: "center", variant: "caption", color: "text.secondary" }, /* @__PURE__ */ React38.createElement(
1266
+ import_ui23.Link,
1267
+ {
1268
+ color: "secondary",
1269
+ variant: "caption",
1270
+ component: "button",
1271
+ onClick: () => setSearchValue("")
1272
+ },
1273
+ (0, import_i18n18.__)("Clear the filters", "elementor")
1274
+ ), "\xA0", (0, import_i18n18.__)("and try again.", "elementor")))));
1275
+ };
1276
+ var useFilteredOptions = (bind, searchValue) => {
1277
+ const dynamicTags = usePropDynamicTags(bind);
1278
+ const options2 = dynamicTags.reduce((categories, { name, label, group }) => {
1279
+ const isVisible = label.toLowerCase().includes(searchValue.trim().toLowerCase());
1280
+ if (!isVisible) {
1281
+ return categories;
1282
+ }
1283
+ if (!categories.has(group)) {
1284
+ categories.set(group, []);
1285
+ }
1286
+ categories.get(group)?.push({ label, value: name });
1287
+ return categories;
1288
+ }, /* @__PURE__ */ new Map());
1289
+ return [...options2];
1290
+ };
1291
+
1292
+ // src/dynamics/components/dynamic-selection-control.tsx
1293
+ var import_ui24 = require("@elementor/ui");
1294
+ var import_i18n19 = require("@wordpress/i18n");
1295
+ var SIZE2 = "tiny";
1296
+ var DynamicSelectionControl = () => {
1297
+ const { bind, value, setValue } = useControl();
1298
+ const { name: tagName = "" } = value?.value || {};
1299
+ const selectionPopoverId = (0, import_react12.useId)();
1300
+ const selectionPopoverState = (0, import_ui24.usePopupState)({ variant: "popover", popupId: selectionPopoverId });
1301
+ const dynamicTag = useDynamicTag(bind, tagName);
1302
+ const removeDynamicTag = () => {
1303
+ setValue(null);
1304
+ };
1305
+ if (!dynamicTag) {
1306
+ throw new Error(`Dynamic tag ${tagName} not found`);
1307
+ }
1308
+ return /* @__PURE__ */ React39.createElement(import_ui24.Box, { sx: { width: "100%" } }, /* @__PURE__ */ React39.createElement(
1309
+ import_ui24.UnstableTag,
1310
+ {
1311
+ fullWidth: true,
1312
+ showActionsOnHover: true,
1313
+ label: dynamicTag.label,
1314
+ startIcon: /* @__PURE__ */ React39.createElement(import_icons7.DatabaseIcon, { fontSize: SIZE2 }),
1315
+ ...(0, import_ui24.bindTrigger)(selectionPopoverState),
1316
+ actions: /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(DynamicSettingsPopover, { dynamicTag }), /* @__PURE__ */ React39.createElement(
1317
+ import_ui24.IconButton,
1318
+ {
1319
+ size: SIZE2,
1320
+ onClick: removeDynamicTag,
1321
+ "aria-label": (0, import_i18n19.__)("Remove dynamic value", "elementor")
1322
+ },
1323
+ /* @__PURE__ */ React39.createElement(import_icons7.XIcon, { fontSize: SIZE2 })
1324
+ ))
1325
+ }
1326
+ ), /* @__PURE__ */ React39.createElement(
1327
+ import_ui24.Popover,
1328
+ {
1329
+ disablePortal: true,
1330
+ disableScrollLock: true,
1331
+ anchorOrigin: { vertical: "bottom", horizontal: "left" },
1332
+ ...(0, import_ui24.bindPopover)(selectionPopoverState)
1333
+ },
1334
+ /* @__PURE__ */ React39.createElement(import_ui24.Stack, null, /* @__PURE__ */ React39.createElement(import_ui24.Stack, { direction: "row", alignItems: "center", pl: 1.5, pr: 0.5, py: 1.5 }, /* @__PURE__ */ React39.createElement(import_icons7.DatabaseIcon, { fontSize: SIZE2, sx: { mr: 0.5 } }), /* @__PURE__ */ React39.createElement(import_ui24.Typography, { variant: "subtitle2" }, (0, import_i18n19.__)("Dynamic Tags", "elementor")), /* @__PURE__ */ React39.createElement(import_ui24.IconButton, { size: SIZE2, sx: { ml: "auto" }, onClick: selectionPopoverState.close }, /* @__PURE__ */ React39.createElement(import_icons7.XIcon, { fontSize: SIZE2 }))), /* @__PURE__ */ React39.createElement(DynamicSelection, { onSelect: selectionPopoverState.close }))
1335
+ ));
1336
+ };
1337
+ var DynamicSettingsPopover = ({ dynamicTag }) => {
1338
+ const popupId = (0, import_react12.useId)();
1339
+ const settingsPopupState = (0, import_ui24.usePopupState)({ variant: "popover", popupId });
1340
+ const hasDynamicSettings = !!dynamicTag.atomic_controls.length;
1341
+ if (!hasDynamicSettings) {
1342
+ return null;
1343
+ }
1344
+ return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(
1345
+ import_ui24.IconButton,
1346
+ {
1347
+ size: SIZE2,
1348
+ ...(0, import_ui24.bindTrigger)(settingsPopupState),
1349
+ "aria-label": (0, import_i18n19.__)("Settings", "elementor")
1350
+ },
1351
+ /* @__PURE__ */ React39.createElement(import_icons7.SettingsIcon, { fontSize: SIZE2 })
1352
+ ), /* @__PURE__ */ React39.createElement(
1353
+ import_ui24.Popover,
1354
+ {
1355
+ disableScrollLock: true,
1356
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1357
+ ...(0, import_ui24.bindPopover)(settingsPopupState)
1358
+ },
1359
+ /* @__PURE__ */ React39.createElement(import_ui24.Paper, { component: import_ui24.Stack, sx: { minHeight: "300px", width: "220px" } }, /* @__PURE__ */ React39.createElement(import_ui24.Stack, { direction: "row", alignItems: "center", px: 1.5, pt: 2, pb: 1 }, /* @__PURE__ */ React39.createElement(import_icons7.DatabaseIcon, { fontSize: SIZE2, sx: { mr: 0.5 } }), /* @__PURE__ */ React39.createElement(import_ui24.Typography, { variant: "subtitle2" }, dynamicTag.label), /* @__PURE__ */ React39.createElement(import_ui24.IconButton, { sx: { ml: "auto" }, size: SIZE2, onClick: settingsPopupState.close }, /* @__PURE__ */ React39.createElement(import_icons7.XIcon, { fontSize: SIZE2 }))), /* @__PURE__ */ React39.createElement(DynamicSettings, { controls: dynamicTag.atomic_controls }))
1360
+ ));
1361
+ };
1362
+ var DynamicSettings = ({ controls }) => {
1363
+ const tabs = controls.filter(({ type }) => type === "section");
1364
+ const { getTabsProps, getTabProps, getTabPanelProps } = (0, import_ui24.useTabs)(0);
1365
+ if (!tabs.length) {
1366
+ return null;
1367
+ }
1368
+ return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(import_ui24.Tabs, { indicatorColor: "secondary", textColor: "secondary", ...getTabsProps() }, tabs.map(({ value }, index) => /* @__PURE__ */ React39.createElement(import_ui24.Tab, { key: index, label: value.label, sx: { px: 1, py: 0.5 }, ...getTabProps(index) }))), /* @__PURE__ */ React39.createElement(import_ui24.Divider, null), tabs.map(({ value }, index) => {
1369
+ return /* @__PURE__ */ React39.createElement(import_ui24.TabPanel, { key: index, sx: { flexGrow: 1 }, ...getTabPanelProps(index) }, /* @__PURE__ */ React39.createElement(import_ui24.Stack, { gap: 1, px: 2 }, value.items.map((item) => {
1370
+ if (item.type === "control") {
1371
+ return /* @__PURE__ */ React39.createElement(Control5, { key: item.value.bind, control: item.value });
1372
+ }
1373
+ return null;
1374
+ })));
1375
+ }));
1376
+ };
1377
+ var Control5 = ({ control }) => {
1378
+ if (!getControlByType(control.type)) {
1379
+ return null;
1380
+ }
1381
+ return /* @__PURE__ */ React39.createElement(DynamicControl, { bind: control.bind }, control.label ? /* @__PURE__ */ React39.createElement(ControlLabel, null, control.label) : null, /* @__PURE__ */ React39.createElement(Control, { type: control.type, props: control.props }));
1382
+ };
1383
+
1384
+ // src/dynamics/init.ts
1385
+ var init = () => {
1386
+ replaceControl({
1387
+ component: DynamicSelectionControl,
1388
+ condition: ({ value }) => isDynamicPropValue(value)
1389
+ });
1390
+ };
1391
+
1392
+ // src/init.ts
1393
+ function init2() {
763
1394
  (0, import_editor_panels3.__registerPanel)(panel);
764
1395
  blockV1Panel();
765
1396
  (0, import_editor.injectIntoLogic)({
766
1397
  id: "editing-panel-hooks",
767
1398
  component: EditingPanelHooks
768
1399
  });
1400
+ init();
769
1401
  }
770
1402
  var blockV1Panel = () => {
771
1403
  (0, import_editor_v1_adapters9.__privateBlockDataCommand)({
@@ -775,5 +1407,10 @@ var blockV1Panel = () => {
775
1407
  };
776
1408
 
777
1409
  // src/index.ts
778
- init();
1410
+ init2();
1411
+ // Annotate the CommonJS export names for ESM import in node:
1412
+ 0 && (module.exports = {
1413
+ replaceControl,
1414
+ useControl
1415
+ });
779
1416
  //# sourceMappingURL=index.js.map