UNPKG

5.92 kBJavaScriptView Raw
1/**
2 * External dependencies
3 */
4import classnames from 'classnames';
5import { isFinite, omit } from 'lodash';
6
7/**
8 * WordPress dependencies
9 */
10import { __ } from '@wordpress/i18n';
11import {
12 RawHTML,
13} from '@wordpress/element';
14import {
15 getColorClassName,
16 getFontSizeClass,
17 RichText,
18} from '@wordpress/block-editor';
19import { getPhrasingContentSchema } from '@wordpress/blocks';
20import {
21 Path,
22 SVG,
23} from '@wordpress/components';
24
25/**
26 * Internal dependencies
27 */
28import edit from './edit';
29
30const supports = {
31 className: false,
32};
33
34const 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
75export const name = 'core/paragraph';
76
77export 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};