@elementor/editor-controls 3.32.0-22 → 3.32.0-24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -288,6 +288,12 @@ declare const transitionsItemsList: {
288
288
 
289
289
  declare const ControlFormLabel: (props: FormLabelProps) => React$1.JSX.Element;
290
290
 
291
+ type CssEditorProps = {
292
+ value: string;
293
+ onChange: (value: string) => void;
294
+ };
295
+ declare const CssEditor: ({ value, onChange }: CssEditorProps) => React$1.JSX.Element;
296
+
291
297
  type AnyComponentType = ComponentType<any>;
292
298
  declare const brandSymbol: unique symbol;
293
299
  type ControlComponent<TComponent extends AnyComponentType = AnyComponentType> = TComponent & {
@@ -403,4 +409,4 @@ type UseInternalStateOptions<TValue> = {
403
409
  };
404
410
  declare const useSyncExternalState: <TValue>({ external, setExternal, persistWhen, fallback, }: UseInternalStateOptions<TValue>) => readonly [TValue, (setter: ((value: TValue) => TValue) | TValue) => void];
405
411
 
406
- export { type AngleUnit, AspectRatioControl, BackgroundControl, BoxShadowRepeaterControl, ColorControl, type ControlActionsItems, ControlActionsProvider, ControlAdornments, ControlAdornmentsProvider, type ControlComponent, ControlFormLabel, ControlReplacementsProvider, ControlToggleButtonGroup, type EqualUnequalItems, EqualUnequalSizesControl, type ExtendedOption, FilterRepeaterControl, type FontCategory, FontFamilyControl, GapControl, ImageControl, ItemSelector, KeyValueControl, type LengthUnit, LinkControl, LinkedDimensionsControl, NumberControl, PopoverContent, PositionControl, PropKeyProvider, PropProvider, type PropProviderProps, RepeatableControl, SelectControl, type SetValue, SizeControl, StrokeControl, SvgMediaControl, SwitchControl, TextAreaControl, TextControl, type TimeUnit, type ToggleButtonGroupItem, ToggleControl, type ToggleControlProps, TransformRepeaterControl, TransitionRepeaterControl, type Unit, UnstableTransformRepeaterControl, UrlControl, createControlReplacementsRegistry, enqueueFont, injectIntoRepeaterHeaderActions, injectIntoRepeaterItemActions, injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel, transitionProperties, transitionsItemsList, useBoundProp, useControlActions, useFloatingActionsBar, useSyncExternalState };
412
+ export { type AngleUnit, AspectRatioControl, BackgroundControl, BoxShadowRepeaterControl, ColorControl, type ControlActionsItems, ControlActionsProvider, ControlAdornments, ControlAdornmentsProvider, type ControlComponent, ControlFormLabel, ControlReplacementsProvider, ControlToggleButtonGroup, CssEditor, type EqualUnequalItems, EqualUnequalSizesControl, type ExtendedOption, FilterRepeaterControl, type FontCategory, FontFamilyControl, GapControl, ImageControl, ItemSelector, KeyValueControl, type LengthUnit, LinkControl, LinkedDimensionsControl, NumberControl, PopoverContent, PositionControl, PropKeyProvider, PropProvider, type PropProviderProps, RepeatableControl, SelectControl, type SetValue, SizeControl, StrokeControl, SvgMediaControl, SwitchControl, TextAreaControl, TextControl, type TimeUnit, type ToggleButtonGroupItem, ToggleControl, type ToggleControlProps, TransformRepeaterControl, TransitionRepeaterControl, type Unit, UnstableTransformRepeaterControl, UrlControl, createControlReplacementsRegistry, enqueueFont, injectIntoRepeaterHeaderActions, injectIntoRepeaterItemActions, injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel, transitionProperties, transitionsItemsList, useBoundProp, useControlActions, useFloatingActionsBar, useSyncExternalState };
package/dist/index.d.ts CHANGED
@@ -288,6 +288,12 @@ declare const transitionsItemsList: {
288
288
 
289
289
  declare const ControlFormLabel: (props: FormLabelProps) => React$1.JSX.Element;
290
290
 
291
+ type CssEditorProps = {
292
+ value: string;
293
+ onChange: (value: string) => void;
294
+ };
295
+ declare const CssEditor: ({ value, onChange }: CssEditorProps) => React$1.JSX.Element;
296
+
291
297
  type AnyComponentType = ComponentType<any>;
292
298
  declare const brandSymbol: unique symbol;
293
299
  type ControlComponent<TComponent extends AnyComponentType = AnyComponentType> = TComponent & {
@@ -403,4 +409,4 @@ type UseInternalStateOptions<TValue> = {
403
409
  };
404
410
  declare const useSyncExternalState: <TValue>({ external, setExternal, persistWhen, fallback, }: UseInternalStateOptions<TValue>) => readonly [TValue, (setter: ((value: TValue) => TValue) | TValue) => void];
405
411
 
406
- export { type AngleUnit, AspectRatioControl, BackgroundControl, BoxShadowRepeaterControl, ColorControl, type ControlActionsItems, ControlActionsProvider, ControlAdornments, ControlAdornmentsProvider, type ControlComponent, ControlFormLabel, ControlReplacementsProvider, ControlToggleButtonGroup, type EqualUnequalItems, EqualUnequalSizesControl, type ExtendedOption, FilterRepeaterControl, type FontCategory, FontFamilyControl, GapControl, ImageControl, ItemSelector, KeyValueControl, type LengthUnit, LinkControl, LinkedDimensionsControl, NumberControl, PopoverContent, PositionControl, PropKeyProvider, PropProvider, type PropProviderProps, RepeatableControl, SelectControl, type SetValue, SizeControl, StrokeControl, SvgMediaControl, SwitchControl, TextAreaControl, TextControl, type TimeUnit, type ToggleButtonGroupItem, ToggleControl, type ToggleControlProps, TransformRepeaterControl, TransitionRepeaterControl, type Unit, UnstableTransformRepeaterControl, UrlControl, createControlReplacementsRegistry, enqueueFont, injectIntoRepeaterHeaderActions, injectIntoRepeaterItemActions, injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel, transitionProperties, transitionsItemsList, useBoundProp, useControlActions, useFloatingActionsBar, useSyncExternalState };
412
+ export { type AngleUnit, AspectRatioControl, BackgroundControl, BoxShadowRepeaterControl, ColorControl, type ControlActionsItems, ControlActionsProvider, ControlAdornments, ControlAdornmentsProvider, type ControlComponent, ControlFormLabel, ControlReplacementsProvider, ControlToggleButtonGroup, CssEditor, type EqualUnequalItems, EqualUnequalSizesControl, type ExtendedOption, FilterRepeaterControl, type FontCategory, FontFamilyControl, GapControl, ImageControl, ItemSelector, KeyValueControl, type LengthUnit, LinkControl, LinkedDimensionsControl, NumberControl, PopoverContent, PositionControl, PropKeyProvider, PropProvider, type PropProviderProps, RepeatableControl, SelectControl, type SetValue, SizeControl, StrokeControl, SvgMediaControl, SwitchControl, TextAreaControl, TextControl, type TimeUnit, type ToggleButtonGroupItem, ToggleControl, type ToggleControlProps, TransformRepeaterControl, TransitionRepeaterControl, type Unit, UnstableTransformRepeaterControl, UrlControl, createControlReplacementsRegistry, enqueueFont, injectIntoRepeaterHeaderActions, injectIntoRepeaterItemActions, injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel, transitionProperties, transitionsItemsList, useBoundProp, useControlActions, useFloatingActionsBar, useSyncExternalState };
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  ControlFormLabel: () => ControlFormLabel,
41
41
  ControlReplacementsProvider: () => ControlReplacementsProvider,
42
42
  ControlToggleButtonGroup: () => ControlToggleButtonGroup,
43
+ CssEditor: () => CssEditor,
43
44
  EqualUnequalSizesControl: () => EqualUnequalSizesControl,
44
45
  FilterRepeaterControl: () => FilterRepeaterControl,
45
46
  FontFamilyControl: () => FontFamilyControl,
@@ -214,13 +215,13 @@ var usePropKeyContext = () => {
214
215
  var import_react3 = require("react");
215
216
  function useBoundProp(propTypeUtil) {
216
217
  const propKeyContext = usePropKeyContext();
217
- const { isValid, validate, restoreValue } = useValidation(propKeyContext.propType);
218
+ const { isValid, validate: validate2, restoreValue } = useValidation(propKeyContext.propType);
218
219
  const disabled = propKeyContext.isDisabled?.(propKeyContext.propType);
219
220
  if (!propTypeUtil) {
220
221
  return { ...propKeyContext, disabled };
221
222
  }
222
223
  function setValue(value2, options, meta) {
223
- if (!validate(value2)) {
224
+ if (!validate2(value2)) {
224
225
  return;
225
226
  }
226
227
  if (value2 === null) {
@@ -243,7 +244,7 @@ function useBoundProp(propTypeUtil) {
243
244
  }
244
245
  var useValidation = (propType) => {
245
246
  const [isValid, setIsValid] = (0, import_react3.useState)(true);
246
- const validate = (value) => {
247
+ const validate2 = (value) => {
247
248
  let valid = true;
248
249
  if (propType.settings.required && value === null) {
249
250
  valid = false;
@@ -255,7 +256,7 @@ var useValidation = (propType) => {
255
256
  return {
256
257
  isValid,
257
258
  setIsValid,
258
- validate,
259
+ validate: validate2,
259
260
  restoreValue
260
261
  };
261
262
  };
@@ -4315,7 +4316,7 @@ var KeyValueControl = createControl((props = {}) => {
4315
4316
  ],
4316
4317
  [props.regexKey, props.regexValue, props.validationErrorMessage]
4317
4318
  );
4318
- const validate = (newValue, fieldType) => {
4319
+ const validate2 = (newValue, fieldType) => {
4319
4320
  if (fieldType === "key" && keyRegex) {
4320
4321
  const isValid = keyRegex.test(newValue);
4321
4322
  setKeyError(isValid ? "" : errMsg);
@@ -4345,7 +4346,7 @@ var KeyValueControl = createControl((props = {}) => {
4345
4346
  ...prev,
4346
4347
  [fieldType]: extractedValue
4347
4348
  }));
4348
- if (extractedValue && validate(extractedValue, fieldType)) {
4349
+ if (extractedValue && validate2(extractedValue, fieldType)) {
4349
4350
  setValue({
4350
4351
  ...value,
4351
4352
  [fieldType]: newChangedValue
@@ -4995,6 +4996,287 @@ var UnstableTransformRepeaterControl = createControl(() => {
4995
4996
  /* @__PURE__ */ React82.createElement(RemoveItemAction, null)
4996
4997
  )));
4997
4998
  });
4999
+
5000
+ // src/components/css-code-editor/css-editor.tsx
5001
+ var React84 = __toESM(require("react"));
5002
+ var import_editor_responsive2 = require("@elementor/editor-responsive");
5003
+ var import_ui72 = require("@elementor/ui");
5004
+ var import_react46 = require("@monaco-editor/react");
5005
+
5006
+ // src/components/css-code-editor/css-editor.styles.ts
5007
+ var import_ui71 = require("@elementor/ui");
5008
+ var EditorWrapper = (0, import_ui71.styled)(import_ui71.Box)`
5009
+ border: 1px solid var( --e-a-border-color );
5010
+ border-radius: 8px;
5011
+ padding: 10px 12px;
5012
+ position: relative;
5013
+ height: 200px;
5014
+
5015
+ .monaco-editor .colorpicker-widget {
5016
+ z-index: 99999999 !important;
5017
+ }
5018
+ `;
5019
+ var ResizeHandle = (0, import_ui71.styled)(import_ui71.Button)`
5020
+ position: absolute;
5021
+ bottom: 0;
5022
+ left: 0;
5023
+ right: 0;
5024
+ height: 6px;
5025
+ cursor: ns-resize;
5026
+ background: transparent;
5027
+ border: none;
5028
+ padding: 0;
5029
+
5030
+ &:hover {
5031
+ background: rgba( 0, 0, 0, 0.05 );
5032
+ }
5033
+
5034
+ &:active {
5035
+ background: rgba( 0, 0, 0, 0.1 );
5036
+ }
5037
+
5038
+ &::after {
5039
+ content: '';
5040
+ position: absolute;
5041
+ top: 50%;
5042
+ left: 50%;
5043
+ transform: translate( -50%, -50% );
5044
+ width: 30px;
5045
+ height: 2px;
5046
+ background: var( --e-a-border-color );
5047
+ border-radius: 1px;
5048
+ }
5049
+ `;
5050
+
5051
+ // src/components/css-code-editor/css-validation.ts
5052
+ var import_i18n42 = require("@wordpress/i18n");
5053
+ var forbiddenPatterns = [
5054
+ {
5055
+ pattern: ":hover",
5056
+ message: (0, import_i18n42.__)(
5057
+ "The use of pseudo-states is not permitted. Instead, switch to the desired pseudo state and add your custom code there.",
5058
+ "elementor"
5059
+ )
5060
+ },
5061
+ {
5062
+ pattern: ":active",
5063
+ message: (0, import_i18n42.__)(
5064
+ "The use of pseudo-states is not permitted. Instead, switch to the desired pseudo state and add your custom code there.",
5065
+ "elementor"
5066
+ )
5067
+ },
5068
+ {
5069
+ pattern: "@media",
5070
+ message: (0, import_i18n42.__)(
5071
+ "The use of @media is not permitted. Instead, switch to the desired breakpoint and add your custom code there.",
5072
+ "elementor"
5073
+ )
5074
+ }
5075
+ ];
5076
+ function setCustomSyntaxRules(editor, monaco) {
5077
+ const model = editor.getModel();
5078
+ if (!model) {
5079
+ return true;
5080
+ }
5081
+ const customMarkers = [];
5082
+ forbiddenPatterns.forEach((rule) => {
5083
+ const matches = model.findMatches(rule.pattern, true, false, true, null, true);
5084
+ matches.forEach((match) => {
5085
+ customMarkers.push({
5086
+ severity: monaco.MarkerSeverity.Error,
5087
+ message: rule.message,
5088
+ startLineNumber: match.range.startLineNumber,
5089
+ startColumn: match.range.startColumn,
5090
+ endLineNumber: match.range.endLineNumber,
5091
+ endColumn: match.range.endColumn,
5092
+ source: "custom-css-rules"
5093
+ });
5094
+ });
5095
+ });
5096
+ monaco.editor.setModelMarkers(model, "custom-css-rules", customMarkers);
5097
+ return customMarkers.length === 0;
5098
+ }
5099
+ function validate(editor, monaco) {
5100
+ const model = editor.getModel();
5101
+ if (!model) {
5102
+ return true;
5103
+ }
5104
+ const allMarkers = monaco.editor.getModelMarkers({ resource: model.uri });
5105
+ return allMarkers.filter((marker) => marker.severity === monaco.MarkerSeverity.Error).length === 0;
5106
+ }
5107
+
5108
+ // src/components/css-code-editor/resize-handle.tsx
5109
+ var React83 = __toESM(require("react"));
5110
+ var ResizeHandleComponent = ({ onResize, containerRef, onHeightChange }) => {
5111
+ const handleResizeMove = React83.useCallback(
5112
+ (e) => {
5113
+ const container = containerRef.current;
5114
+ if (!container) {
5115
+ return;
5116
+ }
5117
+ const containerRect = container.getBoundingClientRect();
5118
+ const newHeight = Math.max(100, e.clientY - containerRect.top);
5119
+ onHeightChange?.(newHeight);
5120
+ onResize(newHeight);
5121
+ },
5122
+ [containerRef, onResize, onHeightChange]
5123
+ );
5124
+ const handleResizeEnd = React83.useCallback(() => {
5125
+ document.removeEventListener("mousemove", handleResizeMove);
5126
+ document.removeEventListener("mouseup", handleResizeEnd);
5127
+ }, [handleResizeMove]);
5128
+ const handleResizeStart = React83.useCallback(
5129
+ (e) => {
5130
+ e.preventDefault();
5131
+ e.stopPropagation();
5132
+ document.addEventListener("mousemove", handleResizeMove);
5133
+ document.addEventListener("mouseup", handleResizeEnd);
5134
+ },
5135
+ [handleResizeMove, handleResizeEnd]
5136
+ );
5137
+ React83.useEffect(() => {
5138
+ return () => {
5139
+ document.removeEventListener("mousemove", handleResizeMove);
5140
+ document.removeEventListener("mouseup", handleResizeEnd);
5141
+ };
5142
+ }, [handleResizeMove, handleResizeEnd]);
5143
+ return /* @__PURE__ */ React83.createElement(
5144
+ ResizeHandle,
5145
+ {
5146
+ onMouseDown: handleResizeStart,
5147
+ "aria-label": "Resize editor height",
5148
+ title: "Drag to resize editor height"
5149
+ }
5150
+ );
5151
+ };
5152
+
5153
+ // src/components/css-code-editor/css-editor.tsx
5154
+ var setVisualContent = (value) => {
5155
+ const trimmed = value.trim();
5156
+ return `element.style {
5157
+ ${trimmed ? " " + trimmed.replace(/\n/g, "\n ") + "\n" : " \n"}}`;
5158
+ };
5159
+ var getActual = (value) => {
5160
+ const lines = value.split("\n");
5161
+ if (lines.length < 2) {
5162
+ return "";
5163
+ }
5164
+ return lines.slice(1, -1).map((line) => line.replace(/^ {2}/, "")).join("\n");
5165
+ };
5166
+ var preventChangeOnVisualContent = (editor, monaco) => {
5167
+ const model = editor.getModel();
5168
+ if (!model) {
5169
+ return;
5170
+ }
5171
+ editor.onKeyDown((e) => {
5172
+ const position = editor.getPosition();
5173
+ if (!position) {
5174
+ return;
5175
+ }
5176
+ const totalLines = model.getLineCount();
5177
+ const isInProtectedRange = position.lineNumber === 1 || position.lineNumber === totalLines;
5178
+ if (isInProtectedRange) {
5179
+ const allowedKeys = [
5180
+ monaco.KeyCode.UpArrow,
5181
+ monaco.KeyCode.DownArrow,
5182
+ monaco.KeyCode.LeftArrow,
5183
+ monaco.KeyCode.RightArrow,
5184
+ monaco.KeyCode.Home,
5185
+ monaco.KeyCode.End,
5186
+ monaco.KeyCode.PageUp,
5187
+ monaco.KeyCode.PageDown,
5188
+ monaco.KeyCode.Tab,
5189
+ monaco.KeyCode.Escape
5190
+ ];
5191
+ if (!allowedKeys.includes(e.keyCode)) {
5192
+ e.preventDefault();
5193
+ e.stopPropagation();
5194
+ }
5195
+ }
5196
+ });
5197
+ };
5198
+ var createEditorDidMountHandler = (editorRef, monacoRef, debounceTimer, onChange) => {
5199
+ return (editor, monaco) => {
5200
+ editorRef.current = editor;
5201
+ monacoRef.current = monaco;
5202
+ preventChangeOnVisualContent(editor, monaco);
5203
+ setCustomSyntaxRules(editor, monaco);
5204
+ editor.onDidChangeModelContent(() => {
5205
+ const code = editor.getModel()?.getValue() ?? "";
5206
+ const userContent = getActual(code);
5207
+ setCustomSyntaxRules(editor, monaco);
5208
+ const currentTimer = debounceTimer.current;
5209
+ if (currentTimer) {
5210
+ clearTimeout(currentTimer);
5211
+ }
5212
+ const newTimer = setTimeout(() => {
5213
+ if (!editorRef.current || !monacoRef.current) {
5214
+ return;
5215
+ }
5216
+ const hasNoErrors = validate(editorRef.current, monacoRef.current);
5217
+ if (hasNoErrors) {
5218
+ onChange(userContent);
5219
+ }
5220
+ }, 500);
5221
+ debounceTimer.current = newTimer;
5222
+ });
5223
+ };
5224
+ };
5225
+ var CssEditor = ({ value, onChange }) => {
5226
+ const theme = (0, import_ui72.useTheme)();
5227
+ const containerRef = React84.useRef(null);
5228
+ const editorRef = React84.useRef(null);
5229
+ const monacoRef = React84.useRef(null);
5230
+ const debounceTimer = React84.useRef(null);
5231
+ const activeBreakpoint = (0, import_editor_responsive2.useActiveBreakpoint)();
5232
+ const handleResize = React84.useCallback(() => {
5233
+ editorRef.current?.layout();
5234
+ }, []);
5235
+ const handleHeightChange = React84.useCallback((height) => {
5236
+ if (containerRef.current) {
5237
+ containerRef.current.style.height = `${height}px`;
5238
+ }
5239
+ }, []);
5240
+ const handleEditorDidMount = createEditorDidMountHandler(editorRef, monacoRef, debounceTimer, onChange);
5241
+ React84.useEffect(() => {
5242
+ const timerRef = debounceTimer;
5243
+ return () => {
5244
+ const timer = timerRef.current;
5245
+ if (timer) {
5246
+ clearTimeout(timer);
5247
+ }
5248
+ };
5249
+ }, []);
5250
+ return /* @__PURE__ */ React84.createElement(EditorWrapper, { ref: containerRef }, /* @__PURE__ */ React84.createElement(
5251
+ import_react46.Editor,
5252
+ {
5253
+ key: activeBreakpoint,
5254
+ height: "100%",
5255
+ language: "css",
5256
+ theme: theme.palette.mode === "dark" ? "vs-dark" : "vs",
5257
+ defaultValue: setVisualContent(value),
5258
+ onMount: handleEditorDidMount,
5259
+ options: {
5260
+ lineNumbers: "off",
5261
+ folding: false,
5262
+ showFoldingControls: "never",
5263
+ minimap: { enabled: false },
5264
+ fontFamily: "Roboto, Arial, Helvetica, Verdana, sans-serif",
5265
+ fontSize: 12,
5266
+ renderLineHighlight: "none",
5267
+ hideCursorInOverviewRuler: true,
5268
+ fixedOverflowWidgets: true
5269
+ }
5270
+ }
5271
+ ), /* @__PURE__ */ React84.createElement(
5272
+ ResizeHandleComponent,
5273
+ {
5274
+ onResize: handleResize,
5275
+ containerRef,
5276
+ onHeightChange: handleHeightChange
5277
+ }
5278
+ ));
5279
+ };
4998
5280
  // Annotate the CommonJS export names for ESM import in node:
4999
5281
  0 && (module.exports = {
5000
5282
  AspectRatioControl,
@@ -5007,6 +5289,7 @@ var UnstableTransformRepeaterControl = createControl(() => {
5007
5289
  ControlFormLabel,
5008
5290
  ControlReplacementsProvider,
5009
5291
  ControlToggleButtonGroup,
5292
+ CssEditor,
5010
5293
  EqualUnequalSizesControl,
5011
5294
  FilterRepeaterControl,
5012
5295
  FontFamilyControl,