@wordpress/block-library 9.34.1-next.2f1c7c01b.0 → 9.35.1-next.16d95556a.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 (172) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/block/edit.js +2 -2
  3. package/build/block/edit.js.map +2 -2
  4. package/build/block-keyboard-shortcuts/index.js +17 -7
  5. package/build/block-keyboard-shortcuts/index.js.map +2 -2
  6. package/build/cover/deprecated.js +15 -3
  7. package/build/cover/deprecated.js.map +2 -2
  8. package/build/cover/edit/inspector-controls.js +1 -1
  9. package/build/cover/edit/inspector-controls.js.map +2 -2
  10. package/build/cover/transforms.js +10 -2
  11. package/build/cover/transforms.js.map +2 -2
  12. package/build/embed/icons.js +2 -2
  13. package/build/embed/icons.js.map +2 -2
  14. package/build/embed/variations.js +3 -3
  15. package/build/embed/variations.js.map +2 -2
  16. package/build/heading/index.js +3 -1
  17. package/build/heading/index.js.map +3 -3
  18. package/build/heading/transforms.js +10 -3
  19. package/build/heading/transforms.js.map +2 -2
  20. package/build/heading/variations.js +55 -0
  21. package/build/heading/variations.js.map +7 -0
  22. package/build/html/edit.js +54 -44
  23. package/build/html/edit.js.map +3 -3
  24. package/build/html/modal.js +328 -0
  25. package/build/html/modal.js.map +7 -0
  26. package/build/html/utils.js +72 -0
  27. package/build/html/utils.js.map +7 -0
  28. package/build/navigation-link/edit.js +25 -10
  29. package/build/navigation-link/edit.js.map +2 -2
  30. package/build/navigation-link/link-ui/index.js +8 -3
  31. package/build/navigation-link/link-ui/index.js.map +2 -2
  32. package/build/navigation-link/shared/controls.js +42 -7
  33. package/build/navigation-link/shared/controls.js.map +2 -2
  34. package/build/navigation-link/shared/use-entity-binding.js +31 -2
  35. package/build/navigation-link/shared/use-entity-binding.js.map +3 -3
  36. package/build/paragraph/block.json +1 -3
  37. package/build/paragraph/deprecated.js +65 -12
  38. package/build/paragraph/deprecated.js.map +2 -2
  39. package/build/paragraph/edit.js +14 -25
  40. package/build/paragraph/edit.js.map +2 -2
  41. package/build/paragraph/index.js +3 -1
  42. package/build/paragraph/index.js.map +3 -3
  43. package/build/paragraph/save.js +3 -3
  44. package/build/paragraph/save.js.map +2 -2
  45. package/build/paragraph/transforms.js +7 -1
  46. package/build/paragraph/transforms.js.map +2 -2
  47. package/build/paragraph/variations.js +57 -0
  48. package/build/paragraph/variations.js.map +7 -0
  49. package/build/pullquote/block.json +3 -2
  50. package/build/pullquote/transforms.js +0 -31
  51. package/build/pullquote/transforms.js.map +2 -2
  52. package/build/quote/transforms.js +0 -20
  53. package/build/quote/transforms.js.map +2 -2
  54. package/build-module/block/edit.js +2 -2
  55. package/build-module/block/edit.js.map +2 -2
  56. package/build-module/block-keyboard-shortcuts/index.js +17 -7
  57. package/build-module/block-keyboard-shortcuts/index.js.map +2 -2
  58. package/build-module/cover/deprecated.js +15 -3
  59. package/build-module/cover/deprecated.js.map +2 -2
  60. package/build-module/cover/edit/inspector-controls.js +1 -1
  61. package/build-module/cover/edit/inspector-controls.js.map +2 -2
  62. package/build-module/cover/transforms.js +10 -2
  63. package/build-module/cover/transforms.js.map +2 -2
  64. package/build-module/embed/icons.js +2 -2
  65. package/build-module/embed/icons.js.map +2 -2
  66. package/build-module/embed/variations.js +3 -3
  67. package/build-module/embed/variations.js.map +2 -2
  68. package/build-module/heading/index.js +3 -1
  69. package/build-module/heading/index.js.map +2 -2
  70. package/build-module/heading/transforms.js +10 -3
  71. package/build-module/heading/transforms.js.map +2 -2
  72. package/build-module/heading/variations.js +34 -0
  73. package/build-module/heading/variations.js.map +7 -0
  74. package/build-module/html/edit.js +62 -51
  75. package/build-module/html/edit.js.map +2 -2
  76. package/build-module/html/modal.js +304 -0
  77. package/build-module/html/modal.js.map +7 -0
  78. package/build-module/html/utils.js +46 -0
  79. package/build-module/html/utils.js.map +7 -0
  80. package/build-module/navigation-link/edit.js +25 -10
  81. package/build-module/navigation-link/edit.js.map +2 -2
  82. package/build-module/navigation-link/link-ui/index.js +8 -3
  83. package/build-module/navigation-link/link-ui/index.js.map +2 -2
  84. package/build-module/navigation-link/shared/controls.js +42 -7
  85. package/build-module/navigation-link/shared/controls.js.map +2 -2
  86. package/build-module/navigation-link/shared/use-entity-binding.js +35 -3
  87. package/build-module/navigation-link/shared/use-entity-binding.js.map +2 -2
  88. package/build-module/paragraph/block.json +1 -3
  89. package/build-module/paragraph/deprecated.js +65 -12
  90. package/build-module/paragraph/deprecated.js.map +2 -2
  91. package/build-module/paragraph/edit.js +14 -26
  92. package/build-module/paragraph/edit.js.map +2 -2
  93. package/build-module/paragraph/index.js +3 -1
  94. package/build-module/paragraph/index.js.map +2 -2
  95. package/build-module/paragraph/save.js +3 -3
  96. package/build-module/paragraph/save.js.map +2 -2
  97. package/build-module/paragraph/transforms.js +7 -1
  98. package/build-module/paragraph/transforms.js.map +2 -2
  99. package/build-module/paragraph/variations.js +36 -0
  100. package/build-module/paragraph/variations.js.map +7 -0
  101. package/build-module/pullquote/block.json +3 -2
  102. package/build-module/pullquote/transforms.js +0 -31
  103. package/build-module/pullquote/transforms.js.map +2 -2
  104. package/build-module/quote/transforms.js +0 -20
  105. package/build-module/quote/transforms.js.map +2 -2
  106. package/build-style/accordion-heading/style-rtl.css +19 -3
  107. package/build-style/accordion-heading/style.css +19 -3
  108. package/build-style/accordion-panel/style-rtl.css +4 -1
  109. package/build-style/accordion-panel/style.css +4 -1
  110. package/build-style/common-rtl.css +3 -3
  111. package/build-style/common.css +3 -3
  112. package/build-style/editor-rtl.css +62 -21
  113. package/build-style/editor.css +62 -21
  114. package/build-style/embed/style-rtl.css +5 -0
  115. package/build-style/embed/style.css +5 -0
  116. package/build-style/html/editor-rtl.css +55 -21
  117. package/build-style/html/editor.css +55 -21
  118. package/build-style/navigation-link/editor-rtl.css +7 -0
  119. package/build-style/navigation-link/editor.css +7 -0
  120. package/build-style/style-rtl.css +31 -7
  121. package/build-style/style.css +31 -7
  122. package/package.json +37 -37
  123. package/src/accordion-heading/style.scss +40 -7
  124. package/src/accordion-panel/style.scss +6 -1
  125. package/src/block/edit.js +2 -2
  126. package/src/block-keyboard-shortcuts/index.js +23 -9
  127. package/src/common.scss +6 -5
  128. package/src/cover/deprecated.js +15 -3
  129. package/src/cover/edit/inspector-controls.js +1 -1
  130. package/src/cover/transforms.js +10 -2
  131. package/src/embed/icons.js +2 -4
  132. package/src/embed/style.scss +6 -0
  133. package/src/embed/variations.js +3 -3
  134. package/src/heading/index.js +2 -0
  135. package/src/heading/test/__snapshots__/transforms.native.js.snap +0 -6
  136. package/src/heading/test/transforms.native.js +1 -5
  137. package/src/heading/transforms.js +10 -3
  138. package/src/heading/variations.js +37 -0
  139. package/src/html/edit.js +62 -56
  140. package/src/html/editor.scss +69 -10
  141. package/src/html/modal.js +290 -0
  142. package/src/html/test/utils.js +234 -0
  143. package/src/html/utils.js +75 -0
  144. package/src/navigation-link/edit.js +44 -13
  145. package/src/navigation-link/editor.scss +7 -0
  146. package/src/navigation-link/index.php +65 -2
  147. package/src/navigation-link/link-ui/index.js +9 -8
  148. package/src/navigation-link/shared/controls.js +70 -12
  149. package/src/navigation-link/shared/test/controls.js +5 -0
  150. package/src/navigation-link/shared/test/use-entity-binding.js +14 -1
  151. package/src/navigation-link/shared/use-entity-binding.js +57 -9
  152. package/src/paragraph/block.json +1 -3
  153. package/src/paragraph/deprecated.js +87 -20
  154. package/src/paragraph/edit.js +7 -18
  155. package/src/paragraph/edit.native.js +18 -6
  156. package/src/paragraph/index.js +2 -0
  157. package/src/paragraph/save.js +4 -3
  158. package/src/paragraph/test/__snapshots__/transforms.native.js.snap +0 -6
  159. package/src/paragraph/test/edit.native.js +5 -5
  160. package/src/paragraph/test/transforms.native.js +0 -1
  161. package/src/paragraph/transforms.js +7 -1
  162. package/src/paragraph/variations.js +39 -0
  163. package/src/pullquote/block.json +3 -2
  164. package/src/pullquote/test/__snapshots__/transforms.native.js.snap +5 -5
  165. package/src/pullquote/test/transforms.native.js +1 -1
  166. package/src/pullquote/transforms.js +0 -31
  167. package/src/quote/test/__snapshots__/transforms.native.js.snap +0 -6
  168. package/src/quote/test/transforms.native.js +1 -5
  169. package/src/quote/transforms.js +0 -25
  170. package/src/utils/transformation-categories.native.js +0 -1
  171. package/tsconfig.tsbuildinfo +1 -1
  172. package/src/pullquote/test/edit.native.js +0 -73
