@elementor/editor-controls 3.32.0-23 → 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.mjs CHANGED
@@ -130,13 +130,13 @@ var usePropKeyContext = () => {
130
130
  import { useState } from "react";
131
131
  function useBoundProp(propTypeUtil) {
132
132
  const propKeyContext = usePropKeyContext();
133
- const { isValid, validate, restoreValue } = useValidation(propKeyContext.propType);
133
+ const { isValid, validate: validate2, restoreValue } = useValidation(propKeyContext.propType);
134
134
  const disabled = propKeyContext.isDisabled?.(propKeyContext.propType);
135
135
  if (!propTypeUtil) {
136
136
  return { ...propKeyContext, disabled };
137
137
  }
138
138
  function setValue(value2, options, meta) {
139
- if (!validate(value2)) {
139
+ if (!validate2(value2)) {
140
140
  return;
141
141
  }
142
142
  if (value2 === null) {
@@ -159,7 +159,7 @@ function useBoundProp(propTypeUtil) {
159
159
  }
160
160
  var useValidation = (propType) => {
161
161
  const [isValid, setIsValid] = useState(true);
162
- const validate = (value) => {
162
+ const validate2 = (value) => {
163
163
  let valid = true;
164
164
  if (propType.settings.required && value === null) {
165
165
  valid = false;
@@ -171,7 +171,7 @@ var useValidation = (propType) => {
171
171
  return {
172
172
  isValid,
173
173
  setIsValid,
174
- validate,
174
+ validate: validate2,
175
175
  restoreValue
176
176
  };
177
177
  };
@@ -4318,7 +4318,7 @@ var KeyValueControl = createControl((props = {}) => {
4318
4318
  ],
4319
4319
  [props.regexKey, props.regexValue, props.validationErrorMessage]
4320
4320
  );
4321
- const validate = (newValue, fieldType) => {
4321
+ const validate2 = (newValue, fieldType) => {
4322
4322
  if (fieldType === "key" && keyRegex) {
4323
4323
  const isValid = keyRegex.test(newValue);
4324
4324
  setKeyError(isValid ? "" : errMsg);
@@ -4348,7 +4348,7 @@ var KeyValueControl = createControl((props = {}) => {
4348
4348
  ...prev,
4349
4349
  [fieldType]: extractedValue
4350
4350
  }));
4351
- if (extractedValue && validate(extractedValue, fieldType)) {
4351
+ if (extractedValue && validate2(extractedValue, fieldType)) {
4352
4352
  setValue({
4353
4353
  ...value,
4354
4354
  [fieldType]: newChangedValue
@@ -5008,6 +5008,287 @@ var UnstableTransformRepeaterControl = createControl(() => {
5008
5008
  /* @__PURE__ */ React82.createElement(RemoveItemAction, null)
5009
5009
  )));
5010
5010
  });
5011
+
5012
+ // src/components/css-code-editor/css-editor.tsx
5013
+ import * as React84 from "react";
5014
+ import { useActiveBreakpoint as useActiveBreakpoint2 } from "@elementor/editor-responsive";
5015
+ import { useTheme as useTheme2 } from "@elementor/ui";
5016
+ import { Editor } from "@monaco-editor/react";
5017
+
5018
+ // src/components/css-code-editor/css-editor.styles.ts
5019
+ import { Box as Box14, Button as Button5, styled as styled7 } from "@elementor/ui";
5020
+ var EditorWrapper = styled7(Box14)`
5021
+ border: 1px solid var( --e-a-border-color );
5022
+ border-radius: 8px;
5023
+ padding: 10px 12px;
5024
+ position: relative;
5025
+ height: 200px;
5026
+
5027
+ .monaco-editor .colorpicker-widget {
5028
+ z-index: 99999999 !important;
5029
+ }
5030
+ `;
5031
+ var ResizeHandle = styled7(Button5)`
5032
+ position: absolute;
5033
+ bottom: 0;
5034
+ left: 0;
5035
+ right: 0;
5036
+ height: 6px;
5037
+ cursor: ns-resize;
5038
+ background: transparent;
5039
+ border: none;
5040
+ padding: 0;
5041
+
5042
+ &:hover {
5043
+ background: rgba( 0, 0, 0, 0.05 );
5044
+ }
5045
+
5046
+ &:active {
5047
+ background: rgba( 0, 0, 0, 0.1 );
5048
+ }
5049
+
5050
+ &::after {
5051
+ content: '';
5052
+ position: absolute;
5053
+ top: 50%;
5054
+ left: 50%;
5055
+ transform: translate( -50%, -50% );
5056
+ width: 30px;
5057
+ height: 2px;
5058
+ background: var( --e-a-border-color );
5059
+ border-radius: 1px;
5060
+ }
5061
+ `;
5062
+
5063
+ // src/components/css-code-editor/css-validation.ts
5064
+ import { __ as __42 } from "@wordpress/i18n";
5065
+ var forbiddenPatterns = [
5066
+ {
5067
+ pattern: ":hover",
5068
+ message: __42(
5069
+ "The use of pseudo-states is not permitted. Instead, switch to the desired pseudo state and add your custom code there.",
5070
+ "elementor"
5071
+ )
5072
+ },
5073
+ {
5074
+ pattern: ":active",
5075
+ message: __42(
5076
+ "The use of pseudo-states is not permitted. Instead, switch to the desired pseudo state and add your custom code there.",
5077
+ "elementor"
5078
+ )
5079
+ },
5080
+ {
5081
+ pattern: "@media",
5082
+ message: __42(
5083
+ "The use of @media is not permitted. Instead, switch to the desired breakpoint and add your custom code there.",
5084
+ "elementor"
5085
+ )
5086
+ }
5087
+ ];
5088
+ function setCustomSyntaxRules(editor, monaco) {
5089
+ const model = editor.getModel();
5090
+ if (!model) {
5091
+ return true;
5092
+ }
5093
+ const customMarkers = [];
5094
+ forbiddenPatterns.forEach((rule) => {
5095
+ const matches = model.findMatches(rule.pattern, true, false, true, null, true);
5096
+ matches.forEach((match) => {
5097
+ customMarkers.push({
5098
+ severity: monaco.MarkerSeverity.Error,
5099
+ message: rule.message,
5100
+ startLineNumber: match.range.startLineNumber,
5101
+ startColumn: match.range.startColumn,
5102
+ endLineNumber: match.range.endLineNumber,
5103
+ endColumn: match.range.endColumn,
5104
+ source: "custom-css-rules"
5105
+ });
5106
+ });
5107
+ });
5108
+ monaco.editor.setModelMarkers(model, "custom-css-rules", customMarkers);
5109
+ return customMarkers.length === 0;
5110
+ }
5111
+ function validate(editor, monaco) {
5112
+ const model = editor.getModel();
5113
+ if (!model) {
5114
+ return true;
5115
+ }
5116
+ const allMarkers = monaco.editor.getModelMarkers({ resource: model.uri });
5117
+ return allMarkers.filter((marker) => marker.severity === monaco.MarkerSeverity.Error).length === 0;
5118
+ }
5119
+
5120
+ // src/components/css-code-editor/resize-handle.tsx
5121
+ import * as React83 from "react";
5122
+ var ResizeHandleComponent = ({ onResize, containerRef, onHeightChange }) => {
5123
+ const handleResizeMove = React83.useCallback(
5124
+ (e) => {
5125
+ const container = containerRef.current;
5126
+ if (!container) {
5127
+ return;
5128
+ }
5129
+ const containerRect = container.getBoundingClientRect();
5130
+ const newHeight = Math.max(100, e.clientY - containerRect.top);
5131
+ onHeightChange?.(newHeight);
5132
+ onResize(newHeight);
5133
+ },
5134
+ [containerRef, onResize, onHeightChange]
5135
+ );
5136
+ const handleResizeEnd = React83.useCallback(() => {
5137
+ document.removeEventListener("mousemove", handleResizeMove);
5138
+ document.removeEventListener("mouseup", handleResizeEnd);
5139
+ }, [handleResizeMove]);
5140
+ const handleResizeStart = React83.useCallback(
5141
+ (e) => {
5142
+ e.preventDefault();
5143
+ e.stopPropagation();
5144
+ document.addEventListener("mousemove", handleResizeMove);
5145
+ document.addEventListener("mouseup", handleResizeEnd);
5146
+ },
5147
+ [handleResizeMove, handleResizeEnd]
5148
+ );
5149
+ React83.useEffect(() => {
5150
+ return () => {
5151
+ document.removeEventListener("mousemove", handleResizeMove);
5152
+ document.removeEventListener("mouseup", handleResizeEnd);
5153
+ };
5154
+ }, [handleResizeMove, handleResizeEnd]);
5155
+ return /* @__PURE__ */ React83.createElement(
5156
+ ResizeHandle,
5157
+ {
5158
+ onMouseDown: handleResizeStart,
5159
+ "aria-label": "Resize editor height",
5160
+ title: "Drag to resize editor height"
5161
+ }
5162
+ );
5163
+ };
5164
+
5165
+ // src/components/css-code-editor/css-editor.tsx
5166
+ var setVisualContent = (value) => {
5167
+ const trimmed = value.trim();
5168
+ return `element.style {
5169
+ ${trimmed ? " " + trimmed.replace(/\n/g, "\n ") + "\n" : " \n"}}`;
5170
+ };
5171
+ var getActual = (value) => {
5172
+ const lines = value.split("\n");
5173
+ if (lines.length < 2) {
5174
+ return "";
5175
+ }
5176
+ return lines.slice(1, -1).map((line) => line.replace(/^ {2}/, "")).join("\n");
5177
+ };
5178
+ var preventChangeOnVisualContent = (editor, monaco) => {
5179
+ const model = editor.getModel();
5180
+ if (!model) {
5181
+ return;
5182
+ }
5183
+ editor.onKeyDown((e) => {
5184
+ const position = editor.getPosition();
5185
+ if (!position) {
5186
+ return;
5187
+ }
5188
+ const totalLines = model.getLineCount();
5189
+ const isInProtectedRange = position.lineNumber === 1 || position.lineNumber === totalLines;
5190
+ if (isInProtectedRange) {
5191
+ const allowedKeys = [
5192
+ monaco.KeyCode.UpArrow,
5193
+ monaco.KeyCode.DownArrow,
5194
+ monaco.KeyCode.LeftArrow,
5195
+ monaco.KeyCode.RightArrow,
5196
+ monaco.KeyCode.Home,
5197
+ monaco.KeyCode.End,
5198
+ monaco.KeyCode.PageUp,
5199
+ monaco.KeyCode.PageDown,
5200
+ monaco.KeyCode.Tab,
5201
+ monaco.KeyCode.Escape
5202
+ ];
5203
+ if (!allowedKeys.includes(e.keyCode)) {
5204
+ e.preventDefault();
5205
+ e.stopPropagation();
5206
+ }
5207
+ }
5208
+ });
5209
+ };
5210
+ var createEditorDidMountHandler = (editorRef, monacoRef, debounceTimer, onChange) => {
5211
+ return (editor, monaco) => {
5212
+ editorRef.current = editor;
5213
+ monacoRef.current = monaco;
5214
+ preventChangeOnVisualContent(editor, monaco);
5215
+ setCustomSyntaxRules(editor, monaco);
5216
+ editor.onDidChangeModelContent(() => {
5217
+ const code = editor.getModel()?.getValue() ?? "";
5218
+ const userContent = getActual(code);
5219
+ setCustomSyntaxRules(editor, monaco);
5220
+ const currentTimer = debounceTimer.current;
5221
+ if (currentTimer) {
5222
+ clearTimeout(currentTimer);
5223
+ }
5224
+ const newTimer = setTimeout(() => {
5225
+ if (!editorRef.current || !monacoRef.current) {
5226
+ return;
5227
+ }
5228
+ const hasNoErrors = validate(editorRef.current, monacoRef.current);
5229
+ if (hasNoErrors) {
5230
+ onChange(userContent);
5231
+ }
5232
+ }, 500);
5233
+ debounceTimer.current = newTimer;
5234
+ });
5235
+ };
5236
+ };
5237
+ var CssEditor = ({ value, onChange }) => {
5238
+ const theme = useTheme2();
5239
+ const containerRef = React84.useRef(null);
5240
+ const editorRef = React84.useRef(null);
5241
+ const monacoRef = React84.useRef(null);
5242
+ const debounceTimer = React84.useRef(null);
5243
+ const activeBreakpoint = useActiveBreakpoint2();
5244
+ const handleResize = React84.useCallback(() => {
5245
+ editorRef.current?.layout();
5246
+ }, []);
5247
+ const handleHeightChange = React84.useCallback((height) => {
5248
+ if (containerRef.current) {
5249
+ containerRef.current.style.height = `${height}px`;
5250
+ }
5251
+ }, []);
5252
+ const handleEditorDidMount = createEditorDidMountHandler(editorRef, monacoRef, debounceTimer, onChange);
5253
+ React84.useEffect(() => {
5254
+ const timerRef = debounceTimer;
5255
+ return () => {
5256
+ const timer = timerRef.current;
5257
+ if (timer) {
5258
+ clearTimeout(timer);
5259
+ }
5260
+ };
5261
+ }, []);
5262
+ return /* @__PURE__ */ React84.createElement(EditorWrapper, { ref: containerRef }, /* @__PURE__ */ React84.createElement(
5263
+ Editor,
5264
+ {
5265
+ key: activeBreakpoint,
5266
+ height: "100%",
5267
+ language: "css",
5268
+ theme: theme.palette.mode === "dark" ? "vs-dark" : "vs",
5269
+ defaultValue: setVisualContent(value),
5270
+ onMount: handleEditorDidMount,
5271
+ options: {
5272
+ lineNumbers: "off",
5273
+ folding: false,
5274
+ showFoldingControls: "never",
5275
+ minimap: { enabled: false },
5276
+ fontFamily: "Roboto, Arial, Helvetica, Verdana, sans-serif",
5277
+ fontSize: 12,
5278
+ renderLineHighlight: "none",
5279
+ hideCursorInOverviewRuler: true,
5280
+ fixedOverflowWidgets: true
5281
+ }
5282
+ }
5283
+ ), /* @__PURE__ */ React84.createElement(
5284
+ ResizeHandleComponent,
5285
+ {
5286
+ onResize: handleResize,
5287
+ containerRef,
5288
+ onHeightChange: handleHeightChange
5289
+ }
5290
+ ));
5291
+ };
5011
5292
  export {
5012
5293
  AspectRatioControl,
5013
5294
  BackgroundControl,
@@ -5019,6 +5300,7 @@ export {
5019
5300
  ControlFormLabel,
5020
5301
  ControlReplacementsProvider,
5021
5302
  ControlToggleButtonGroup,
5303
+ CssEditor,
5022
5304
  EqualUnequalSizesControl,
5023
5305
  FilterRepeaterControl,
5024
5306
  FontFamilyControl,