PluginProbe ʕ •ᴥ•ʔ
VK Blocks / trunk
VK Blocks vtrunk
1.122.0 1.121.0 1.120.0 1.119.2 1.119.1 1.119.0 1.118.7 1.82.0.0 1.82.0.1 1.83.0.0 1.83.0.1 1.84.0.0 1.84.0.1 1.85.0.2 1.85.0.3 1.85.1.0 1.85.1.1 1.86.0.0 1.86.0.1 1.86.1.0 1.87.0.0 1.87.0.1 1.88.0.1 1.88.0.2 1.89.0.0 1.9.2 1.90.0.0 1.90.0.1 1.90.1.1 1.91.0.0 1.91.1.1 1.92.0.0 1.92.0.1 1.92.1.0 1.92.1.1 1.93.0.0 trunk 1.93.0.1 0.1.1 1.93.1.0 0.10.3 1.93.1.1 0.11.0 1.94.0.0 0.12.6 1.94.0.1 0.15.1 1.94.1.0 0.16.2 1.94.2.1 0.17.6 1.94.2.2 0.2.2 1.95.0.3 0.22.4 1.95.0.4 0.26.7 1.96.2.0 0.3.2 1.96.2.1 0.31.0 1.97.0.1 0.35.5 1.97.0.2 0.37.5 1.99.0.0 0.38.8 1.99.0.1 0.39.4 0.4.7 0.41.0 0.42.0 0.44.13 0.45.2 0.46.1 0.47.0 0.48.0 0.49.8 0.5.2 0.50.3 0.51.0 0.52.2 0.53.2 0.54.0 0.55.0 0.56.2 0.56.3 0.57.6 0.58.10 0.59.0 0.6.0 0.60.1 0.61.2 0.7.1 0.8.2 1.0.16 1.10.0 1.100.0.0 1.100.0.1 1.102.0.0 1.102.0.1 1.103.0.0 1.104.0.0 1.104.0.1 1.105.1.0 1.105.1.1 1.106.0.0 1.106.0.1 1.107.0.0 1.107.0.1 1.107.0.2 1.108.0.0 1.108.0.1 1.109.0.0 1.109.0.1 1.11.4 1.110.0.0 1.110.0.1 1.111.0.0 1.111.0.1 1.111.0.2 1.112.0.0 1.112.0.1 1.113.0.0 1.113.0.1 1.114.0.0 1.114.0.1 1.114.2.0 1.114.2.1 1.115.0.0 1.115.0.1 1.115.1.0 1.115.1.1 1.115.2.0 1.115.2.1 1.116.0.0 1.116.0.1 1.116.1.0 1.116.1.1 1.116.2.0 1.117.0.0 1.117.0.1 1.117.1.0 1.118.2 1.118.5 1.12.0 1.13.2 1.14.1 1.15.1 1.16.11 1.17.0 1.18.6 1.19.0 1.19.1 1.2.3 1.20.7 1.21.0 1.22.4 1.23.0 1.24.5 1.25.1 1.26.2 1.27.7.2 1.28.0.1 1.29.2.0 1.3.9 1.30.0.1 1.31.0.1 1.32.0.2 1.33.2.1 1.36.1.5 1.37.0.0 1.39.2.1 1.4.6 1.40.0.1 1.40.1.0 1.40.1.1 1.41.0.0 1.41.0.1 1.41.2.2 1.41.2.3 1.43.0.0 1.43.0.1 1.43.0.2 1.44.0.0 1.44.0.1 1.45.0.0 1.45.0.1 1.46.0.0 1.46.0.1 1.47.0.0 1.47.0.1 1.47.1.0 1.48.0.0 1.48.0.1 1.48.0.2 1.48.1.0 1.48.1.1 1.5.0 1.50.0.0 1.50.0.1 1.51.0.0 1.51.0.1 1.52.0.0 1.52.0.1 1.53.0.0 1.53.0.1 1.54.0.0 1.54.0.1 1.55.0.0 1.55.0.1 1.56.0.0 1.56.0.1 1.57.0.0 1.57.0.2 1.57.0.3 1.57.0.4 1.57.0.5 1.57.1.0 1.57.1.1 1.57.1.2 1.58.0.0 1.58.0.1 1.59.0.0 1.59.0.1 1.6.0 1.60.0.0 1.60.0.1 1.63.0.0 1.63.0.1 1.64.0.0 1.64.0.1 1.64.1.0 1.64.1.2 1.67.0.0 1.67.0.1 1.68.0.0 1.68.0.1 1.69.0.0 1.69.0.1 1.69.1.1 1.69.1.2 1.7.1 1.70.0.0 1.70.0.1 1.71.0.0 1.71.0.1 1.72.0.0 1.72.1.0 1.72.1.1 1.73.0.0 1.73.0.1 1.74.0.0 1.74.0.1 1.75.0.0 1.75.1.0 1.75.1.1 1.76.0.0 1.76.0.1 1.76.1.0 1.76.1.1 1.76.2.0 1.76.2.1 1.77.0.0 1.77.0.1 1.78.0.0 1.78.0.1 1.79.0.0 1.79.0.1 1.79.0.2 1.79.0.3 1.79.1.0 1.79.1.1 1.8.2 1.80.1.0 1.80.1.1 1.80.1.2 1.81.0.1 1.81.0.2
vk-blocks / src / components / code-mirror-css / index.js
vk-blocks / src / components / code-mirror-css Last commit date
index.js 2 months ago
index.js
182 lines
1 /**
2 * WordPress dependencies
3 */
4 import { __ } from '@wordpress/i18n';
5 import { transformStyles } from '@wordpress/block-editor';
6 import { useState, useRef, useEffect } from '@wordpress/element';
7 import { Tooltip, Icon } from '@wordpress/components';
8 import { info } from '@wordpress/icons';
9
10 /**
11 * External dependencies
12 */
13 import classnames from 'classnames';
14 import CodeMirror from '@uiw/react-codemirror';
15 import { css } from '@codemirror/lang-css';
16 import { EditorView } from '@codemirror/view';
17
18 /**
19 * Internal dependencies
20 */
21 import { stripHTML } from '@vkblocks/utils/strip-html';
22
23 export const CodeMirrorCss = (props) => {
24 const {
25 id = 'vk-custom-css-code-mirror',
26 className,
27 value,
28 onChange,
29 style = {
30 ...style,
31 marginTop: '0.5em',
32 border: '1px solid #ccc',
33 height: '200px',
34 resize: 'vertical',
35 overflow: 'hidden',
36 },
37 onBlur = (event) => {
38 if (!event?.target?.textContent) {
39 setCSSError(null);
40 return;
41 }
42
43 const [transformed] = transformStyles(
44 [{ css: event.target.textContent }],
45 '.editor-styles-wrapper'
46 );
47
48 setCSSError(
49 transformed === null
50 ? __(
51 'There is an error with your CSS structure.',
52 'vk-blocks'
53 )
54 : null
55 );
56 },
57 } = props;
58 const [cssError, setCSSError] = useState(null);
59 const wrapperRef = useRef(null);
60 const [isInitialLoad, setIsInitialLoad] = useState(true);
61
62 // リサイズ検知して高さを動的に調整
63 useEffect(() => {
64 if (wrapperRef.current) {
65 const observer = new window.ResizeObserver(() => {
66 if (isInitialLoad) {
67 wrapperRef.current.style.setProperty(
68 'height',
69 'auto',
70 'important'
71 );
72 setIsInitialLoad(false);
73 }
74 });
75 observer.observe(wrapperRef.current);
76 return () => observer.disconnect();
77 }
78 }, [isInitialLoad]);
79
80 // gutterの高さ検知して動的に調整
81 useEffect(() => {
82 if (wrapperRef.current) {
83 const gutters = wrapperRef.current.querySelector('.cm-gutters');
84 if (gutters) {
85 const observer = new window.ResizeObserver(() => {
86 const guttersHeight = gutters.offsetHeight;
87 if (guttersHeight < 200) {
88 gutters.style.setProperty(
89 'minHeight',
90 '200px',
91 'important'
92 );
93 } else {
94 gutters.style.minHeight = '';
95 }
96 });
97 observer.observe(gutters);
98 return () => observer.disconnect();
99 }
100 }
101 }, [value]);
102
103 const customStyleExtension = EditorView.theme({
104 '.cm-editor': {
105 minHeight: '200px',
106 height: '100%',
107 overflowY: 'auto',
108 resize: 'vertical',
109 },
110 '.cm-scroller': {
111 minHeight: '200px',
112 overflow: 'auto',
113 },
114 });
115
116 return (
117 <div
118 className="vk_custom-css-editor-wrapper"
119 style={{ position: 'relative' }}
120 >
121 <CodeMirror
122 id={id}
123 className={classnames(`vk_custom-css-editor`, className)}
124 height="100%" // �
125 部のエディタをラッパーの高さに合わせる
126 // https://uiwjs.github.io/react-codemirror/#/extensions/color
127 extensions={[
128 css(),
129 EditorView.lineWrapping,
130 customStyleExtension,
131 ]}
132 value={value}
133 onChange={(newValue) => {
134 onChange(stripHTML(newValue));
135
136 const [transformed] = transformStyles(
137 [{ css: newValue }],
138 '.editor-styles-wrapper'
139 );
140 if (transformed) {
141 setCSSError(null);
142 }
143 }}
144 style={{
145 ...style,
146 height: '200px',
147 minHeight: '200px',
148 resize: 'vertical',
149 }}
150 onBlur={(event) => {
151 onBlur(event);
152 }}
153 />
154 {cssError && (
155 <Tooltip text={cssError}>
156 <div
157 style={{
158 position: 'absolute',
159 bottom: '0px',
160 right: '5px',
161 }}
162 >
163 <Icon icon={info} style={{ fill: '#cc1818' }} />
164 </div>
165 </Tooltip>
166 )}
167 {(() => {
168 if (value && value.indexOf(' ') !== -1) {
169 return (
170 <p>
171 {__(
172 'Note : Contains double-byte spaces; CSS may not work.',
173 'vk-blocks'
174 )}
175 </p>
176 );
177 }
178 })()}
179 </div>
180 );
181 };
182