@@ -0,0 +1,37 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { Path, SVG } from '@wordpress/primitives';
6
+ import { heading } from '@wordpress/icons';
7
+
8
+ const variations = [
9
+ {
10
+ name: 'heading',
11
+ title: __( 'Heading' ),
12
+ description: __(
13
+ 'Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.'
14
+ ),
15
+ isDefault: true,
16
+ scope: [ 'inserter', 'transform' ],
17
+ attributes: { fitText: undefined },
18
+ icon: heading,
19
+ },
20
+ // There is a hardcoded workaround in packages/block-editor/src/store/selectors.js
21
+ // to make Stretchy variations appear as the last of their sections in the inserter.
22
+ {
23
+ name: 'stretchy-heading',
24
+ title: __( 'Stretchy Heading' ),
25
+ description: __( 'Heading that resizes to fit its container.' ),
26
+ icon: (
27
+ <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
28
+ <Path d="m3 18.6 6-4.7 6 4.7V5H3v13.6Zm16.2-9.8v1.5h2.2L17.7 14l1.1 1.1 3.7-3.7v2.2H24V8.8h-4.8Z" />
29
+ </SVG>
30
+ ),
31
+ attributes: { fitText: true },
32
+ scope: [ 'inserter', 'transform' ],
33
+ isActive: ( blockAttributes ) => blockAttributes.fitText === true,
34
+ },
35
+ ];
36
+
37
+ export default variations;
package/src/html/edit.js CHANGED
@@ -2,88 +2,94 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
- import { useContext, useState } from '@wordpress/element';
5
+ import { useState } from '@wordpress/element';
6
6
  import {
7
7
  BlockControls,
8
- PlainText,
8
+ BlockIcon,
9
+ InspectorControls,
9
10
  useBlockProps,
10
- store as blockEditorStore,
11
11
  } from '@wordpress/block-editor';
