@_sh/strapi-plugin-ckeditor 6.0.2 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,7 @@
28
28
  - **Self-Hosted**
29
29
 
30
30
  <p align="right">
31
- <a href="https://www.buymeacoffee.com/nshenderov" target="_blank">
31
+ <a href="https://boosty.to/nkshenderov/donate" target="_blank">
32
32
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px; width: 217px;" >
33
33
  </a>
34
34
  </p>
@@ -469,7 +469,7 @@ export default {
469
469
  <summary>Setting a new set of presets [TS]</summary>
470
470
 
471
471
  ```ts
472
- // src/admin/app.tsx
472
+ // src/admin/app.ts
473
473
 
474
474
  import {
475
475
  Bold,
@@ -553,7 +553,7 @@ export default {
553
553
  <summary>Default presets modification using setPluginConfig [TS]</summary>
554
554
 
555
555
  ```ts
556
- // src/admin/app.tsx
556
+ // src/admin/app.ts
557
557
 
558
558
  import { css } from 'styled-components';
559
559
 
@@ -627,7 +627,7 @@ export default {
627
627
  <summary>Default presets modification using getPluginPresets [TS]</summary>
628
628
 
629
629
  ```ts
630
- // src/admin/app.tsx
630
+ // src/admin/app.ts
631
631
 
632
632
  import { css } from 'styled-components';
633
633
  import { getPluginPresets } from '@_sh/strapi-plugin-ckeditor';
@@ -687,7 +687,7 @@ export default {
687
687
  <summary>Modifying theme using setPluginConfig [TS]</summary>
688
688
 
689
689
  ```ts
690
- // src/admin/app.tsx
690
+ // src/admin/app.ts
691
691
 
692
692
  import { css } from 'styled-components';
693
693
 
@@ -723,7 +723,7 @@ export default {
723
723
  <summary>Modifying theme using getPluginTheme [TS]</summary>
724
724
 
725
725
  ```ts
726
- // src/admin/app.tsx
726
+ // src/admin/app.ts
727
727
 
728
728
  import { css } from 'styled-components';
729
729
  import { getPluginTheme } from '@_sh/strapi-plugin-ckeditor';
@@ -849,7 +849,7 @@ for detailed instructions.
849
849
 
850
850
  Strapi **>= 5.0.0**
851
851
 
852
- Node **>= 18.0.0 <= 22.x.x**
852
+ Node **>= 20.0.0 <= 24.x.x**
853
853
 
854
854
  ---
855
855
 
@@ -30,7 +30,7 @@ const admin = require("@strapi/strapi/admin");
30
30
  const ckeditor5 = require("ckeditor5");
31
31
  const ckeditor5React = require("@ckeditor/ckeditor5-react");
32
32
  require("ckeditor5/ckeditor5.css");
33
- const index = require("./index-CgWKes-C.js");
33
+ const index = require("./index-V5z1nLLU.js");
34
34
  require("sanitize-html");
35
35
  const icons = require("@strapi/icons");
36
36
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -309,7 +309,7 @@ function MediaLib({ isOpen = false, toggle, handleChangeAssets }) {
309
309
  return /* @__PURE__ */ jsxRuntime.jsx(MediaLibraryDialog, { onClose: toggle, onSelectAssets: handleSelectAssets });
310
310
  }
311
311
  const MemoizedMediaLib = React__default.default.memo(MediaLib);
312
- function CKEReact() {
312
+ const CKEReact = React__default.default.forwardRef((_, forwardedRef) => {
313
313
  const [mediaLibVisible, setMediaLibVisible] = React.useState(false);
314
314
  const [editorInstance, setEditorInstance] = React.useState(null);
315
315
  const [isWordsMax, setIsWordsMax] = React.useState(false);
@@ -317,13 +317,20 @@ function CKEReact() {
317
317
  const { name, disabled, preset, wordsLimit, charsLimit } = useEditorContext();
318
318
  const { onChange: fieldOnChange, value: fieldValue } = admin.useField(name);
319
319
  const wordCounterRef = React.useRef(null);
320
+ const debounceTimeout = React.useRef(null);
320
321
  const onEditorReady = (editor) => {
321
322
  setUpPlugins(editor);
322
323
  setEditorInstance(editor);
323
324
  };
324
325
  const onEditorChange = (_e, editor) => {
326
+ if (debounceTimeout.current) {
327
+ clearTimeout(debounceTimeout.current);
328
+ }
325
329
  const data = editor.getData();
326
- fieldOnChange(name, data);
330
+ debounceTimeout.current = setTimeout(() => {
331
+ fieldOnChange(name, data);
332
+ debounceTimeout.current = null;
333
+ }, 300);
327
334
  };
328
335
  const toggleMediaLib = React.useCallback(() => setMediaLibVisible((prev) => !prev), [setMediaLibVisible]);
329
336
  const handleChangeAssets = React.useCallback(
@@ -338,6 +345,24 @@ function CKEReact() {
338
345
  },
339
346
  [toggleMediaLib, editorInstance]
340
347
  );
348
+ React.useEffect(() => {
349
+ const ckWrapper = document.querySelector(".ck-body-wrapper");
350
+ const listener = ckWrapper?.addEventListener("pointerdown", (e) => e.stopPropagation(), true);
351
+ return () => {
352
+ if (listener) {
353
+ ckWrapper?.removeEventListener("pointerdown", listener);
354
+ }
355
+ };
356
+ }, [editorInstance]);
357
+ React.useImperativeHandle(
358
+ forwardedRef,
359
+ () => ({
360
+ focus() {
361
+ editorInstance?.focus();
362
+ }
363
+ }),
364
+ [editorInstance]
365
+ );
341
366
  if (!preset) {
342
367
  return null;
343
368
  }
@@ -421,7 +446,7 @@ function CKEReact() {
421
446
  setIsCharsMax(stats.characters > charsLimit);
422
447
  }
423
448
  }
424
- }
449
+ });
425
450
  const WordCounter = styledComponents.styled(designSystem.Flex)`
426
451
  ${({ theme, $isWordsMax, $isCharsMax }) => styledComponents.css`
427
452
  .ck-word-count__words {
@@ -434,7 +459,25 @@ const WordCounter = styledComponents.styled(designSystem.Flex)`
434
459
  `;
435
460
  function EditorLayout({ children }) {
436
461
  const { error, preset } = useEditorContext();
437
- const [isExpandedMode, handleToggleExpand] = React.useReducer((prev) => !prev, false);
462
+ const [isExpandedMode, setIsExpandedMode] = React.useState(false);
463
+ const handleToggleExpand = (open) => {
464
+ if (open) {
465
+ setTimeout(() => {
466
+ const ckPopupsWrapper = document.querySelector(".ck-body-wrapper");
467
+ const ckEditorModal = document.getElementById("ck-editor-modal");
468
+ if (ckPopupsWrapper && ckEditorModal) {
469
+ ckEditorModal.appendChild(ckPopupsWrapper);
470
+ }
471
+ document.querySelector(".ck-editor__expanded .ck-editor__editable")?.focus();
472
+ }, 0);
473
+ } else {
474
+ const ckPopupsWrapper = document.querySelector(".ck-body-wrapper");
475
+ if (ckPopupsWrapper) {
476
+ document.body.appendChild(ckPopupsWrapper);
477
+ }
478
+ }
479
+ setIsExpandedMode(open);
480
+ };
438
481
  React.useEffect(() => {
439
482
  if (isExpandedMode) {
440
483
  document.body.classList.add("lock-body-scroll");
@@ -444,41 +487,34 @@ function EditorLayout({ children }) {
444
487
  };
445
488
  }, [isExpandedMode]);
446
489
  if (isExpandedMode) {
447
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Portal, { role: "dialog", "aria-modal": false, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.FocusTrap, { onEscape: handleToggleExpand, children: /* @__PURE__ */ jsxRuntime.jsx(
448
- Backdrop,
490
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isExpandedMode, onOpenChange: handleToggleExpand, children: /* @__PURE__ */ jsxRuntime.jsx(Content, { id: "ck-editor-modal", children: /* @__PURE__ */ jsxRuntime.jsx(
491
+ designSystem.Flex,
449
492
  {
450
- position: "fixed",
451
- top: 0,
452
- left: 0,
453
- right: 0,
454
- bottom: 0,
455
- zIndex: 4,
456
- justifyContent: "center",
457
- onClick: handleToggleExpand,
458
- children: /* @__PURE__ */ jsxRuntime.jsx(
459
- FullScreenBox,
493
+ height: "90dvh",
494
+ width: "90dvw",
495
+ maxWidth: "100%",
496
+ direction: "column",
497
+ alignItems: "flex-start",
498
+ background: "neutral100",
499
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
500
+ EditorWrapper,
460
501
  {
461
- background: "neutral100",
462
- hasRadius: true,
463
- shadow: "popupShadow",
464
- overflow: "hidden",
465
- width: "90%",
466
- height: "90%",
467
- onClick: (e) => e.stopPropagation(),
468
- position: "relative",
469
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { height: "100%", alignItems: "flex-start", direction: "column", children: /* @__PURE__ */ jsxRuntime.jsxs(
470
- EditorWrapper,
471
- {
472
- $presetStyles: preset?.styles,
473
- $isExpanded: isExpandedMode,
474
- $hasError: Boolean(error),
475
- className: "ck-editor__expanded",
476
- children: [
477
- children,
478
- /* @__PURE__ */ jsxRuntime.jsx(CollapseButton, { label: "Collapse", onClick: handleToggleExpand, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Collapse, {}) })
479
- ]
480
- }
481
- ) })
502
+ $presetStyles: preset?.styles,
503
+ $isExpanded: isExpandedMode,
504
+ $hasError: Boolean(error),
505
+ className: "ck-editor__expanded",
506
+ children: [
507
+ children,
508
+ /* @__PURE__ */ jsxRuntime.jsx(
509
+ CollapseButton,
510
+ {
511
+ tabIndex: "-1",
512
+ label: "Collapse",
513
+ onClick: () => handleToggleExpand(false),
514
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Collapse, {})
515
+ }
516
+ )
517
+ ]
482
518
  }
483
519
  )
484
520
  }
@@ -492,7 +528,7 @@ function EditorLayout({ children }) {
492
528
  $hasError: Boolean(error),
493
529
  children: [
494
530
  children,
495
- /* @__PURE__ */ jsxRuntime.jsx(ExpandButton, { label: "Expand", onClick: handleToggleExpand, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Expand, {}) })
531
+ /* @__PURE__ */ jsxRuntime.jsx(ExpandButton, { label: "Expand", onClick: () => handleToggleExpand(true), children: /* @__PURE__ */ jsxRuntime.jsx(icons.Expand, {}) })
496
532
  ]
497
533
  }
498
534
  );
@@ -534,11 +570,10 @@ const CollapseButton = styledComponents.styled(designSystem.IconButton)`
534
570
  z-index: 2;
535
571
  box-shadow: ${({ theme }) => theme.shadows.filterShadow};
536
572
  `;
537
- const FullScreenBox = styledComponents.styled(designSystem.Box)`
573
+ const Content = styledComponents.styled(designSystem.Modal.Content)`
538
574
  max-width: var(--ck-editor-full-screen-box-max-width);
539
- `;
540
- const Backdrop = styledComponents.styled(designSystem.Flex)`
541
- background: ${({ theme }) => `${theme.colors.neutral800}1F`};
575
+ width: unset;
576
+ overflow: visible;
542
577
  `;
543
578
  const GlobalStyle = styledComponents.createGlobalStyle`
544
579
  ${({ $editortTheme, $variant }) => $editortTheme && styledComponents.css`
@@ -555,18 +590,18 @@ function GlobalStyling() {
555
590
  return /* @__PURE__ */ jsxRuntime.jsx(GlobalStyle, { $editortTheme: theme, $variant: variant });
556
591
  }
557
592
  const MemoizedGlobalStyling = React__default.default.memo(GlobalStyling);
558
- function Editor() {
593
+ const Editor = React__default.default.forwardRef((_, forwardedRef) => {
559
594
  const { name, hint, required, labelAction, label, error, preset } = useEditorContext();
560
595
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Root, { id: name, name, error, hint, required, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
561
596
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { action: labelAction, children: label }),
562
597
  preset ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
563
598
  /* @__PURE__ */ jsxRuntime.jsx(MemoizedGlobalStyling, {}),
564
- /* @__PURE__ */ jsxRuntime.jsx(EditorLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(CKEReact, {}) })
599
+ /* @__PURE__ */ jsxRuntime.jsx(EditorLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(CKEReact, { ref: forwardedRef }) })
565
600
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(LoaderBox, { hasRadius: true, background: "neutral100", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: "Loading..." }) }),
566
601
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {}),
567
602
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
568
603
  ] }) });
