UNPKG

3.51 kBJavaScriptView Raw
1/**
2 * External dependencies
3 */
4import classnames from 'classnames';
5
6/**
7 * WordPress dependencies
8 */
9import { __, _x } from '@wordpress/i18n';
10import { getPhrasingContentSchema } from '@wordpress/blocks';
11import { G, Path, SVG } from '@wordpress/components';
12import { RichText, getColorClassName } from '@wordpress/block-editor';
13
14/**
15 * Internal dependencies
16 */
17import edit from './edit';
18
19const tableContentPasteSchema = {
20 tr: {
21 allowEmpty: true,
22 children: {
23 th: {
24 allowEmpty: true,
25 children: getPhrasingContentSchema(),
26 },
27 td: {
28 allowEmpty: true,
29 children: getPhrasingContentSchema(),
30 },
31 },
32 },
33};
34
35const tablePasteSchema = {
36 table: {
37 children: {
38 thead: {
39 allowEmpty: true,
40 children: tableContentPasteSchema,
41 },
42 tfoot: {
43 allowEmpty: true,
44 children: tableContentPasteSchema,
45 },
46 tbody: {
47 allowEmpty: true,
48 children: tableContentPasteSchema,
49 },
50 },
51 },
52};
53
54function getTableSectionAttributeSchema( section ) {
55 return {
56 type: 'array',
57 default: [],
58 source: 'query',
59 selector: `t${ section } tr`,
60 query: {
61 cells: {
62 type: 'array',
63 default: [],
64 source: 'query',
65 selector: 'td,th',
66 query: {
67 content: {
68 type: 'string',
69 source: 'html',
70 },
71 tag: {
72 type: 'string',
73 default: 'td',
74 source: 'tag',
75 },
76 },
77 },
78 },
79 };
80}
81
82export const name = 'core/table';
83
84export const settings = {
85 title: __( 'Table' ),
86 description: __( 'Insert a table — perfect for sharing charts and data.' ),
87 icon: <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><Path fill="none" d="M0 0h24v24H0V0z" /><G><Path d="M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v3H5V5h15zm-5 14h-5v-9h5v9zM5 10h3v9H5v-9zm12 9v-9h3v9h-3z" /></G></SVG>,
88 category: 'formatting',
89
90 attributes: {
91 hasFixedLayout: {
92 type: 'boolean',
93 default: false,
94 },
95 backgroundColor: {
96 type: 'string',
97 },
98 head: getTableSectionAttributeSchema( 'head' ),
99 body: getTableSectionAttributeSchema( 'body' ),
100 foot: getTableSectionAttributeSchema( 'foot' ),
101 },
102
103 styles: [
104 { name: 'regular', label: _x( 'Default', 'block style' ), isDefault: true },
105 { name: 'stripes', label: __( 'Stripes' ) },
106 ],
107
108 supports: {
109 align: true,
110 },
111
112 transforms: {
113 from: [
114 {
115 type: 'raw',
116 selector: 'table',
117 schema: tablePasteSchema,
118 },
119 ],
120 },
121
122 edit,
123
124 save( { attributes } ) {
125 const {
126 hasFixedLayout,
127 head,
128 body,
129 foot,
130 backgroundColor,
131 } = attributes;
132 const isEmpty = ! head.length && ! body.length && ! foot.length;
133
134 if ( isEmpty ) {
135 return null;
136 }
137
138 const backgroundClass = getColorClassName( 'background-color', backgroundColor );
139
140 const classes = classnames( backgroundClass, {
141 'has-fixed-layout': hasFixedLayout,
142 'has-background': !! backgroundClass,
143 } );
144
145 const Section = ( { type, rows } ) => {
146 if ( ! rows.length ) {
147 return null;
148 }
149
150 const Tag = `t${ type }`;
151
152 return (
153 <Tag>
154 { rows.map( ( { cells }, rowIndex ) => (
155 <tr key={ rowIndex }>
156 { cells.map( ( { content, tag }, cellIndex ) =>
157 <RichText.Content
158 tagName={ tag }
159 value={ content }
160 key={ cellIndex }
161 />
162 ) }
163 </tr>
164 ) ) }
165 </Tag>
166 );
167 };
168
169 return (
170 <table className={ classes }>
171 <Section type="head" rows={ head } />
172 <Section type="body" rows={ body } />
173 <Section type="foot" rows={ foot } />
174 </table>
175 );
176 },
177};