12
12
  import {
13
13
  ToolbarButton,
14
- Disabled,
15
14
  ToolbarGroup,
16
- VisuallyHidden,
15
+ Placeholder,
16
+ Button,
17
+ __experimentalVStack as VStack,
17
18
  } from '@wordpress/components';
18
- import { useSelect } from '@wordpress/data';
19
- import { useInstanceId } from '@wordpress/compose';
19
+ import { code } from '@wordpress/icons';
20
20
 
21
21
  /**
22
22
  * Internal dependencies
23
23
  */
24
24
  import Preview from './preview';
25
+ import HTMLEditModal from './modal';
25
26
 
26
27
  export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
27
- const [ isPreview, setIsPreview ] = useState();
28
- const isDisabled = useContext( Disabled.Context );
29
-
30
- const instanceId = useInstanceId( HTMLEdit, 'html-edit-desc' );
31
-
32
- const isPreviewMode = useSelect( ( select ) => {
33
- return select( blockEditorStore ).getSettings().isPreviewMode;
34
- }, [] );
35
-
36
- function switchToPreview() {
37
- setIsPreview( true );
38
- }
39
-
40
- function switchToHTML() {
41
- setIsPreview( false );
42
- }
43
-
28
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
44
29
  const blockProps = useBlockProps( {
45
30
  className: 'block-library-html__edit',
46
- 'aria-describedby': isPreview ? instanceId : undefined,
47
31
  } );
