1 |
|
2 |
|
3 |
|
4 | import classnames from 'classnames';
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | import { __, _x } from '@wordpress/i18n';
|
10 | import { getPhrasingContentSchema } from '@wordpress/blocks';
|
11 | import { G, Path, SVG } from '@wordpress/components';
|
12 | import { RichText, getColorClassName } from '@wordpress/block-editor';
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | import edit from './edit';
|
18 |
|
19 | const 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 |
|
35 | const 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 |
|
54 | function 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 |
|
82 | export const name = 'core/table';
|
83 |
|
84 | export 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 | };
|