@elementor/editor-editing-panel 0.14.2 → 0.15.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 (34) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/index.d.mts +29 -1
  3. package/dist/index.d.ts +29 -1
  4. package/dist/index.js +327 -263
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +309 -259
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +4 -4
  9. package/src/components/editing-panel.tsx +1 -1
  10. package/src/components/settings-tab.tsx +6 -17
  11. package/src/components/style-sections/size-section.tsx +5 -6
  12. package/src/components/style-sections/typography-section/font-size-control.tsx +16 -0
  13. package/src/components/style-sections/typography-section/font-weight-control.tsx +24 -0
  14. package/src/{controls/control-types → components/style-sections/typography-section}/text-style-control.tsx +16 -14
  15. package/src/components/style-sections/typography-section/typography-section.tsx +20 -0
  16. package/src/components/style-tab.tsx +1 -1
  17. package/src/contexts/element-context.tsx +5 -3
  18. package/src/controls/components/control-container.tsx +18 -0
  19. package/src/controls/control-replacement.ts +26 -0
  20. package/src/controls/control-types/image-control.tsx +3 -18
  21. package/src/controls/control-types/size-control.tsx +4 -2
  22. package/src/controls/control-types/text-area-control.tsx +1 -1
  23. package/src/controls/control.tsx +50 -0
  24. package/src/controls/{get-control-by-type.ts → controls-registry.tsx} +13 -9
  25. package/src/controls/settings-control.tsx +8 -21
  26. package/src/hooks/use-dynamic-tags-config.ts +35 -0
  27. package/src/hooks/use-element-type.ts +5 -0
  28. package/src/index.ts +3 -0
  29. package/src/sync/get-atomic-dynamic-tags.ts +14 -0
  30. package/src/sync/get-elementor-config.ts +7 -0
  31. package/src/sync/types.ts +15 -1
  32. package/src/types.ts +14 -0
  33. package/LICENSE +0 -674
  34. package/src/components/style-sections/typography-section.tsx +0 -15
package/dist/index.mjs CHANGED
@@ -1,9 +1,34 @@
1
+ // src/controls/control-replacement.ts
2
+ var controlReplacement;
3
+ var replaceControl = ({ component, condition }) => {
4
+ controlReplacement = { component, condition };
5
+ };
6
+ var getControlReplacement = ({ value }) => {
7
+ let shouldReplace = false;
8
+ try {
9
+ shouldReplace = !!controlReplacement?.condition({ value });
10
+ } catch {
11
+ }
12
+ return shouldReplace ? controlReplacement?.component : void 0;
13
+ };
14
+
15
+ // src/controls/control-context.tsx
16
+ import { createContext, useContext } from "react";
17
+ var ControlContext = createContext(null);
18
+ function useControl(defaultValue) {
19
+ const controlContext = useContext(ControlContext);
20
+ if (!controlContext) {
21
+ throw new Error("useControl must be used within a ControlContext");
22
+ }
23
+ return { ...controlContext, value: controlContext.value ?? defaultValue };
24
+ }
25
+
1
26
  // src/panel.ts
2
27
  import { __createPanel as createPanel } from "@elementor/editor-panels";
3
28
 
4
29
  // src/components/editing-panel.tsx
5
- import * as React19 from "react";
6
- import { __ as __7 } from "@wordpress/i18n";
30
+ import * as React23 from "react";
31
+ import { __ as __9 } from "@wordpress/i18n";
7
32
 
8
33
  // src/hooks/use-selected-elements.ts
9
34
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
@@ -54,9 +79,13 @@ function useElementType(type) {
54
79
  if (!elementType?.atomic_controls) {
55
80
  return null;
56
81
  }
82
+ if (!elementType?.atomic_props_schema) {
83
+ return null;
84
+ }
57
85
  return {
58
86
  key: type,
59
87
  controls: elementType.atomic_controls,
88
+ propsSchema: elementType.atomic_props_schema,
60
89
  title: elementType.title
61
90
  };
62
91
  },
@@ -69,13 +98,13 @@ import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from "@elementor/edit
69
98
 
70
99
  // src/contexts/element-context.tsx
71
100
  import * as React from "react";