48
32
 
33
+ // Show placeholder when content is empty
34
+ if ( ! attributes.content?.trim() ) {
35
+ return (
36
+ <div { ...blockProps }>
37
+ <Placeholder
38
+ icon={ <BlockIcon icon={ code } /> }
39
+ label={ __( 'Custom HTML' ) }
40
+ instructions={ __(
41
+ 'Add custom HTML code and preview how it looks.'
42
+ ) }
43
+ >
44
+ <Button
45
+ __next40pxDefaultSize
46
+ variant="primary"
47
+ onClick={ () => setIsModalOpen( true ) }
48
+ >
49
+ { __( 'Edit HTML' ) }
50
+ </Button>
51
+ </Placeholder>
52
+ <HTMLEditModal
53
+ isOpen={ isModalOpen }
54
+ onRequestClose={ () => setIsModalOpen( false ) }
55
+ content={ attributes.content }
56
+ setAttributes={ setAttributes }
57
+ />
58
+ </div>
59
+ );
60
+ }
61
+
49
62
  return (
50
63
  <div { ...blockProps }>
51
64
  <BlockControls>
52
65
  <ToolbarGroup>
53
- <ToolbarButton
54
- isPressed={ ! isPreview }
55
- onClick={ switchToHTML }
56
- >
57
- HTML
58
- </ToolbarButton>
59
- <ToolbarButton
60
- isPressed={ isPreview }
61
- onClick={ switchToPreview }
62
- >
63
- { __( 'Preview' ) }
66
+ <ToolbarButton onClick={ () => setIsModalOpen( true ) }>
67
+ { __( 'Edit code' ) }
64
68
  </ToolbarButton>
65
69
  </ToolbarGroup>
66
70
  </BlockControls>
67
- { isPreview || isPreviewMode || isDisabled ? (
68
- <>
69
- <Preview
70
- content={ attributes.content }
71
- isSelected={ isSelected }
72
- />
73
- <VisuallyHidden id={ instanceId }>
74
- { __(
75
- 'HTML preview is not yet fully accessible. Please switch screen reader to virtualized mode to navigate the below iFrame.'
76
- ) }
77
- </VisuallyHidden>
78
- </>
79
- ) : (
80
- <PlainText
81
- value={ attributes.content }
82
- onChange={ ( content ) => setAttributes( { content } ) }
83
- placeholder={ __( 'Write HTML…' ) }
84
- aria-label={ __( 'HTML' ) }
85
- />
86
- ) }
71
+ <InspectorControls>
72
+ <VStack
73
+ className="block-editor-block-inspector-edit-contents"
74
+ expanded
75
+ >
76
+ <Button
77
+ className="block-editor-block-inspector-edit-contents__button"
78
+ __next40pxDefaultSize
79
+ variant="secondary"
80
+ onClick={ () => setIsModalOpen( true ) }
81
+ >
82
+ { __( 'Edit code' ) }
83
+ </Button>
84
+ </VStack>
85
+ </InspectorControls>
86
+ <Preview content={ attributes.content } isSelected={ isSelected } />
87
+ <HTMLEditModal
88
+ isOpen={ isModalOpen }
89
+ onRequestClose={ () => setIsModalOpen( false ) }
90
+ content={ attributes.content }
91
+ setAttributes={ setAttributes }
92
+ />
87
93
  </div>
88
94
  );
89
95
  }