569
- }
604
+ });
570
605
  const LoaderBox = styledComponents.styled(designSystem.Box)`
571
606
  display: flex;
572
607
  justify-content: center;
@@ -574,38 +609,40 @@ const LoaderBox = styledComponents.styled(designSystem.Box)`
574
609
  height: 200px;
575
610
  width: 100%;
576
611
  `;
577
- function Field({
578
- name,
579
- hint,
580
- error,
581
- placeholder,
582
- label,
583
- attribute,
584
- labelAction = null,
585
- disabled = false,
586
- required = false
587
- }) {
588
- const { preset, maxLengthWords, maxLengthCharacters } = attribute.options;
589
- const isFieldLocalized = attribute?.pluginOptions?.i18n?.localized ?? false;
590
- return /* @__PURE__ */ jsxRuntime.jsx(
591
- EditorProvider,
592
- {
593
- name,
594
- error,
595
- disabled,
596
- required,
597
- placeholder,
598
- hint,
599
- label,
600
- labelAction,
601
- presetName: preset,
602
- wordsLimit: maxLengthWords,
603
- charsLimit: maxLengthCharacters,
604
- isFieldLocalized,
605
- children: /* @__PURE__ */ jsxRuntime.jsx(Editor, {})
606
- }
607
- );
608
- }
612
+ const Field = React__default.default.forwardRef(
613
+ ({
614
+ name,
615
+ hint,
616
+ error,
617
+ placeholder,
618
+ label,
619
+ attribute,
620
+ labelAction = null,
621
+ disabled = false,
622
+ required = false
623
+ }, forwardedRef) => {
624
+ const { preset, maxLengthWords, maxLengthCharacters } = attribute.options;
625
+ const isFieldLocalized = attribute?.pluginOptions?.i18n?.localized ?? false;
626
+ return /* @__PURE__ */ jsxRuntime.jsx(
627
+ EditorProvider,
628
+ {
629
+ name,
630
+ error,
631
+ disabled,
632
+ required,
633
+ placeholder,
634
+ hint,
635
+ label,
636
+ labelAction,
637
+ presetName: preset,
638
+ wordsLimit: maxLengthWords,
639
+ charsLimit: maxLengthCharacters,
640
+ isFieldLocalized,
641
+ children: /* @__PURE__ */ jsxRuntime.jsx(Editor, { ref: forwardedRef })
642
+ }
643
+ );
644
+ }
645
+ );
609
646
  function compare(oldProps, newProps) {
610
647
  return oldProps.error === newProps.error && oldProps.labelAction === newProps.labelAction;
611
648
  }
@@ -1,12 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import React, { createContext, useState, useEffect, useMemo, useContext, useRef, useCallback, useReducer } from "react";
3
- import { Flex, IconButton, Box, Portal, FocusTrap, Field as Field$1, Loader } from "@strapi/design-system";
2
+ import React, { createContext, useContext, useState, useEffect, useMemo, useRef, useCallback, useImperativeHandle } from "react";
3
+ import { Flex, IconButton, Modal, Field as Field$1, Loader, Box } from "@strapi/design-system";
4
4
  import { styled, css, createGlobalStyle } from "styled-components";
5
5
  import { useStrapiApp, useField } from "@strapi/strapi/admin";
6
6
  import { ClassicEditor } from "ckeditor5";
7
7
  import { CKEditor } from "@ckeditor/ckeditor5-react";
8
8
  import "ckeditor5/ckeditor5.css";
9
- import { g as getPluginConfig, p as prefixFileUrlWithBackendUrl, i as isImageResponsive } from "./index-CM-eZqTL.mjs";
9
+ import { g as getPluginConfig, p as prefixFileUrlWithBackendUrl, i as isImageResponsive } from "./index-D6brYb_3.mjs";
10
10
  import "sanitize-html";
11
11
  import { Collapse, Expand } from "@strapi/icons";
12
12
  const STORAGE_KEYS = {
@@ -283,7 +283,7 @@ function MediaLib({ isOpen = false, toggle, handleChangeAssets }) {
283
283
  return /* @__PURE__ */ jsx(MediaLibraryDialog, { onClose: toggle, onSelectAssets: handleSelectAssets });
284
284
  }
285
285
  const MemoizedMediaLib = React.memo(MediaLib);
286
- function CKEReact() {
286
+ const CKEReact = React.forwardRef((_, forwardedRef) => {
287
287
  const [mediaLibVisible, setMediaLibVisible] = useState(false);
288
288
  const [editorInstance, setEditorInstance] = useState(null);
289
289
  const [isWordsMax, setIsWordsMax] = useState(false);
@@ -291,13 +291,20 @@ function CKEReact() {
291
291
  const { name, disabled, preset, wordsLimit, charsLimit } = useEditorContext();
292
292
  const { onChange: fieldOnChange, value: fieldValue } = useField(name);
293
293
  const wordCounterRef = useRef(null);
294
+ const debounceTimeout = useRef(null);
294
295
  const onEditorReady = (editor) => {
295
296
  setUpPlugins(editor);
296
297
  setEditorInstance(editor);
297
298
  };
298
299
  const onEditorChange = (_e, editor) => {
300
+ if (debounceTimeout.current) {
301
+ clearTimeout(debounceTimeout.current);
302
+ }
299
303
  const data = editor.getData();
300
- fieldOnChange(name, data);
304
+ debounceTimeout.current = setTimeout(() => {
305
+ fieldOnChange(name, data);
306
+ debounceTimeout.current = null;
307
+ }, 300);
301
308
  };
302
309
  const toggleMediaLib = useCallback(() => setMediaLibVisible((prev) => !prev), [setMediaLibVisible]);
303
310
  const handleChangeAssets = useCallback(
@@ -312,6 +319,24 @@ function CKEReact() {
312
319
  },
313
320
  [toggleMediaLib, editorInstance]
314
321
  );
322
+ useEffect(() => {
323
+ const ckWrapper = document.querySelector(".ck-body-wrapper");
324
+ const listener = ckWrapper?.addEventListener("pointerdown", (e) => e.stopPropagation(), true);
325
+ return () => {
326
+ if (listener) {
327
+ ckWrapper?.removeEventListener("pointerdown", listener);
328
+ }
329
+ };
330
+ }, [editorInstance]);
331
+ useImperativeHandle(
332
+ forwardedRef,
333
+ () => ({
334
+ focus() {
335
+ editorInstance?.focus();
336
+ }
337
+ }),
338
+ [editorInstance]
339
+ );
315
340
  if (!preset) {
316
341
  return null;
317
342
  }
@@ -395,7 +420,7 @@ function CKEReact() {
395
420
  setIsCharsMax(stats.characters > charsLimit);
396
421
  }
397
422
  }
398
- }
423
+ });
399
424
  const WordCounter = styled(Flex)`