72
- import { createContext, useContext } from "react";
73
- var Context = createContext(null);
74
- function ElementContext({ children, element }) {
75
- return /* @__PURE__ */ React.createElement(Context.Provider, { value: { element } }, children);
101
+ import { createContext as createContext2, useContext as useContext2 } from "react";
102
+ var Context = createContext2(null);
103
+ function ElementContext({ children, element, elementType }) {
104
+ return /* @__PURE__ */ React.createElement(Context.Provider, { value: { element, elementType } }, children);
76
105
  }
77
106
  function useElementContext() {
78
- const context = useContext(Context);
107
+ const context = useContext2(Context);
79
108
  if (!context) {
80
109
  throw new Error("useElementContext must be used within a ElementContextProvider");
81
110
  }
@@ -83,30 +112,16 @@ function useElementContext() {
83
112
  }
84
113
 
85
114
  // src/components/editing-panel-tabs.tsx
86
- import { Stack as Stack10, Tabs, Tab, TabPanel, useTabs } from "@elementor/ui";
87
- import * as React18 from "react";
88
- import { __ as __6 } from "@wordpress/i18n";
115
+ import { Stack as Stack9, Tabs, Tab, TabPanel, useTabs } from "@elementor/ui";
116
+ import * as React22 from "react";
117
+ import { __ as __8 } from "@wordpress/i18n";
89
118
 
90
119
  // src/components/settings-tab.tsx
91
- import * as React9 from "react";
92
- import { Stack as Stack3 } from "@elementor/ui";
93
-
94
- // src/controls/settings-control.tsx
95
- import * as React3 from "react";
96
-
97
- // src/controls/control-context.tsx
98
- import { createContext as createContext2, useContext as useContext2 } from "react";
99
- var ControlContext = createContext2(null);
100
- function useControl(defaultValue) {
101
- const controlContext = useContext2(ControlContext);
102
- if (!controlContext) {
103
- throw new Error("useControl must be used within a ControlContext");
104
- }
105
- return { ...controlContext, value: controlContext.value ?? defaultValue };
106
- }
120
+ import * as React12 from "react";
121
+ import { Stack as Stack4 } from "@elementor/ui";
107
122
 
108
123
  // src/controls/settings-control.tsx
109
- import { Stack, styled } from "@elementor/ui";
124
+ import * as React4 from "react";
110
125
 
111
126
  // src/hooks/use-widget-settings.ts
112
127
  import { commandEndEvent as commandEndEvent3, __privateUseListenTo as useListenTo3 } from "@elementor/editor-v1-adapters";
@@ -150,10 +165,28 @@ var ControlLabel = ({ children }) => {
150
165
  return /* @__PURE__ */ React2.createElement(Typography, { component: "label", variant: "caption", color: "text.secondary" }, children);
151
166
  };
152
167
 
168
+ // src/controls/components/control-container.tsx
169
+ import * as React3 from "react";
170
+ import { Stack, styled } from "@elementor/ui";
171
+ var StyledStack = styled(Stack)(({ theme, gap, direction }) => ({
172
+ "> :only-child": {
173
+ width: "100%"
174
+ },
175
+ "&:where( :has( > :nth-child( 2 ):last-child ) ) > :where( * )": {
176
+ width: direction === "column" ? "100%" : `calc( 50% - ${theme.spacing(gap / 2)})`
177
+ },
178
+ "&:where( :has( > :nth-child( 3 ):last-child ) ) > :where( * )": {
179
+ width: direction === "column" ? "100%" : `calc( 33.3333% - ${theme.spacing(gap * 2)} / 3)`
180
+ }
181
+ }));
182
+ var ControlContainer = (props) => /* @__PURE__ */ React3.createElement(StyledStack, { gap: 1, direction: "row", alignItems: "center", justifyContent: "space-between", ...props });
183
+
153
184
  // src/controls/settings-control.tsx
154
185
  var SettingsControlProvider = ({ bind, children }) => {
155
- const { element } = useElementContext();
156
- const value = useWidgetSettings({ id: element.id, bind });
186
+ const { element, elementType } = useElementContext();
187
+ const defaultValue = elementType.propsSchema[bind]?.default;
188
+ const settingsValue = useWidgetSettings({ id: element.id, bind });
189
+ const value = settingsValue ?? defaultValue ?? null;
157
190
  const setValue = (newValue) => {
158
191
  updateSettings({
159
192
  id: element.id,
@@ -162,97 +195,36 @@ var SettingsControlProvider = ({ bind, children }) => {
162
195
  }
163
196
  });
164
197
  };
165
- return /* @__PURE__ */ React3.createElement(ControlContext.Provider, { value: { setValue, value, bind } }, children);
166
- };
167
- var SettingsControl = ({ children, bind }) => /* @__PURE__ */ React3.createElement(SettingsControlProvider, { bind }, /* @__PURE__ */ React3.createElement(StyledStack, { direction: "row", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap" }, children));
168
- var StyledStack = styled(Stack)(({ theme }) => {
169
- const gap = theme.spacing(1);
170
- return {
171
- gap,
172
- "& > *": {
173
- width: `calc(50% - ${gap} / 2)`
174
- },
175
- "& > label": {
176
- flexShrink: 0
177
- }
178
- };
179
- });
198
+ return /* @__PURE__ */ React4.createElement(ControlContext.Provider, { value: { setValue, value, bind } }, children);
199
+ };
200
+ var SettingsControl = ({ children, bind }) => /* @__PURE__ */ React4.createElement(SettingsControlProvider, { bind }, /* @__PURE__ */ React4.createElement(ControlContainer, { flexWrap: "wrap" }, children));
180
201
  SettingsControl.Label = ControlLabel;
181
202
 
182
203
  // src/components/accordion-section.tsx
183
- import * as React4 from "react";
204
+ import * as React5 from "react";
184
205
  import { useId } from "react";
185
206
  import { Accordion, AccordionSummary, AccordionDetails, AccordionSummaryText, Stack as Stack2 } from "@elementor/ui";
186
207
  var AccordionSection = ({ title, children }) => {
187
208
  const uid = useId();
188
209
  const labelId = `label-${uid}`;
189
210
  const contentId = `content-${uid}`;
190
- return /* @__PURE__ */ React4.createElement(Accordion, { disableGutters: true, defaultExpanded: true }, /* @__PURE__ */ React4.createElement(AccordionSummary, { "aria-controls": contentId, id: labelId }, /* @__PURE__ */ React4.createElement(AccordionSummaryText, { primaryTypographyProps: { variant: "caption" } }, title)), /* @__PURE__ */ React4.createElement(AccordionDetails, { id: contentId, "aria-labelledby": labelId }, /* @__PURE__ */ React4.createElement(Stack2, { gap: 2.5 }, children)));
211
+ return /* @__PURE__ */ React5.createElement(Accordion, { disableGutters: true, defaultExpanded: true }, /* @__PURE__ */ React5.createElement(AccordionSummary, { "aria-controls": contentId, id: labelId }, /* @__PURE__ */ React5.createElement(AccordionSummaryText, { primaryTypographyProps: { variant: "caption" } }, title)), /* @__PURE__ */ React5.createElement(AccordionDetails, { id: contentId, "aria-labelledby": labelId }, /* @__PURE__ */ React5.createElement(Stack2, { gap: 2.5 }, children)));
191
212
  };
192
213
 
193
- // src/controls/control-types/select-control.tsx
194
- import * as React5 from "react";
195
- import { MenuItem, Select } from "@elementor/ui";
196
- var SelectControl = ({ options }) => {
197
- const { value, setValue } = useControl();
198
- const handleChange = (event) => {
199
- setValue(event.target.value);
200
- };
201
- return /* @__PURE__ */ React5.createElement(Select, { size: "tiny", value: value ?? "", onChange: handleChange }, options.map(({ label, ...props }) => /* @__PURE__ */ React5.createElement(MenuItem, { key: props.value, ...props }, label)));
202
- };
203
-
204
- // src/controls/control-types/text-area-control.tsx
205
- import * as React6 from "react";
206
- import { TextField } from "@elementor/ui";
207
- var TextAreaControl = ({ placeholder }) => {
208
- const { value, setValue } = useControl("");
209
- const handleChange = (event) => {
210
- setValue(event.target.value);
211
- };
212
- return /* @__PURE__ */ React6.createElement(
213
- TextField,
214
- {
215
- size: "tiny",
216
- multiline: true,
217
- fullWidth: true,
218
- rows: 5,
219
- value,
220
- onChange: handleChange,
221
- placeholder
222
- }
223
- );
224
- };
225
-
226
- // src/controls/control-types/text-control.tsx
227
- import * as React7 from "react";
228
- import { TextField as TextField2 } from "@elementor/ui";
229
- var TextControl = ({ placeholder }) => {
230
- const { value, setValue } = useControl("");
231
- const handleChange = (event) => setValue(event.target.value);
232
- return /* @__PURE__ */ React7.createElement(TextField2, { type: "text", size: "tiny", value, onChange: handleChange, placeholder });
233
- };
214
+ // src/controls/control.tsx
215
+ import * as React11 from "react";
216
+ import { createError } from "@elementor/utils";
234
217
 
235
218
  // src/controls/control-types/image-control.tsx
236
- import * as React8 from "react";
219
+ import * as React6 from "react";
237
220
  import { Button, Card, CardMedia, CardOverlay } from "@elementor/ui";
238
221
  import { UploadIcon } from "@elementor/icons";
239
222
  import { __ } from "@wordpress/i18n";
240
223
  import { useWpMediaAttachment, useWpMediaFrame } from "@elementor/wp-media";
241
- var defaultState = {
242
- $$type: "image",
243
- value: {
244
- url: "/wp-content/plugins/elementor/assets/images/placeholder.png"
245
- }
246
- };
247
224
  var ImageControl = () => {
248
- const { value, setValue } = useControl(defaultState);
225
+ const { value, setValue } = useControl();
249
226
  const { data: attachment } = useWpMediaAttachment(value?.value?.attachmentId);
250
- const getImageSrc = () => {
251
- if (attachment?.url) {
252
- return attachment.url;
253
- }
254
- return value?.value?.url ?? defaultState.value.url;
255
- };
227
+ const src = attachment?.url ?? value?.value?.url;
256
228
  const { open } = useWpMediaFrame({
257
229
  types: ["image"],
258
230
  multiple: false,
@@ -266,7 +238,7 @@ var ImageControl = () => {
266
238
  });
267
239
  }
268
240
  });
269
- return /* @__PURE__ */ React8.createElement(Card, { variant: "outlined" }, /* @__PURE__ */ React8.createElement(CardMedia, { image: getImageSrc(), sx: { height: 150 } }), /* @__PURE__ */ React8.createElement(CardOverlay, null, /* @__PURE__ */ React8.createElement(
241
+ return /* @__PURE__ */ React6.createElement(Card, { variant: "outlined" }, /* @__PURE__ */ React6.createElement(CardMedia, { image: src, sx: { height: 150 } }), /* @__PURE__ */ React6.createElement(CardOverlay, null, /* @__PURE__ */ React6.createElement(
270
242
  Button,
271
243
  {
272
244
  color: "inherit",
@@ -277,13 +249,13 @@ var ImageControl = () => {
277
249
  }
278
250
  },
279
251
  __("Select Image", "elementor")
280
- ), /* @__PURE__ */ React8.createElement(
252
+ ), /* @__PURE__ */ React6.createElement(
281
253
  Button,
282
254
  {
283
255
  color: "inherit",
284
256
  size: "small",
285
257
  variant: "text",
286
- startIcon: /* @__PURE__ */ React8.createElement(UploadIcon, null),
258
+ startIcon: /* @__PURE__ */ React6.createElement(UploadIcon, null),
287
259
  onClick: () => {
288
260
  open({ mode: "upload" });
289
261
  }
@@ -292,32 +264,180 @@ var ImageControl = () => {
292
264
  )));
293
265
  };
294
266
 
295
- // src/controls/get-control-by-type.ts
267
+ // src/controls/control-types/text-control.tsx
268
+ import * as React7 from "react";
269
+ import { TextField } from "@elementor/ui";
270
+ var TextControl = ({ placeholder }) => {
271
+ const { value, setValue } = useControl("");
272
+ const handleChange = (event) => setValue(event.target.value);
273
+ return /* @__PURE__ */ React7.createElement(TextField, { type: "text", size: "tiny", value, onChange: handleChange, placeholder });
274
+ };
275
+
276
+ // src/controls/control-types/text-area-control.tsx
277
+ import * as React8 from "react";
278
+ import { TextField as TextField2 } from "@elementor/ui";
279
+ var TextAreaControl = ({ placeholder }) => {
280
+ const { value, setValue } = useControl();
281
+ const handleChange = (event) => {
282
+ setValue(event.target.value);
283
+ };
284
+ return /* @__PURE__ */ React8.createElement(
285
+ TextField2,
286
+ {
287
+ size: "tiny",
288
+ multiline: true,
289
+ fullWidth: true,
290
+ rows: 5,
291
+ value,
292
+ onChange: handleChange,
293
+ placeholder
294
+ }
295
+ );
296
+ };
297
+
298
+ // src/controls/control-types/size-control.tsx
299
+ import * as React9 from "react";
300
+ import { MenuItem, Select, Stack as Stack3, TextField as TextField3 } from "@elementor/ui";
301
+
302
+ // src/controls/hooks/use-sync-external-state.tsx
303
+ import { useEffect, useState } from "react";
304
+ var useSyncExternalState = ({
305
+ external,
306
+ setExternal,
307
+ persistWhen,
308
+ fallback
309
+ }) => {
310
+ function toExternal(internalValue) {
311
+ if (persistWhen(internalValue)) {
312
+ return internalValue;
313
+ }
314
+ return void 0;
315
+ }
316
+ function toInternal(externalValue, internalValue) {
317
+ if (!externalValue) {
318
+ return fallback(internalValue);
319
+ }
320
+ return externalValue;
321
+ }
322
+ const [internal, setInternal] = useState(toInternal(external, void 0));
323
+ useEffect(() => {
324
+ setInternal((prevInternal) => toInternal(external, prevInternal));
325
+ }, [external]);
326
+ const setInternalValue = (setter) => {
327
+ const setterFn = typeof setter === "function" ? setter : () => setter;
328
+ const updated = setterFn(internal);
329
+ setInternal(updated);
330
+ setExternal(toExternal(updated));
331
+ };
332
+ return [internal, setInternalValue];
333
+ };
334
+
335
+ // src/controls/control-types/size-control.tsx
336
+ var defaultUnits = ["px", "%", "em", "rem", "vw"];
337
+ var SizeControl = ({ units = defaultUnits, placeholder }) => {
338
+ const { value, setValue } = useControl();
339
+ const [state, setState] = useSyncExternalState({
340
+ external: value,
341
+ setExternal: setValue,
342
+ persistWhen: (controlValue) => !!controlValue?.value.size || controlValue?.value.size === 0,
343
+ fallback: (controlValue) => ({
344
+ $$type: "size",
345
+ value: { unit: controlValue?.value.unit || "px", size: NaN }
346
+ })
347
+ });
348
+ const handleUnitChange = (event) => {
349
+ const unit = event.target.value;
350
+ setState((prev) => ({
351
+ ...prev,
352
+ value: {
353
+ ...prev.value,
354
+ unit
355
+ }
356
+ }));
357
+ };
358
+ const handleSizeChange = (event) => {
359
+ const { value: size } = event.target;
360
+ setState((prev) => ({
361
+ ...prev,
362
+ value: {
363
+ ...prev.value,
364
+ size: size || size === "0" ? parseFloat(size) : NaN
365
+ }
366
+ }));
367
+ };
368
+ return /* @__PURE__ */ React9.createElement(Stack3, { direction: "row" }, /* @__PURE__ */ React9.createElement(
369
+ TextField3,
370
+ {
371
+ size: "tiny",
372
+ type: "number",
373
+ value: Number.isNaN(state.value.size) ? "" : state.value.size,
374
+ onChange: handleSizeChange,
375
+ placeholder
376
+ }
377
+ ), /* @__PURE__ */ React9.createElement(
378
+ Select,
379
+ {
380
+ size: "tiny",
381
+ value: state.value.unit,
382
+ onChange: handleUnitChange,
383
+ MenuProps: {
384
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
385
+ transformOrigin: { vertical: "top", horizontal: "right" }
386
+ }
387
+ },
388
+ units.map((unit) => /* @__PURE__ */ React9.createElement(MenuItem, { key: unit, value: unit }, unit.toUpperCase()))
389
+ ));
390
+ };
391
+
392
+ // src/controls/control-types/select-control.tsx
393
+ import * as React10 from "react";
394
+ import { MenuItem as MenuItem2, Select as Select2 } from "@elementor/ui";
395
+ var SelectControl = ({ options }) => {
396
+ const { value, setValue } = useControl();
397
+ const handleChange = (event) => {
398
+ setValue(event.target.value);
399
+ };
400
+ return /* @__PURE__ */ React10.createElement(Select2, { size: "tiny", value: value ?? "", onChange: handleChange }, options.map(({ label, ...props }) => /* @__PURE__ */ React10.createElement(MenuItem2, { key: props.value, ...props }, label)));
401
+ };
402
+
403
+ // src/controls/controls-registry.tsx
296
404
  var controlTypes = {
297
405
  image: ImageControl,
298
- select: SelectControl,
299
406
  text: TextControl,
300
- textarea: TextAreaControl
407
+ textarea: TextAreaControl,
408
+ size: SizeControl,
409
+ select: SelectControl
301
410
  };
302
- var getControlByType = (type) => {
303
- return controlTypes[type] ?? null;
411
+ var getControlByType = (type) => controlTypes[type];
412
+
413
+ // src/controls/control.tsx
414
+ var ControlTypeError = createError({
415
+ code: "CONTROL_TYPE_NOT_FOUND",
416
+ message: `Control type not found.`
417
+ });
418
+ var Control = ({ props, type }) => {
419
+ const { value } = useControl();
420
+ const ControlByType = getControlByType(type);
421
+ if (!ControlByType) {
422
+ throw new ControlTypeError({
423
+ context: { type }
424
+ });
425
+ }
426
+ const ControlComponent = getControlReplacement({ value }) || ControlByType;
427
+ return /* @__PURE__ */ React11.createElement(ControlComponent, { ...props });
304
428
  };
305
429
 
306
430
  // src/components/settings-tab.tsx
307
431
  var SettingsTab = () => {
308
- const { element } = useElementContext();
309
- const elementType = useElementType(element?.type);
310
- if (!elementType) {
311
- return null;
312
- }
313
- return /* @__PURE__ */ React9.createElement(Stack3, null, elementType.controls.map(({ type, value }, index) => {
432
+ const { elementType } = useElementContext();
433
+ return /* @__PURE__ */ React12.createElement(Stack4, null, elementType.controls.map(({ type, value }, index) => {
314
434
  if (type === "control") {
315
- return /* @__PURE__ */ React9.createElement(Control, { key: value.bind, control: value });
435
+ return /* @__PURE__ */ React12.createElement(Control2, { key: value.bind, control: value });
316
436
  }
317
437
  if (type === "section") {
318
- return /* @__PURE__ */ React9.createElement(AccordionSection, { key: type + "." + index, title: value.label }, value.items?.map((item) => {
438
+ return /* @__PURE__ */ React12.createElement(AccordionSection, { key: type + "." + index, title: value.label }, value.items?.map((item) => {
319
439
  if (item.type === "control") {
320
- return /* @__PURE__ */ React9.createElement(Control, { key: item.value.bind, control: item.value });
440
+ return /* @__PURE__ */ React12.createElement(Control2, { key: item.value.bind, control: item.value });
321
441
  }
322
442
  return null;
323
443
  }));
@@ -325,31 +445,25 @@ var SettingsTab = () => {
325
445
  return null;
326
446
  }));
327
447
  };
328
- var Control = ({ control }) => {
329
- const ControlComponent = getControlByType(control.type);
330
- if (!ControlComponent) {
448
+ var Control2 = ({ control }) => {
449
+ if (!getControlByType(control.type)) {
331
450
  return null;
332
451
  }
333
- return /* @__PURE__ */ React9.createElement(SettingsControl, { bind: control.bind }, control.label ? /* @__PURE__ */ React9.createElement(SettingsControl.Label, null, control.label) : null, /* @__PURE__ */ React9.createElement(
334
- ControlComponent,
335
- {
336
- ...control.props
337
- }
338
- ));
452
+ return /* @__PURE__ */ React12.createElement(SettingsControl, { bind: control.bind }, control.label ? /* @__PURE__ */ React12.createElement(SettingsControl.Label, null, control.label) : null, /* @__PURE__ */ React12.createElement(Control, { type: control.type, props: control.props }));
339
453
  };
340
454
 
341
455
  // src/components/style-tab.tsx
342
- import * as React17 from "react";
456
+ import * as React21 from "react";
343
457
 
344
458
  // src/contexts/style-context.tsx
345
- import * as React10 from "react";
459
+ import * as React13 from "react";
346
460
  import { createContext as createContext3, useContext as useContext3 } from "react";
347
461
  import { useActiveBreakpoint } from "@elementor/editor-responsive";
348
462
  var Context2 = createContext3(null);
349
463
  function StyleContext({ children, selectedStyleDef }) {
350
464
  const breakpoint = useActiveBreakpoint();
351
465
  const selectedMeta = { breakpoint, state: null };
352
- return /* @__PURE__ */ React10.createElement(Context2.Provider, { value: { selectedStyleDef, selectedMeta } }, children);
466
+ return /* @__PURE__ */ React13.createElement(Context2.Provider, { value: { selectedStyleDef, selectedMeta } }, children);
353
467
  }
354
468
  function useStyleContext() {
355
469
  const context = useContext3(Context2);
@@ -380,13 +494,13 @@ var useElementStyles = (elementID) => {
380
494
  };
381
495
 
382
496
  // src/components/style-tab.tsx
383
- import { Stack as Stack9 } from "@elementor/ui";
497
+ import { Stack as Stack8 } from "@elementor/ui";
384
498
 
385
499
  // src/components/style-sections/size-section.tsx
386
- import * as React14 from "react";
500
+ import * as React16 from "react";
387
501
 
388
502
  // src/controls/style-control.tsx
389
- import * as React11 from "react";
503
+ import * as React14 from "react";
390
504
 
391
505
  // src/hooks/use-element-style-prop.ts
392
506
  import { commandEndEvent as commandEndEvent5, __privateUseListenTo as useListenTo5 } from "@elementor/editor-v1-adapters";
@@ -455,22 +569,22 @@ var useStyleControl = (propName) => {
455
569
  // src/controls/style-control.tsx
456
570
  var StyleControl = ({ bind, children }) => {
457
571
  const [value, setValue] = useStyleControl(bind);
458
- return /* @__PURE__ */ React11.createElement(ControlContext.Provider, { value: { bind, value, setValue } }, children);
572
+ return /* @__PURE__ */ React14.createElement(ControlContext.Provider, { value: { bind, value, setValue } }, children);
459
573
  };
460
574
  StyleControl.Label = ControlLabel;
461
575
 
462
576
  // src/components/collapsible-content.tsx
463
- import * as React12 from "react";
464
- import { useState } from "react";
577
+ import * as React15 from "react";
578
+ import { useState as useState2 } from "react";
465
579
  import { ChevronDownIcon } from "@elementor/icons";
466
- import { Button as Button2, Collapse, Stack as Stack4, styled as styled2 } from "@elementor/ui";
580
+ import { Button as Button2, Collapse, Stack as Stack5, styled as styled2 } from "@elementor/ui";
467
581
  import { __ as __2 } from "@wordpress/i18n";
468
582
  var CollapsibleContent = ({ children, defaultOpen = false }) => {
469
- const [open, setOpen] = useState(defaultOpen);
583
+ const [open, setOpen] = useState2(defaultOpen);
470
584
  const handleToggle = () => {
471
585
  setOpen((prevOpen) => !prevOpen);
472
586
  };
473
- return /* @__PURE__ */ React12.createElement(Stack4, { sx: { py: 0.5 } }, /* @__PURE__ */ React12.createElement(
587
+ return /* @__PURE__ */ React15.createElement(Stack5, { sx: { py: 0.5 } }, /* @__PURE__ */ React15.createElement(
474
588
  Button2,
475
589
  {
476
590
  fullWidth: true,
@@ -478,10 +592,10 @@ var CollapsibleContent = ({ children, defaultOpen = false }) => {
478
592
  color: "secondary",
479
593
  variant: "outlined",
480
594
  onClick: handleToggle,
481
- endIcon: /* @__PURE__ */ React12.createElement(ChevronIcon, { open })
595
+ endIcon: /* @__PURE__ */ React15.createElement(ChevronIcon, { open })
482
596
  },
483
597
  open ? __2("Show less", "elementor") : __2("Show more", "elementor")
484
- ), /* @__PURE__ */ React12.createElement(Collapse, { in: open, timeout: "auto" }, children));
598
+ ), /* @__PURE__ */ React15.createElement(Collapse, { in: open, timeout: "auto" }, children));
485
599
  };
486
600
  var ChevronIcon = styled2(ChevronDownIcon, {
487
601
  shouldForwardProp: (prop) => prop !== "open"
@@ -492,131 +606,40 @@ var ChevronIcon = styled2(ChevronDownIcon, {
492
606
  })
493
607
  }));
494
608
 
495
- // src/controls/control-types/size-control.tsx
496
- import * as React13 from "react";
497
- import { MenuItem as MenuItem2, Select as Select2, Stack as Stack5, TextField as TextField3 } from "@elementor/ui";
498
-
499
- // src/controls/hooks/use-sync-external-state.tsx
500
- import { useEffect, useState as useState2 } from "react";
501
- var useSyncExternalState = ({
502
- external,
503
- setExternal,
504
- persistWhen,
505
- fallback
506
- }) => {
507
- function toExternal(internalValue) {
508
- if (persistWhen(internalValue)) {
509
- return internalValue;
510
- }
511
- return void 0;
512
- }
513
- function toInternal(externalValue, internalValue) {
514
- if (!externalValue) {
515
- return fallback(internalValue);
516
- }
517
- return externalValue;
518
- }
519
- const [internal, setInternal] = useState2(toInternal(external, void 0));
520
- useEffect(() => {
521
- setInternal((prevInternal) => toInternal(external, prevInternal));
522
- }, [external]);
523
- const setInternalValue = (setter) => {
524
- const setterFn = typeof setter === "function" ? setter : () => setter;
525
- const updated = setterFn(internal);
526
- setInternal(updated);
527
- setExternal(toExternal(updated));
528
- };
529
- return [internal, setInternalValue];
530
- };
531
-
532
- // src/controls/control-types/size-control.tsx
533
- var SizeControl = ({ units: units2, placeholder }) => {
534
- const { value, setValue } = useControl();
535
- const [state, setState] = useSyncExternalState({
536
- external: value,
537
- setExternal: setValue,
538
- persistWhen: (controlValue) => !!controlValue?.value.size || controlValue?.value.size === 0,
539
- fallback: (controlValue) => ({
540
- $$type: "size",
541
- value: { unit: controlValue?.value.unit || "px", size: NaN }
542
- })
543
- });
544
- const handleUnitChange = (event) => {
545
- const unit = event.target.value;
546
- setState((prev) => ({
547
- ...prev,
548
- value: {
549
- ...prev.value,
550
- unit
551
- }
552
- }));
553
- };
554
- const handleSizeChange = (event) => {
555
- const { value: size } = event.target;
556
- setState((prev) => ({
557
- ...prev,
558
- value: {
559
- ...prev.value,
560
- size: size || size === "0" ? parseFloat(size) : NaN
561
- }
562
- }));
563
- };
564
- return /* @__PURE__ */ React13.createElement(Stack5, { direction: "row" }, /* @__PURE__ */ React13.createElement(
565
- TextField3,
566
- {
567
- size: "tiny",
568
- type: "number",
569
- value: Number.isNaN(state.value.size) ? "" : state.value.size,
570
- onChange: handleSizeChange,
571
- placeholder
572
- }
573
- ), /* @__PURE__ */ React13.createElement(
574
- Select2,
575
- {
576
- size: "tiny",
577
- value: state.value.unit,
578
- onChange: handleUnitChange,
579
- MenuProps: {
580
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
581
- transformOrigin: { vertical: "top", horizontal: "right" }
582
- }
583
- },
584
- units2.map((unit) => /* @__PURE__ */ React13.createElement(MenuItem2, { key: unit, value: unit }, unit.toUpperCase()))
585
- ));
586
- };
587
-
588
609
  // src/components/style-sections/size-section.tsx
589
610
  import { Stack as Stack6 } from "@elementor/ui";
590
611
  import { __ as __3 } from "@wordpress/i18n";
591
612
  var SizeSection = () => {
592
- return /* @__PURE__ */ React14.createElement(AccordionSection, { title: __3("Size", "elementor") }, /* @__PURE__ */ React14.createElement(Stack6, { gap: 1.5 }, /* @__PURE__ */ React14.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "width", label: __3("Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "height", label: __3("Height", "elementor") })), /* @__PURE__ */ React14.createElement(CollapsibleContent, null, /* @__PURE__ */ React14.createElement(Stack6, { gap: 1.5, sx: { pt: 1.5 } }, /* @__PURE__ */ React14.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "minWidth", label: __3("Min. Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "minHeight", label: __3("Min. Height", "elementor") })), /* @__PURE__ */ React14.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React14.createElement(Control2, { bind: "maxWidth", label: __3("Max. Width", "elementor") }), /* @__PURE__ */ React14.createElement(Control2, { bind: "maxHeight", label: __3("Max. Height", "elementor") }))))));
613
+ return /* @__PURE__ */ React16.createElement(AccordionSection, { title: __3("Size", "elementor") }, /* @__PURE__ */ React16.createElement(Stack6, { gap: 1.5 }, /* @__PURE__ */ React16.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "width", label: __3("Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "height", label: __3("Height", "elementor") })), /* @__PURE__ */ React16.createElement(CollapsibleContent, null, /* @__PURE__ */ React16.createElement(Stack6, { gap: 1.5, sx: { pt: 1.5 } }, /* @__PURE__ */ React16.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "minWidth", label: __3("Min. Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "minHeight", label: __3("Min. Height", "elementor") })), /* @__PURE__ */ React16.createElement(Stack6, { direction: "row", gap: 2 }, /* @__PURE__ */ React16.createElement(Control3, { bind: "maxWidth", label: __3("Max. Width", "elementor") }), /* @__PURE__ */ React16.createElement(Control3, { bind: "maxHeight", label: __3("Max. Height", "elementor") }))))));
593
614
  };
594
- var units = ["px", "%", "em", "rem", "vw"];
595
- var Control2 = ({ label, bind }) => {
596
- return /* @__PURE__ */ React14.createElement(StyleControl, { bind }, /* @__PURE__ */ React14.createElement(Stack6, { gap: 1, sx: { flex: "0 1 50%" } }, /* @__PURE__ */ React14.createElement(StyleControl.Label, null, label), /* @__PURE__ */ React14.createElement(SizeControl, { units })));
615
+ var Control3 = ({ label, bind }) => {
616
+ 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" })));
597
617
  };
598
618
 
599
- // src/components/style-sections/typography-section.tsx
600
- import * as React16 from "react";
601
- import { Stack as Stack8 } from "@elementor/ui";
619
+ // src/components/style-sections/typography-section/typography-section.tsx
620
+ import * as React20 from "react";
621
+ import { Divider, Stack as Stack7 } from "@elementor/ui";
602
622
 
603
- // src/controls/control-types/text-style-control.tsx
604
- import * as React15 from "react";
605
- import { Stack as Stack7, ToggleButton as ToggleButtonBase, ToggleButtonGroup } from "@elementor/ui";
623
+ // src/components/style-sections/typography-section/text-style-control.tsx
624
+ import * as React17 from "react";
625
+ import { ToggleButton as ToggleButtonBase, ToggleButtonGroup } from "@elementor/ui";
626
+ import { ItalicIcon, StrikethroughIcon, UnderlineIcon } from "@elementor/icons";
606
627
  import { __ as __4 } from "@wordpress/i18n";
628
+ var buttonSize = "tiny";
607
629
  var TextStyleControl = () => {
608
630
  const [fontStyle, setFontStyle] = useStyleControl("fontStyle");
609
631
  const [textDecoration, setTextDecoration] = useStyleControl("textDecoration");
610
632
  const formats = [fontStyle, ...(textDecoration || "").split(" ")];
611
- return /* @__PURE__ */ React15.createElement(Stack7, { direction: "row", justifyContent: "space-between", alignItems: "center" }, /* @__PURE__ */ React15.createElement(ControlLabel, null, __4("Style", "elementor")), /* @__PURE__ */ React15.createElement(ToggleButtonGroup, { value: formats }, /* @__PURE__ */ React15.createElement(
633
+ return /* @__PURE__ */ React17.createElement(ControlContainer, null, /* @__PURE__ */ React17.createElement(ControlLabel, null, __4("Style", "elementor")), /* @__PURE__ */ React17.createElement(ToggleButtonGroup, { value: formats }, /* @__PURE__ */ React17.createElement(
612
634
  ToggleButton,
613
635
  {
614
636
  value: "italic",
615
637
  onChange: (v) => setFontStyle(fontStyle === v ? null : v),
616
- "aria-label": "italic"
638
+ "aria-label": "italic",
639
+ sx: { marginLeft: "auto" }
617
640
  },
618
- /* @__PURE__ */ React15.createElement("span", { style: { fontStyle: "italic", fontSize: "12px" } }, "I")
619
- ), /* @__PURE__ */ React15.createElement(
641
+ /* @__PURE__ */ React17.createElement(ItalicIcon, { fontSize: buttonSize })
642
+ ), /* @__PURE__ */ React17.createElement(
620
643
  ShorthandControl,
621
644
  {
622
645
  value: "line-through",
@@ -624,8 +647,8 @@ var TextStyleControl = () => {
624
647
  updateValues: setTextDecoration,
625
648
  "aria-label": "line-through"
626
649
  },
627
- /* @__PURE__ */ React15.createElement("span", { style: { textDecoration: "line-through", fontSize: "12px" } }, "S")
628
- ), /* @__PURE__ */ React15.createElement(
650
+ /* @__PURE__ */ React17.createElement(StrikethroughIcon, { fontSize: buttonSize })
651
+ ), /* @__PURE__ */ React17.createElement(
629
652
  ShorthandControl,
630
653
  {
631
654
  value: "underline",
@@ -633,7 +656,7 @@ var TextStyleControl = () => {
633
656
  updateValues: setTextDecoration,
634
657
  "aria-label": "underline"
635
658
  },
636
- /* @__PURE__ */ React15.createElement("span", { style: { textDecoration: "underline", fontSize: "12px" } }, "U")
659
+ /* @__PURE__ */ React17.createElement(UnderlineIcon, { fontSize: buttonSize })
637
660
  )));
638
661
  };
639
662
  var ShorthandControl = ({
@@ -652,19 +675,42 @@ var ShorthandControl = ({
652
675
  updateValues([...valuesArr, newValue].join(" "));
653
676
  }
654
677
  };
655
- return /* @__PURE__ */ React15.createElement(ToggleButton, { value, onChange: toggleValue, selected, "aria-label": ariaLabel }, children);
678
+ return /* @__PURE__ */ React17.createElement(ToggleButton, { value, onChange: toggleValue, selected, "aria-label": ariaLabel }, children);
656
679
  };
657
680
  var ToggleButton = ({ onChange, ...props }) => {
658
681
  const handleChange = (_e, newValue) => {
659
682
  onChange(newValue);
660
683
  };
661
- return /* @__PURE__ */ React15.createElement(ToggleButtonBase, { ...props, onChange: handleChange, size: "tiny", sx: { px: 1.5 } });
684
+ return /* @__PURE__ */ React17.createElement(ToggleButtonBase, { ...props, onChange: handleChange, size: buttonSize });
662
685
  };
663
686
 
664
- // src/components/style-sections/typography-section.tsx
687
+ // src/components/style-sections/typography-section/typography-section.tsx
688
+ import { __ as __7 } from "@wordpress/i18n";
689
+
690
+ // src/components/style-sections/typography-section/font-size-control.tsx
691
+ import * as React18 from "react";
665
692
  import { __ as __5 } from "@wordpress/i18n";
693
+ var FontSizeControl = () => {
694
+ return /* @__PURE__ */ React18.createElement(StyleControl, { bind: "font-size" }, /* @__PURE__ */ React18.createElement(ControlContainer, null, /* @__PURE__ */ React18.createElement(StyleControl.Label, null, __5("Font Size", "elementor")), /* @__PURE__ */ React18.createElement(SizeControl, null)));
695
+ };
696
+
697
+ // src/components/style-sections/typography-section/font-weight-control.tsx
698
+ import * as React19 from "react";
699
+ import { __ as __6 } from "@wordpress/i18n";
700
+ var fontWeightOptions = [
701
+ { label: __6("Light - 400", "elementor"), value: 400 },
702
+ { label: __6("Regular - 500", "elementor"), value: 500 },
703
+ { label: __6("Semi Bold - 600", "elementor"), value: 600 },
704
+ { label: __6("Bold - 700", "elementor"), value: 700 },
705
+ { label: __6("Black - 900", "elementor"), value: 900 }
706
+ ];
707
+ var FontWeightControl = () => {
708
+ return /* @__PURE__ */ React19.createElement(StyleControl, { bind: "fontWeight" }, /* @__PURE__ */ React19.createElement(ControlContainer, null, /* @__PURE__ */ React19.createElement(StyleControl.Label, null, __6("Font Weight", "elementor")), /* @__PURE__ */ React19.createElement(SelectControl, { options: fontWeightOptions })));
709
+ };
710
+
711
+ // src/components/style-sections/typography-section/typography-section.tsx
666
712
  var TypographySection = () => {
667
- return /* @__PURE__ */ React16.createElement(AccordionSection, { title: __5("Typography", "elementor") }, /* @__PURE__ */ React16.createElement(Stack8, { gap: 1.5 }, /* @__PURE__ */ React16.createElement(TextStyleControl, null)));
713
+ return /* @__PURE__ */ React20.createElement(AccordionSection, { title: __7("Typography", "elementor") }, /* @__PURE__ */ React20.createElement(Stack7, { gap: 1.5 }, /* @__PURE__ */ React20.createElement(FontWeightControl, null), /* @__PURE__ */ React20.createElement(FontSizeControl, null), /* @__PURE__ */ React20.createElement(Divider, null), /* @__PURE__ */ React20.createElement(TextStyleControl, null)));
668
714
  };
669
715
 
670
716
  // src/components/style-tab.tsx
@@ -672,13 +718,13 @@ var StyleTab = () => {
672
718
  const { element } = useElementContext();
673
719
  const elementStyles = useElementStyles(element.id);
674
720
  const [selectedStyleDef = null] = Object.values(elementStyles || {});
675
- return /* @__PURE__ */ React17.createElement(StyleContext, { selectedStyleDef }, /* @__PURE__ */ React17.createElement(Stack9, null, /* @__PURE__ */ React17.createElement(SizeSection, null), /* @__PURE__ */ React17.createElement(TypographySection, null)));
721
+ return /* @__PURE__ */ React21.createElement(StyleContext, { selectedStyleDef }, /* @__PURE__ */ React21.createElement(Stack8, null, /* @__PURE__ */ React21.createElement(SizeSection, null), /* @__PURE__ */ React21.createElement(TypographySection, null)));
676
722
  };
677
723
 
678
724
  // src/components/editing-panel-tabs.tsx
679
725
  var EditingPanelTabs = () => {
680
726
  const { getTabProps, getTabPanelProps, getTabsProps } = useTabs("settings");
681
- return /* @__PURE__ */ React18.createElement(Stack10, { direction: "column", sx: { width: "100%" } }, /* @__PURE__ */ React18.createElement(Tabs, { variant: "fullWidth", indicatorColor: "secondary", textColor: "inherit", ...getTabsProps() }, /* @__PURE__ */ React18.createElement(Tab, { label: __6("General", "elementor"), ...getTabProps("settings") }), /* @__PURE__ */ React18.createElement(Tab, { label: __6("Style", "elementor"), ...getTabProps("style") })), /* @__PURE__ */ React18.createElement(TabPanel, { ...getTabPanelProps("settings"), disablePadding: true }, /* @__PURE__ */ React18.createElement(SettingsTab, null)), /* @__PURE__ */ React18.createElement(TabPanel, { ...getTabPanelProps("style"), disablePadding: true }, /* @__PURE__ */ React18.createElement(StyleTab, null)));
727
+ return /* @__PURE__ */ React22.createElement(Stack9, { direction: "column", sx: { width: "100%" } }, /* @__PURE__ */ React22.createElement(Tabs, { variant: "fullWidth", indicatorColor: "secondary", textColor: "inherit", ...getTabsProps() }, /* @__PURE__ */ React22.createElement(Tab, { label: __8("General", "elementor"), ...getTabProps("settings") }), /* @__PURE__ */ React22.createElement(Tab, { label: __8("Style", "elementor"), ...getTabProps("style") })), /* @__PURE__ */ React22.createElement(TabPanel, { ...getTabPanelProps("settings"), disablePadding: true }, /* @__PURE__ */ React22.createElement(SettingsTab, null)), /* @__PURE__ */ React22.createElement(TabPanel, { ...getTabPanelProps("style"), disablePadding: true }, /* @__PURE__ */ React22.createElement(StyleTab, null)));
682
728
  };
683
729
 
684
730
  // src/components/editing-panel.tsx
@@ -689,8 +735,8 @@ var EditingPanel = () => {
689
735
  if (elements.length !== 1 || !elementType) {
690
736
  return null;
691
737
  }
692
- const panelTitle = __7("Edit %s", "elementor").replace("%s", elementType.title);
693
- return /* @__PURE__ */ React19.createElement(Panel, null, /* @__PURE__ */ React19.createElement(PanelHeader, null, /* @__PURE__ */ React19.createElement(PanelHeaderTitle, null, panelTitle)), /* @__PURE__ */ React19.createElement(PanelBody, null, /* @__PURE__ */ React19.createElement(ElementContext, { element: selectedElement }, /* @__PURE__ */ React19.createElement(EditingPanelTabs, null))));
738
+ const panelTitle = __9("Edit %s", "elementor").replace("%s", elementType.title);
739
+ return /* @__PURE__ */ React23.createElement(Panel, null, /* @__PURE__ */ React23.createElement(PanelHeader, null, /* @__PURE__ */ React23.createElement(PanelHeaderTitle, null, panelTitle)), /* @__PURE__ */ React23.createElement(PanelBody, null, /* @__PURE__ */ React23.createElement(ElementContext, { element: selectedElement, elementType }, /* @__PURE__ */ React23.createElement(EditingPanelTabs, null))));
694
740
  };
695
741
 
696
742
  // src/panel.ts
@@ -752,4 +798,8 @@ var blockV1Panel = () => {
752
798
 
753
799
  // src/index.ts
754
800
  init();
801
+ export {
802
+ replaceControl,
803
+ useControl
804
+ };
755
805
  //# sourceMappingURL=index.mjs.map