@@ -1,4 +1,6 @@
1
1
  @use "@wordpress/base-styles/mixins" as *;
2
+ @use "@wordpress/base-styles/variables" as *;
3
+ @use "@wordpress/base-styles/colors" as *;
2
4
 
3
5
  .block-library-html__edit {
4
6
  .block-library-html__preview-overlay {
@@ -8,16 +10,73 @@
8
10
  top: 0;
9
11
  left: 0;
10
12
  }
13
+ }
14
+
15
+ // Modal styles
16
+ .block-library-html__modal {
17
+ // Make modal content scrollable
18
+ .components-modal__content {
19
+ display: flex;
20
+ flex-direction: column;
21
+ padding: 0;
22
+ min-height: 70vh;
23
+ }
24
+
25
+ .components-modal__children-container {
26
+ height: 100%;
27
+ padding: $grid-unit-20;
28
+ }
29
+ }
30
+
31
+ .block-library-html__modal-tabs {
32
+ height: 100%;
33
+ }
34
+
35
+ .block-library-html__modal-tab {
36
+ height: 100%;
37
+ display: flex;
38
+ flex-direction: column;
39
+ margin: 0;
40
+ box-sizing: border-box;
41
+ border: 1px solid $gray-200;
42
+ border-radius: 2px;
43
+ padding: $grid-unit-20;
44
+ font-family: $editor-html-font;
45
+ }
46
+
47
+ .block-library-html__modal-editor {
48
+ width: 100%;
49
+ height: 100%;
50
+ flex: 1;
51
+ // Reset textarea styles to inherit from pre
52
+ border: none;
53
+ background: transparent;
54
+ padding: 0;
55
+ font-family: inherit;
56
+ font-size: inherit;
57
+ line-height: inherit;
58
+ color: inherit;
59
+ resize: none;
60
+ // HTML input is always LTR regardless of language.
61
+ /*rtl:ignore*/
62
+ direction: ltr;
63
+ overflow-x: auto;
64
+ box-sizing: border-box;
11
65
 
12
- // The editing view for the HTML block is equivalent to block UI.
13
- // Therefore we increase specificity to avoid theme styles bleeding in.
14
- .block-editor-plain-text {
15
- display: block;
16
- box-sizing: border-box;
17
- max-height: 250px;
18
- @include editor-input-reset();
19
- // HTML input is always LTR regardless of language.
20
- /*rtl:ignore*/
21
- direction: ltr;
66
+ &:focus {
67
+ outline: none;
68
+ box-shadow: none;
22
69
  }
23
70
  }
71
+
72
+ .block-library-html__preview {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ padding: $grid-unit-60;
77
+ }
78
+
79
+ .block-library-html__modal-actions {
80
+ margin-top: $grid-unit-20;
81
+ padding: 0 $grid-unit-40 $grid-unit-40;
82
+ }
@@ -0,0 +1,290 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { useState, useMemo } from '@wordpress/element';
6
+ import { useSelect } from '@wordpress/data';
7
+ import {
8
+ Modal,
9
+ Button,
10
+ Flex,
11
+ privateApis as componentsPrivateApis,
12
+ __experimentalHStack as HStack,
13
+ __experimentalVStack as VStack,
14
+ } from '@wordpress/components';
15
+ import { PlainText, store as blockEditorStore } from '@wordpress/block-editor';
16
+ import { fullscreen, square } from '@wordpress/icons';
17
+
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+ import { unlock } from '../lock-unlock';
22
+ import Preview from './preview';
23
+ import { parseContent, serializeContent } from './utils';
24
+
25
+ const { Tabs } = unlock( componentsPrivateApis );
26
+
27
+ export default function HTMLEditModal( {
28
+ isOpen,
29
+ onRequestClose,
30
+ content,
31
+ setAttributes,
32
+ } ) {
33
+ // Parse content into separate sections and use as initial state
34
+ const { html, css, js } = parseContent( content );
35
+ const [ editedHtml, setEditedHtml ] = useState( html );
36
+ const [ editedCss, setEditedCss ] = useState( css );
37
+ const [ editedJs, setEditedJs ] = useState( js );
38
+ const [ isDirty, setIsDirty ] = useState( false );
39
+ const [ showUnsavedWarning, setShowUnsavedWarning ] = useState( false );
40
+ const [ isFullscreen, setIsFullscreen ] = useState( false );
41
+
42
+ // Check if user has permission to save scripts and get editor styles
43
+ const { canUserUseUnfilteredHTML, editorStyles } = useSelect(
44
+ ( select ) => {
45
+ const settings = select( blockEditorStore ).getSettings();
46
+ return {
47
+ canUserUseUnfilteredHTML:
48
+ settings.__experimentalCanUserUseUnfilteredHTML,
49
+ editorStyles: settings.styles,
50
+ };
51
+ },
52
+ []
53
+ );
54
+
55
+ // Show JS tab if user has permission OR if block contains JavaScript
56
+ const shouldShowJsTab = canUserUseUnfilteredHTML || js.trim() !== '';
57
+
58
+ // Combine all editor styles to inject into modal
59
+ const styleContent = useMemo( () => {
60
+ if ( ! editorStyles ) {
61
+ return '';
62
+ }
63
+ return editorStyles
64
+ .filter( ( style ) => style.css )
65
+ .map( ( style ) => style.css )
66
+ .join( '\n' );
67
+ }, [ editorStyles ] );
68
+
69
+ if ( ! isOpen ) {
70
+ return null;
71
+ }
72
+
73
+ const handleHtmlChange = ( value ) => {
74
+ setEditedHtml( value );
75
+ setIsDirty( true );
76
+ };
77
+ const handleCssChange = ( value ) => {
78
+ setEditedCss( value );
79
+ setIsDirty( true );
80
+ };
81
+ const handleJsChange = ( value ) => {
82
+ setEditedJs( value );
83
+ setIsDirty( true );
84
+ };
85
+ const handleUpdate = () => {
86
+ setAttributes( {
87
+ content: serializeContent( {
88
+ html: editedHtml,
89
+ css: editedCss,
90
+ js: editedJs,
91
+ } ),
92
+ } );
93
+ setIsDirty( false );
94
+ };
95
+ const handleCancel = () => {
96
+ setIsDirty( false );
97
+ onRequestClose();
98
+ };
99
+ const handleRequestClose = () => {
100
+ if ( isDirty ) {
101
+ setShowUnsavedWarning( true );
102
+ } else {
103
+ onRequestClose();
104
+ }
105
+ };
106
+ const handleDiscardChanges = () => {
107
+ setShowUnsavedWarning( false );
108
+ onRequestClose();
109
+ };
110
+ const handleContinueEditing = () => {
111
+ setShowUnsavedWarning( false );
112
+ };
113
+ const handleUpdateAndClose = () => {
114
+ handleUpdate();
115
+ onRequestClose();
116
+ };
117
+ const toggleFullscreen = () => {
118
+ setIsFullscreen( ( prevState ) => ! prevState );
119
+ };
120
+
121
+ return (
122
+ <>
123
+ <Modal
124
+ title={ __( 'Edit HTML' ) }
125
+ onRequestClose={ handleRequestClose }
126
+ className="block-library-html__modal"
127
+ size="large"
128
+ isDismissible={ false }
129
+ shouldCloseOnClickOutside={ ! isDirty }
130
+ shouldCloseOnEsc={ ! isDirty }
131
+ isFullScreen={ isFullscreen }
132
+ __experimentalHideHeader
133
+ >
134
+ { styleContent && (
135
+ <style
136
+ dangerouslySetInnerHTML={ { __html: styleContent } }
137
+ />
138
+ ) }
139
+ <Tabs orientation="horizontal" defaultTabId="html">
140
+ <VStack spacing={ 4 } style={ { height: '100%' } }>
141
+ <HStack justify="space-between">
142
+ <div>
143
+ <Tabs.TabList>
144
+ <Tabs.Tab tabId="html">HTML</Tabs.Tab>
145
+ <Tabs.Tab tabId="css">CSS</Tabs.Tab>
146
+ { shouldShowJsTab && (
147
+ <Tabs.Tab tabId="js">
148
+ { __( 'JavaScript' ) }
149
+ </Tabs.Tab>
150
+ ) }
151
+ </Tabs.TabList>
152
+ </div>
153
+ <div>
154
+ <Button
155
+ __next40pxDefaultSize
156
+ icon={ isFullscreen ? square : fullscreen }
157
+ label={ __( 'Enable/disable fullscreen' ) }
158
+ onClick={ toggleFullscreen }
159
+ variant="tertiary"
160
+ />
161
+ </div>
162
+ </HStack>
163
+ <HStack
164
+ alignment="stretch"
165
+ justify="flex-start"
166
+ spacing={ 4 }
167
+ className="block-library-html__modal-tabs"
168
+ style={ { flexGrow: 1 } }
169
+ >
170
+ <div style={ { flexGrow: 1 } }>
171
+ <Tabs.TabPanel
172
+ tabId="html"
173
+ focusable={ false }
174
+ className="block-library-html__modal-tab"
175
+ >
176
+ <PlainText
177
+ value={ editedHtml }
178
+ onChange={ handleHtmlChange }
179
+ placeholder={ __( 'Write HTML…' ) }
180
+ aria-label={ __( 'HTML' ) }
181
+ className="block-library-html__modal-editor"
182
+ />
183
+ </Tabs.TabPanel>
184
+ <Tabs.TabPanel
185
+ tabId="css"
186
+ focusable={ false }
187
+ className="block-library-html__modal-tab"
188
+ >
189
+ <PlainText
190
+ value={ editedCss }
191
+ onChange={ handleCssChange }
192
+ placeholder={ __( 'Write CSS…' ) }
193
+ aria-label={ __( 'CSS' ) }
194
+ className="block-library-html__modal-editor"
195
+ />
196
+ </Tabs.TabPanel>
197
+ { shouldShowJsTab && (
198
+ <Tabs.TabPanel
199
+ tabId="js"
200
+ focusable={ false }
201
+ className="block-library-html__modal-tab"
202
+ >
203
+ <PlainText
204
+ value={ editedJs }
205
+ onChange={ handleJsChange }
206
+ placeholder={ __(
207
+ 'Write JavaScript…'
208
+ ) }
209
+ aria-label={ __( 'JavaScript' ) }
210
+ className="block-library-html__modal-editor"
211
+ />
212
+ </Tabs.TabPanel>
213
+ ) }
214
+ </div>
215
+ <div
216
+ className="block-library-html__preview"
217
+ style={ { width: '50%' } }
218
+ >
219
+ <Preview
220
+ content={ serializeContent( {
221
+ html: editedHtml,
222
+ css: editedCss,
223
+ js: editedJs,
224
+ } ) }
225
+ />
226
+ </div>
227
+ </HStack>
228
+ <HStack
229
+ alignment="center"
230
+ justify="flex-end"
231
+ spacing={ 4 }
232
+ >
233
+ <Button
234
+ __next40pxDefaultSize
235
+ variant="tertiary"
236
+ onClick={ handleCancel }
237
+ >
238
+ { __( 'Cancel' ) }
239
+ </Button>
240
+ <Button
241
+ __next40pxDefaultSize
242
+ variant="primary"
243
+ onClick={ handleUpdateAndClose }
244
+ >
245
+ { __( 'Update' ) }
246
+ </Button>
247
+ </HStack>
248
+ </VStack>
249
+ </Tabs>
250
+ </Modal>
251
+
252
+ { showUnsavedWarning && (
253
+ <Modal
254
+ title={ __( 'Unsaved changes' ) }
255
+ onRequestClose={ handleContinueEditing }
256
+ size="medium"
257
+ >
258
+ <p>
259
+ { __(
260
+ 'You have unsaved changes. What would you like to do?'
261
+ ) }
262
+ </p>
263
+ <Flex direction="row" justify="flex-end" gap={ 2 }>
264
+ <Button
265
+ __next40pxDefaultSize
266
+ variant="secondary"
267
+ onClick={ handleDiscardChanges }
268
+ >
269
+ { __( 'Discard unsaved changes' ) }
270
+ </Button>
271
+ <Button
272
+ __next40pxDefaultSize
273
+ variant="secondary"
274
+ onClick={ handleContinueEditing }
275
+ >
276
+ { __( 'Continue editing' ) }
277
+ </Button>
278
+ <Button
279
+ __next40pxDefaultSize
280
+ variant="primary"
281
+ onClick={ handleUpdateAndClose }
282
+ >
283
+ { __( 'Update and close' ) }
284
+ </Button>
285
+ </Flex>
286
+ </Modal>
287
+ ) }
288
+ </>
289
+ );
290
+ }