400
425
  ${({ theme, $isWordsMax, $isCharsMax }) => css`
401
426
  .ck-word-count__words {
@@ -408,7 +433,25 @@ const WordCounter = styled(Flex)`
408
433
  `;
409
434
  function EditorLayout({ children }) {
410
435
  const { error, preset } = useEditorContext();
411
- const [isExpandedMode, handleToggleExpand] = useReducer((prev) => !prev, false);
436
+ const [isExpandedMode, setIsExpandedMode] = useState(false);
437
+ const handleToggleExpand = (open) => {
438
+ if (open) {
439
+ setTimeout(() => {
440
+ const ckPopupsWrapper = document.querySelector(".ck-body-wrapper");
441
+ const ckEditorModal = document.getElementById("ck-editor-modal");
442
+ if (ckPopupsWrapper && ckEditorModal) {
443
+ ckEditorModal.appendChild(ckPopupsWrapper);
444
+ }
445
+ document.querySelector(".ck-editor__expanded .ck-editor__editable")?.focus();
446
+ }, 0);
447
+ } else {
448
+ const ckPopupsWrapper = document.querySelector(".ck-body-wrapper");
449
+ if (ckPopupsWrapper) {
450
+ document.body.appendChild(ckPopupsWrapper);
451
+ }
452
+ }
453
+ setIsExpandedMode(open);
454
+ };
412
455
  useEffect(() => {
413
456
  if (isExpandedMode) {
414
457
  document.body.classList.add("lock-body-scroll");
@@ -418,41 +461,34 @@ function EditorLayout({ children }) {
418
461
  };
419
462
  }, [isExpandedMode]);
420
463
  if (isExpandedMode) {
421
- return /* @__PURE__ */ jsx(Portal, { role: "dialog", "aria-modal": false, children: /* @__PURE__ */ jsx(FocusTrap, { onEscape: handleToggleExpand, children: /* @__PURE__ */ jsx(
422
- Backdrop,
464
+ return /* @__PURE__ */ jsx(Modal.Root, { open: isExpandedMode, onOpenChange: handleToggleExpand, children: /* @__PURE__ */ jsx(Content, { id: "ck-editor-modal", children: /* @__PURE__ */ jsx(
465
+ Flex,
423
466
  {
424
- position: "fixed",
425
- top: 0,
426
- left: 0,
427
- right: 0,
428
- bottom: 0,
429
- zIndex: 4,
430
- justifyContent: "center",
431
- onClick: handleToggleExpand,
432
- children: /* @__PURE__ */ jsx(
433
- FullScreenBox,
467
+ height: "90dvh",
468
+ width: "90dvw",
469
+ maxWidth: "100%",
470
+ direction: "column",
471
+ alignItems: "flex-start",
472
+ background: "neutral100",
473
+ children: /* @__PURE__ */ jsxs(
474
+ EditorWrapper,
434
475
  {
435
- background: "neutral100",
436
- hasRadius: true,
437
- shadow: "popupShadow",
438
- overflow: "hidden",
439
- width: "90%",
440
- height: "90%",
441
- onClick: (e) => e.stopPropagation(),
442
- position: "relative",
443
- children: /* @__PURE__ */ jsx(Flex, { height: "100%", alignItems: "flex-start", direction: "column", children: /* @__PURE__ */ jsxs(
444
- EditorWrapper,
445
- {
446
- $presetStyles: preset?.styles,
447
- $isExpanded: isExpandedMode,
448
- $hasError: Boolean(error),
449
- className: "ck-editor__expanded",
450
- children: [
451
- children,
452
- /* @__PURE__ */ jsx(CollapseButton, { label: "Collapse", onClick: handleToggleExpand, children: /* @__PURE__ */ jsx(Collapse, {}) })
453
- ]
454
- }
455
- ) })
476
+ $presetStyles: preset?.styles,
477
+ $isExpanded: isExpandedMode,
478
+ $hasError: Boolean(error),
479
+ className: "ck-editor__expanded",
480
+ children: [
481
+ children,
482
+ /* @__PURE__ */ jsx(
483
+ CollapseButton,
484
+ {
485
+ tabIndex: "-1",
486
+ label: "Collapse",
487
+ onClick: () => handleToggleExpand(false),
488
+ children: /* @__PURE__ */ jsx(Collapse, {})
489
+ }
490
+ )
491
+ ]
456
492
  }
457
493
  )
458
494
  }
@@ -466,7 +502,7 @@ function EditorLayout({ children }) {
466
502
  $hasError: Boolean(error),
467
503
  children: [
468
504
  children,
469
- /* @__PURE__ */ jsx(ExpandButton, { label: "Expand", onClick: handleToggleExpand, children: /* @__PURE__ */ jsx(Expand, {}) })
505
+ /* @__PURE__ */ jsx(ExpandButton, { label: "Expand", onClick: () => handleToggleExpand(true), children: /* @__PURE__ */ jsx(Expand, {}) })
470
506
  ]
471
507
  }
472
508
  );
@@ -508,11 +544,10 @@ const CollapseButton = styled(IconButton)`
508
544
  z-index: 2;
509
545
  box-shadow: ${({ theme }) => theme.shadows.filterShadow};
510
546
  `;
511
- const FullScreenBox = styled(Box)`
547
+ const Content = styled(Modal.Content)`
512
548
  max-width: var(--ck-editor-full-screen-box-max-width);
513
- `;
514
- const Backdrop = styled(Flex)`
515
- background: ${({ theme }) => `${theme.colors.neutral800}1F`};
549
+ width: unset;
550
+ overflow: visible;
516
551
  `;
517
552
  const GlobalStyle = createGlobalStyle`
518
553
  ${({ $editortTheme, $variant }) => $editortTheme && css`
@@ -529,18 +564,18 @@ function GlobalStyling() {
529
564
  return /* @__PURE__ */ jsx(GlobalStyle, { $editortTheme: theme, $variant: variant });
530
565
  }
531
566
  const MemoizedGlobalStyling = React.memo(GlobalStyling);
532
- function Editor() {
567
+ const Editor = React.forwardRef((_, forwardedRef) => {
533
568
  const { name, hint, required, labelAction, label, error, preset } = useEditorContext();
534
569
  return /* @__PURE__ */ jsx(Field$1.Root, { id: name, name, error, hint, required, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
535
570
  /* @__PURE__ */ jsx(Field$1.Label, { action: labelAction, children: label }),
536
571
  preset ? /* @__PURE__ */ jsxs(Fragment, { children: [
537
572
  /* @__PURE__ */ jsx(MemoizedGlobalStyling, {}),
538
- /* @__PURE__ */ jsx(EditorLayout, { children: /* @__PURE__ */ jsx(CKEReact, {}) })
573
+ /* @__PURE__ */ jsx(EditorLayout, { children: /* @__PURE__ */ jsx(CKEReact, { ref: forwardedRef }) })
539
574
  ] }) : /* @__PURE__ */ jsx(LoaderBox, { hasRadius: true, background: "neutral100", children: /* @__PURE__ */ jsx(Loader, { children: "Loading..." }) }),
540
575
  /* @__PURE__ */ jsx(Field$1.Hint, {}),
541
576
  /* @__PURE__ */ jsx(Field$1.Error, {})
542
577
  ] }) });
543
- }
578
+ });
544
579
  const LoaderBox = styled(Box)`
545
580
  display: flex;
546
581
  justify-content: center;
@@ -548,38 +583,40 @@ const LoaderBox = styled(Box)`
548
583
  height: 200px;
