1 |
|
2 |
|
3 |
|
4 | import classnames from 'classnames';
|
5 | import { isFinite, omit } from 'lodash';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | import { __ } from '@wordpress/i18n';
|
11 | import {
|
12 | RawHTML,
|
13 | } from '@wordpress/element';
|
14 | import {
|
15 | getColorClassName,
|
16 | getFontSizeClass,
|
17 | RichText,
|
18 | } from '@wordpress/block-editor';
|
19 | import { getPhrasingContentSchema } from '@wordpress/blocks';
|
20 | import {
|
21 | Path,
|
22 | SVG,
|
23 | } from '@wordpress/components';
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | import edit from './edit';
|
29 |
|
30 | const supports = {
|
31 | className: false,
|
32 | };
|
33 |
|
34 | const schema = {
|
35 | content: {
|
36 | type: 'string',
|
37 | source: 'html',
|
38 | selector: 'p',
|
39 | default: '',
|
40 | },
|
41 | align: {
|
42 | type: 'string',
|
43 | },
|
44 | dropCap: {
|
45 | type: 'boolean',
|
46 | default: false,
|
47 | },
|
48 | placeholder: {
|
49 | type: 'string',
|
50 | },
|
51 | textColor: {
|
52 | type: 'string',
|
53 | },
|
54 | customTextColor: {
|
55 | type: 'string',
|
56 | },
|
57 | backgroundColor: {
|
58 | type: 'string',
|
59 | },
|
60 | customBackgroundColor: {
|
61 | type: 'string',
|
62 | },
|
63 | fontSize: {
|
64 | type: 'string',
|
65 | },
|
66 | customFontSize: {
|
67 | type: 'number',
|
68 | },
|
69 | direction: {
|
70 | type: 'string',
|
71 | enum: [ 'ltr', 'rtl' ],
|
72 | },
|
73 | };
|
74 |
|
75 | export const name = 'core/paragraph';
|
76 |
|
77 | export const settings = {
|
78 | title: __( 'Paragraph' ),
|
79 |
|
80 | description: __( 'Start with the building block of all narrative.' ),
|
81 |
|
82 | icon: <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><Path d="M11 5v7H9.5C7.6 12 6 10.4 6 8.5S7.6 5 9.5 5H11m8-2H9.5C6.5 3 4 5.5 4 8.5S6.5 14 9.5 14H11v7h2V5h2v16h2V5h2V3z" /></SVG>,
|
83 |
|
84 | category: 'common',
|
85 |
|
86 | keywords: [ __( 'text' ) ],
|
87 |
|
88 | supports,
|
89 |
|
90 | attributes: schema,
|
91 |
|
92 | transforms: {
|
93 | from: [
|
94 | {
|
95 | type: 'raw',
|
96 | // Paragraph is a fallback and should be matched last.
|
97 | priority: 20,
|
98 | selector: 'p',
|
99 | schema: {
|
100 | p: {
|
101 | children: getPhrasingContentSchema(),
|
102 | },
|
103 | },
|
104 | },
|
105 | ],
|
106 | },
|
107 |
|
108 | deprecated: [
|
109 | {
|
110 | supports,
|
111 | attributes: {
|
112 | ...schema,
|
113 | width: {
|
114 | type: 'string',
|
115 | },
|
116 | },
|
117 | save( { attributes } ) {
|
118 | const {
|
119 | width,
|
120 | align,
|
121 | content,
|
122 | dropCap,
|
123 | backgroundColor,
|
124 | textColor,
|
125 | customBackgroundColor,
|
126 | customTextColor,
|
127 | fontSize,
|
128 | customFontSize,
|
129 | } = attributes;
|
130 |
|
131 | const textClass = getColorClassName( 'color', textColor );
|
132 | const backgroundClass = getColorClassName( 'background-color', backgroundColor );
|
133 | const fontSizeClass = fontSize && `is-${ fontSize }-text`;
|
134 |
|
135 | const className = classnames( {
|
136 | [ `align${ width }` ]: width,
|
137 | 'has-background': backgroundColor || customBackgroundColor,
|
138 | 'has-drop-cap': dropCap,
|
139 | [ fontSizeClass ]: fontSizeClass,
|
140 | [ textClass ]: textClass,
|
141 | [ backgroundClass ]: backgroundClass,
|
142 | } );
|
143 |
|
144 | const styles = {
|
145 | backgroundColor: backgroundClass ? undefined : customBackgroundColor,
|
146 | color: textClass ? undefined : customTextColor,
|
147 | fontSize: fontSizeClass ? undefined : customFontSize,
|
148 | textAlign: align,
|
149 | };
|
150 |
|
151 | return (
|
152 | <RichText.Content
|
153 | tagName="p"
|
154 | style={ styles }
|
155 | className={ className ? className : undefined }
|
156 | value={ content }
|
157 | />
|
158 | );
|
159 | },
|
160 | },
|
161 | {
|
162 | supports,
|
163 | attributes: omit( {
|
164 | ...schema,
|
165 | fontSize: {
|
166 | type: 'number',
|
167 | },
|
168 | }, 'customFontSize', 'customTextColor', 'customBackgroundColor' ),
|
169 | save( { attributes } ) {
|
170 | const { width, align, content, dropCap, backgroundColor, textColor, fontSize } = attributes;
|
171 | const className = classnames( {
|
172 | [ `align${ width }` ]: width,
|
173 | 'has-background': backgroundColor,
|
174 | 'has-drop-cap': dropCap,
|
175 | } );
|
176 | const styles = {
|
177 | backgroundColor,
|
178 | color: textColor,
|
179 | fontSize,
|
180 | textAlign: align,
|
181 | };
|
182 |
|
183 | return <p style={ styles } className={ className ? className : undefined }>{ content }</p>;
|
184 | },
|
185 | migrate( attributes ) {
|
186 | return omit( {
|
187 | ...attributes,
|
188 | customFontSize: isFinite( attributes.fontSize ) ? attributes.fontSize : undefined,
|
189 | customTextColor: attributes.textColor && '#' === attributes.textColor[ 0 ] ? attributes.textColor : undefined,
|
190 | customBackgroundColor: attributes.backgroundColor && '#' === attributes.backgroundColor[ 0 ] ? attributes.backgroundColor : undefined,
|
191 | }, [ 'fontSize', 'textColor', 'backgroundColor' ] );
|
192 | },
|
193 | },
|
194 | {
|
195 | supports,
|
196 | attributes: {
|
197 | ...schema,
|
198 | content: {
|
199 | type: 'string',
|
200 | source: 'html',
|
201 | default: '',
|
202 | },
|
203 | },
|
204 | save( { attributes } ) {
|
205 | return <RawHTML>{ attributes.content }</RawHTML>;
|
206 | },
|
207 | migrate( attributes ) {
|
208 | return attributes;
|
209 | },
|
210 | },
|
211 | ],
|
212 |
|
213 | merge( attributes, attributesToMerge ) {
|
214 | return {
|
215 | content: ( attributes.content || '' ) + ( attributesToMerge.content || '' ),
|
216 | };
|
217 | },
|
218 |
|
219 | getEditWrapperProps( attributes ) {
|
220 | const { width } = attributes;
|
221 | if ( [ 'wide', 'full', 'left', 'right' ].indexOf( width ) !== -1 ) {
|
222 | return { 'data-align': width };
|
223 | }
|
224 | },
|
225 |
|
226 | edit,
|
227 |
|
228 | save( { attributes } ) {
|
229 | const {
|
230 | align,
|
231 | content,
|
232 | dropCap,
|
233 | backgroundColor,
|
234 | textColor,
|
235 | customBackgroundColor,
|
236 | customTextColor,
|
237 | fontSize,
|
238 | customFontSize,
|
239 | direction,
|
240 | } = attributes;
|
241 |
|
242 | const textClass = getColorClassName( 'color', textColor );
|
243 | const backgroundClass = getColorClassName( 'background-color', backgroundColor );
|
244 | const fontSizeClass = getFontSizeClass( fontSize );
|
245 |
|
246 | const className = classnames( {
|
247 | 'has-text-color': textColor || customTextColor,
|
248 | 'has-background': backgroundColor || customBackgroundColor,
|
249 | 'has-drop-cap': dropCap,
|
250 | [ fontSizeClass ]: fontSizeClass,
|
251 | [ textClass ]: textClass,
|
252 | [ backgroundClass ]: backgroundClass,
|
253 | } );
|
254 |
|
255 | const styles = {
|
256 | backgroundColor: backgroundClass ? undefined : customBackgroundColor,
|
257 | color: textClass ? undefined : customTextColor,
|
258 | fontSize: fontSizeClass ? undefined : customFontSize,
|
259 | textAlign: align,
|
260 | };
|
261 |
|
262 | return (
|
263 | <RichText.Content
|
264 | tagName="p"
|
265 | style={ styles }
|
266 | className={ className ? className : undefined }
|
267 | value={ content }
|
268 | dir={ direction }
|
269 | />
|
270 | );
|
271 | },
|
272 | };
|