549
584
  width: 100%;
550
585
  `;
551
- function Field({
552
- name,
553
- hint,
554
- error,
555
- placeholder,
556
- label,
557
- attribute,
558
- labelAction = null,
559
- disabled = false,
560
- required = false
561
- }) {
562
- const { preset, maxLengthWords, maxLengthCharacters } = attribute.options;
563
- const isFieldLocalized = attribute?.pluginOptions?.i18n?.localized ?? false;
564
- return /* @__PURE__ */ jsx(
565
- EditorProvider,
566
- {
567
- name,
568
- error,
569
- disabled,
570
- required,
571
- placeholder,
572
- hint,
573
- label,
574
- labelAction,
575
- presetName: preset,
576
- wordsLimit: maxLengthWords,
577
- charsLimit: maxLengthCharacters,
578
- isFieldLocalized,
579
- children: /* @__PURE__ */ jsx(Editor, {})
580
- }
581
- );
582
- }
586
+ const Field = React.forwardRef(
587
+ ({
588
+ name,
589
+ hint,
590
+ error,
591
+ placeholder,
592
+ label,
593
+ attribute,
594
+ labelAction = null,
595
+ disabled = false,
596
+ required = false
597
+ }, forwardedRef) => {
598
+ const { preset, maxLengthWords, maxLengthCharacters } = attribute.options;
599
+ const isFieldLocalized = attribute?.pluginOptions?.i18n?.localized ?? false;
600
+ return /* @__PURE__ */ jsx(
601
+ EditorProvider,
602
+ {
603
+ name,
604
+ error,
605
+ disabled,
606
+ required,
607
+ placeholder,
608
+ hint,
609
+ label,
610
+ labelAction,
611
+ presetName: preset,
612
+ wordsLimit: maxLengthWords,
613
+ charsLimit: maxLengthCharacters,
614
+ isFieldLocalized,
615
+ children: /* @__PURE__ */ jsx(Editor, { ref: forwardedRef })
616
+ }
617
+ );
618
+ }
619
+ );
583
620
  function compare(oldProps, newProps) {
584
621
  return oldProps.error === newProps.error && oldProps.labelAction === newProps.labelAction;
585
622
  }