diff --git a/.bin/block-manifest-generator.php b/.bin/block-manifest-generator.php new file mode 100644 index 0000000..9f56da0 --- /dev/null +++ b/.bin/block-manifest-generator.php @@ -0,0 +1,125 @@ +getFilename() !== 'index.php' ) { + continue; + } + + // Get the block info. + $block = $file->getPath(); + $block_file = $block . '/index.php'; + $file_modified_time = filemtime( $block_file ); + $block_path = str_replace( $theme_dir . '/', '', $block ) . '/index.php'; + + // If the block file is already in cache and the file is not modified, skip. + if ( isset( $cache[ $block_file ] ) && $cache[ $block_file ]['mtime'] === $file_modified_time ) { + $blocks_mapping[ $block_path ] = $cache[ $block_file ]['namespace']; + continue; + } + + // Tokenize the file to get the namespace. + $tokens = token_get_all( file_get_contents( $block . '/index.php' ) ); + + // Store the namespace. + $namespace = ''; + + // Loop through the tokens to get the namespace. + foreach ( $tokens as $token ) { + // If the token is a namespace token, store the namespace. + // @see: . + if ( T_NAME_QUALIFIED === $token[0] ) { + $namespace = $token[1]; + break; + } + } + + // Bail with error if namespace not found. + if ( empty( $namespace ) ) { + logger( 'Error: Namespace not found in ' . $block_path, 'e' ); + continue; + } + + // Add the namespace to the mapping. + $blocks_mapping[ $block_path ] = $namespace; + + // Update cache. + $cache[ $block_file ] = [ + 'namespace' => $namespace, + 'mtime' => $file_modified_time, + ]; +} + +// If manifest path not exists, create it recursively. +if ( ! file_exists( dirname( $blocks_manifest ) ) ) { + mkdir( dirname( $blocks_manifest ), 0755, true ); +} + +// Add the manifest comment. +$manifest_comment = << "\033[31m$message \033[0m\n", // error + 's' => "\033[32m$message \033[0m\n", // success + 'w' => "\033[33m$message \033[0m\n", // warning + 'i' => "\033[36m$message \033[0m\n", // info + default => $message, + }; + + echo $message; +} + +// Read cache file. +function read_cache( $cache_file ) { + if ( ! file_exists( $cache_file ) ) { + return []; + } + + return json_decode( file_get_contents( $cache_file ), true ); +} + +// Write cache file. +function write_cache( $cache_file, $data ) { + if ( ! file_exists( dirname( $cache_file ) ) ) { + mkdir( dirname( $cache_file ), 0755, true ); + } + + file_put_contents( $cache_file, json_encode( $data, JSON_PRETTY_PRINT ) ); +} diff --git a/.gitignore b/.gitignore index c81b870..72b6ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ vendor # --- Root /* +!.bin !.browserslistrc !.eslintignore !.eslintrc.json @@ -36,4 +37,4 @@ vendor # --- Source Code !inc !src -!dist \ No newline at end of file +!dist diff --git a/dist/blocks.php b/dist/blocks.php new file mode 100644 index 0000000..7de42ae --- /dev/null +++ b/dist/blocks.php @@ -0,0 +1,12 @@ + 'Travelopia\\Blocks\\Table', + 'src/editor/blocks/table/children/column/index.php' => 'Travelopia\\Blocks\\Table\\Column', + 'src/editor/blocks/table/children/cell/index.php' => 'Travelopia\\Blocks\\Table\\Cell', + 'src/editor/blocks/table/children/row/index.php' => 'Travelopia\\Blocks\\Table\\Row', + 'src/editor/blocks/table/children/row-container/index.php' => 'Travelopia\\Blocks\\Table\\RowContainer', +); \ No newline at end of file diff --git a/dist/editor/blocks.asset.php b/dist/editor/blocks.asset.php index a12af25..e3fd5de 100644 --- a/dist/editor/blocks.asset.php +++ b/dist/editor/blocks.asset.php @@ -1 +1 @@ - array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives'), 'version' => 'a9d2811d6f17d28c57df'); + array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives'), 'version' => '326f13cf548360be4989'); diff --git a/dist/editor/blocks.css b/dist/editor/blocks.css index 3d84fb6..8d8a2bd 100644 --- a/dist/editor/blocks.css +++ b/dist/editor/blocks.css @@ -1,2 +1,2 @@ -.travelopia-table__placeholder-input{width:112px}.travelopia-table__placeholder-input input{height:36px}.travelopia-table__placeholder-form{display:flex;flex-direction:column;align-items:flex-start;gap:8px}@media screen and (min-width: 768px){.travelopia-table__placeholder-form{flex-direction:row;align-items:flex-end}}.travelopia-table__placeholder-form .components-base-control__field{margin-bottom:0}.travelopia-table__column.alignleft{float:unset;z-index:unset}.travelopia-table__column.alignright{float:unset;z-index:unset} .travelopia-table table{width:100%;border-collapse:collapse;border-spacing:0}.travelopia-table__column--sticky{position:sticky !important;left:0;z-index:1}.travelopia-table__column.alignleft{text-align:left}.travelopia-table__column.alignleft figure{display:flex;flex-direction:column;align-items:flex-start}.travelopia-table__column.aligncenter{text-align:center}.travelopia-table__column.aligncenter figure{display:flex;flex-direction:column;align-items:center}.travelopia-table__column.alignright{text-align:right}.travelopia-table__column.alignright figure{display:flex;flex-direction:column;align-items:flex-end}.travelopia-table__row-container--sticky tr th{position:sticky !important;top:0;z-index:1} +.travelopia-table__placeholder-input{width:112px}.travelopia-table__placeholder-input input{height:36px}.travelopia-table__placeholder-form{display:flex;flex-direction:column;align-items:flex-start;gap:8px}@media screen and (min-width: 768px){.travelopia-table__placeholder-form{flex-direction:row;align-items:flex-end}}.travelopia-table__placeholder-form .components-base-control__field{margin-bottom:0}.travelopia-table__column.alignleft{float:unset;z-index:unset}.travelopia-table__column.alignright{float:unset;z-index:unset} diff --git a/dist/editor/blocks.css.map b/dist/editor/blocks.css.map index a94032d..d4dd3fb 100644 --- a/dist/editor/blocks.css.map +++ b/dist/editor/blocks.css.map @@ -1 +1 @@ -{"version":3,"file":"./dist/editor/blocks.css","mappings":"AAEC,qCACC,YAEA,2CACC,YAIF,oCACC,aACA,sBACA,uBACA,QAEA,qCAND,oCAOE,mBACA,sBAGD,oEACC,gBAMD,oCACC,YACA,cAGD,qCACC,YACA,c;ACjCF,wBACC,WACA,yBACA,iBAKA,kCACC,2BACA,OACA,UAGD,oCACC,gBAEA,2CACC,aACA,sBACA,uBAIF,sCACC,kBAEA,6CACC,aACA,sBACA,mBAIF,qCACC,iBAEA,4CACC,aACA,sBACA,qBASD,+CACC,2BACA,MACA,U","sources":["webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/editor.scss","webpack://travelopia-wordpress-blocks/./src/front-end/table/index.scss"],"sourcesContent":[".travelopia-table {\n\n\t&__placeholder-input {\n\t\twidth: 8px * 14;\n\n\t\tinput {\n\t\t\theight: 36px;\n\t\t}\n\t}\n\n\t&__placeholder-form {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: flex-start;\n\t\tgap: 8px;\n\n\t\t@media screen and (min-width: 768px) {\n\t\t\tflex-direction: row;\n\t\t\talign-items: flex-end;\n\t\t}\n\n\t\t.components-base-control__field {\n\t\t\tmargin-bottom: 0;\n\t\t}\n\t}\n\n\t&__column {\n\n\t\t&.alignleft {\n\t\t\tfloat: unset;\n\t\t\tz-index: unset;\n\t\t}\n\n\t\t&.alignright {\n\t\t\tfloat: unset;\n\t\t\tz-index: unset;\n\t\t}\n\t}\n}\n",".travelopia-table {\n\n\ttable {\n\t\twidth: 100%;\n\t\tborder-collapse: collapse;\n\t\tborder-spacing: 0;\n\t}\n\n\t&__column {\n\n\t\t&--sticky {\n\t\t\tposition: sticky !important;\n\t\t\tleft: 0;\n\t\t\tz-index: 1;\n\t\t}\n\n\t\t&.alignleft {\n\t\t\ttext-align: left;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: flex-start;\n\t\t\t}\n\t\t}\n\n\t\t&.aligncenter {\n\t\t\ttext-align: center;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t}\n\t\t}\n\n\t\t&.alignright {\n\t\t\ttext-align: right;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: flex-end;\n\t\t\t}\n\t\t}\n\t}\n\n\t&__row-container {\n\n\t\t&--sticky {\n\n\t\t\ttr th {\n\t\t\t\tposition: sticky !important;\n\t\t\t\ttop: 0;\n\t\t\t\tz-index: 1;\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./dist/editor/blocks.css","mappings":"AAEC,wBACC,WACA,yBACA,iBAKA,kCACC,2BACA,OACA,UAGD,oCACC,gBAEA,2CACC,aACA,sBACA,uBAIF,sCACC,kBAEA,6CACC,aACA,sBACA,mBAIF,qCACC,iBAEA,4CACC,aACA,sBACA,qBASD,+CACC,2BACA,MACA,U;ACpDH,qCACC,YAEA,2CACC,YAIF,oCACC,aACA,sBACA,uBACA,QAEA,qCAND,oCAOE,mBACA,sBAGD,oEACC,gBAMD,oCACC,YACA,cAGD,qCACC,YACA,c","sources":["webpack://travelopia-wordpress-blocks/./src/front-end/table/index.scss","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/editor.scss"],"sourcesContent":[".travelopia-table {\n\n\ttable {\n\t\twidth: 100%;\n\t\tborder-collapse: collapse;\n\t\tborder-spacing: 0;\n\t}\n\n\t&__column {\n\n\t\t&--sticky {\n\t\t\tposition: sticky !important;\n\t\t\tleft: 0;\n\t\t\tz-index: 1;\n\t\t}\n\n\t\t&.alignleft {\n\t\t\ttext-align: left;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: flex-start;\n\t\t\t}\n\t\t}\n\n\t\t&.aligncenter {\n\t\t\ttext-align: center;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t}\n\t\t}\n\n\t\t&.alignright {\n\t\t\ttext-align: right;\n\n\t\t\tfigure {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: flex-end;\n\t\t\t}\n\t\t}\n\t}\n\n\t&__row-container {\n\n\t\t&--sticky {\n\n\t\t\ttr th {\n\t\t\t\tposition: sticky !important;\n\t\t\t\ttop: 0;\n\t\t\t\tz-index: 1;\n\t\t\t}\n\t\t}\n\t}\n}\n",".travelopia-table {\n\n\t&__placeholder-input {\n\t\twidth: 8px * 14;\n\n\t\tinput {\n\t\t\theight: 36px;\n\t\t}\n\t}\n\n\t&__placeholder-form {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: flex-start;\n\t\tgap: 8px;\n\n\t\t@media screen and (min-width: 768px) {\n\t\t\tflex-direction: row;\n\t\t\talign-items: flex-end;\n\t\t}\n\n\t\t.components-base-control__field {\n\t\t\tmargin-bottom: 0;\n\t\t}\n\t}\n\n\t&__column {\n\n\t\t&.alignleft {\n\t\t\tfloat: unset;\n\t\t\tz-index: unset;\n\t\t}\n\n\t\t&.alignright {\n\t\t\tfloat: unset;\n\t\t\tz-index: unset;\n\t\t}\n\t}\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/dist/editor/blocks.js b/dist/editor/blocks.js index f9c2439..53c28ab 100644 --- a/dist/editor/blocks.js +++ b/dist/editor/blocks.js @@ -1 +1 @@ -(()=>{var e={251:(e,t,o)=>{"use strict";var n=o(196),r=Symbol.for("react.element"),l=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,o){var n,l={},c=null,p=null;for(n in void 0!==o&&(c=""+o),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(p=t.ref),t)a.call(t,n)&&!i.hasOwnProperty(n)&&(l[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===l[n]&&(l[n]=t[n]);return{$$typeof:r,type:e,key:c,ref:p,props:l,_owner:s.current}}t.Fragment=l,t.jsx=c,t.jsxs=c},893:(e,t,o)=>{"use strict";e.exports=o(251)},196:e=>{"use strict";e.exports=window.React},967:(e,t)=>{var o;!function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e="",t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{"use strict";var e={};o.r(e),o.d(e,{name:()=>z,settings:()=>E});var t={};o.r(t),o.d(t,{name:()=>P,settings:()=>M});var n={};o.r(n),o.d(n,{name:()=>A,settings:()=>N});var r={};o.r(r),o.d(r,{name:()=>G,settings:()=>L});var l={};o.r(l),o.d(l,{name:()=>$,settings:()=>W});const a=window.wp.blocks;var s=o(893);const i=window.wp.i18n,c=window.wp.blockEditor;var p=o(196);const d=window.wp.primitives,u=(0,p.createElement)(d.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,p.createElement)(d.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v3.5h-15V5c0-.3.2-.5.5-.5zm8 5.5h6.5v3.5H13V10zm-1.5 3.5h-7V10h7v3.5zm-7 5.5v-4h7v4.5H5c-.3 0-.5-.2-.5-.5zm14.5.5h-6V15h6.5v4c0 .3-.2.5-.5.5z"})),v=window.wp.element,h=window.wp.components,m=window.wp.data;var b=o(967),w=o.n(b);function k(e){const{setAttributes:t,clientId:o}=e,[n,r]=(0,v.useState)(2),[l,a]=(0,v.useState)(2);return(0,s.jsx)(h.Placeholder,{label:(0,i.__)("Table","tp"),icon:(0,s.jsx)(c.BlockIcon,{icon:u,showColors:!0}),instructions:(0,i.__)("Insert a table for sharing data.","tp"),children:(0,s.jsxs)("form",{className:"travelopia-table__placeholder-form",onSubmit:e=>{e.preventDefault(),t({rows:n,columns:l}),F("tbody",o)},children:[(0,s.jsx)(h.TextControl,{type:"number",label:(0,i.__)("Column count","tp"),value:l,onChange:e=>a(parseInt(e)),min:"1",className:"travelopia-table__placeholder-input"}),(0,s.jsx)(h.TextControl,{type:"number",label:(0,i.__)("Row count","tp"),value:n,onChange:e=>r(parseInt(e)),min:"1",className:"travelopia-table__placeholder-input"}),(0,s.jsx)(h.Button,{variant:"primary",type:"submit",children:(0,i.__)("Create Table","tp")})]})})}const f=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84zM6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84z"})),_=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M13.824 10.176h-2.88v-2.88H9.536v2.88h-2.88v1.344h2.88v2.88h1.408v-2.88h2.88zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm6.4 0H7.68v3.84h5.12V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.056H1.28v9.024H19.2V6.336z"})),g=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M17.728 11.456L14.592 8.32l3.2-3.2-1.536-1.536-3.2 3.2L9.92 3.648 8.384 5.12l3.2 3.2-3.264 3.264 1.536 1.536 3.264-3.264 3.136 3.136 1.472-1.536zM0 17.92V0h20.48v17.92H0zm19.2-6.4h-.448l-1.28-1.28H19.2V6.4h-1.792l1.28-1.28h.512V1.28H1.28v3.84h6.208l1.28 1.28H1.28v3.84h7.424l-1.28 1.28H1.28v3.84H19.2v-3.84z"})),y=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M6.4 3.776v3.648H2.752v1.792H6.4v3.648h1.728V9.216h3.712V7.424H8.128V3.776zM0 17.92V0h20.48v17.92H0zM12.8 1.28H1.28v14.08H12.8V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.12h-5.12v3.84h5.12V6.4zm0 5.12h-5.12v3.84h5.12v-3.84z"})),x=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M14.08 12.864V9.216h3.648V7.424H14.08V3.776h-1.728v3.648H8.64v1.792h3.712v3.648zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm0 5.12H1.28v3.84H6.4V6.4zm0 5.12H1.28v3.84H6.4v-3.84zM19.2 1.28H7.68v14.08H19.2V1.28z"})),B=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,p.createElement)(d.Path,{d:"M6.4 9.98L7.68 8.7v-.256L6.4 7.164V9.98zm6.4-1.532l1.28-1.28V9.92L12.8 8.64v-.192zm7.68 9.472V0H0v17.92h20.48zm-1.28-2.56h-5.12v-1.024l-.256.256-1.024-1.024v1.792H7.68v-1.792l-1.024 1.024-.256-.256v1.024H1.28V1.28H6.4v2.368l.704-.704.576.576V1.216h5.12V3.52l.96-.96.32.32V1.216h5.12V15.36zm-5.76-2.112l-3.136-3.136-3.264 3.264-1.536-1.536 3.264-3.264L5.632 5.44l1.536-1.536 3.136 3.136 3.2-3.2 1.536 1.536-3.2 3.2 3.136 3.136-1.536 1.536z"})),I=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,p.createElement)(d.Path,{d:"M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z"})),V=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,p.createElement)(d.Path,{d:"m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z"})),j=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,p.createElement)(d.Path,{d:"M12 3.9 6.5 9.5l1 1 3.8-3.7V20h1.5V6.8l3.7 3.7 1-1z"})),S=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,p.createElement)(d.Path,{d:"m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z"})),C=(0,p.createElement)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,p.createElement)(d.Path,{d:"M4 6v11.5h16V6H4zm1.5 1.5h6V11h-6V7.5zm0 8.5v-3.5h6V16h-6zm13 0H13v-3.5h5.5V16zM13 11V7.5h5.5V11H13z"}));const H=function(e){const{attributes:t,setAttributes:o}=e,n=(0,c.useBlockProps)({className:"travelopia-table__cell"});return(0,s.jsx)(c.RichText,Object.assign({tagName:"span"},n,{placeholder:(0,i.__)("Cell content","tp"),onChange:e=>o({content:e}),value:t.content}))},z="travelopia/table-cell",E={apiVersion:3,icon:u,title:(0,i.__)("Cell","tp"),description:(0,i.__)("Individual cell of the table.","tp"),parent:["travelopia/table-column"],category:"text",keywords:[(0,i.__)("cell","tp")],attributes:{content:{type:"string",source:"html"}},supports:{html:!0,className:!1},transforms:{to:[{type:"block",blocks:["core/heading"],transform:(e,t)=>(0,a.createBlock)("core/heading",Object.assign(Object.assign({},e),{level:"3"}),t)},{type:"block",blocks:["core/paragraph"],transform:(e,t)=>(0,a.createBlock)("core/paragraph",e,t)},{type:"block",blocks:["core/list"],transform:(e,t)=>(0,a.createBlock)("core/list",{},[(0,a.createBlock)("core/list-item",e,t)])}]},edit:H,save:({attributes:e})=>(0,s.jsx)(c.RichText.Content,{value:e.content})};function O({isSelected:e,tableId:t,tableRow:o,tableColumn:n,rowContainerId:r,columnId:l}){const{getBlock:p,canInsertBlockType:d,getBlockAttributes:u,canRemoveBlock:b,getAdjacentBlockClientId:w}=(0,m.select)("core/block-editor"),{removeBlock:k,removeBlocks:H,insertBlock:E,updateBlockAttributes:O,moveBlocksToPosition:T}=(0,m.dispatch)("core/block-editor"),[M,D]=(0,v.useState)(0),[N,R]=(0,v.useState)(0),L=(0,v.useMemo)((()=>{var e,t;return null===(t=null===(e=p(r))||void 0===e?void 0:e.attributes)||void 0===t?void 0:t.type}),[r,p]);(0,v.useEffect)((()=>{const e=p(t);e?e.innerBlocks.some((e=>{if(e.name!==G||!e.innerBlocks.length)return!1;let t=0;return e.innerBlocks.forEach(((e,r)=>{e.name===A&&e.innerBlocks.length&&(r+1===o&&D(e.innerBlocks.length),e.innerBlocks.forEach(((e,o)=>{e.name===P&&o+1===n&&t++})))})),R(t),!0})):D(0)}),[o,n,p,t]);const F=(e=0)=>{var n,l;const s=p(t);if(!s)return;if(!d(A,r))return;const i=[];for(let e=0;e<(null===(n=s.attributes)||void 0===n?void 0:n.columns);e++)i.push((0,a.createBlock)(P,{},[(0,a.createBlock)(z)]));const c=(0,a.createBlock)(A,{},i);E(c,o+e,r),O(t,{rows:(null===(l=s.attributes)||void 0===l?void 0:l.rows)+1})},U=(e=0)=>{var o;const l=p(t);if(!l)return;p(r)&&(l.innerBlocks.forEach((t=>{t.name===G&&t.innerBlocks.forEach((t=>{if(t.name!==A)return;if(!d(P,t.clientId))return;const o=(0,a.createBlock)(P,{},[(0,a.createBlock)(z)]);E(o,n+e,t.clientId)}))})),O(t,{columns:(null===(o=l.attributes)||void 0===o?void 0:o.columns)+1}))},Y=(e,t)=>{var o,n,r,l;const a=u(t.clientId),s=u(e.clientId);if(parseInt(null!==(o=null==a?void 0:a.rowSpan)&&void 0!==o?o:1)!==parseInt(null!==(n=null==s?void 0:s.rowSpan)&&void 0!==n?n:1))return;const i=parseInt(null!==(r=null==a?void 0:a.colSpan)&&void 0!==r?r:1),c=parseInt(null!==(l=null==s?void 0:s.colSpan)&&void 0!==l?l:1);O(t.clientId,{colSpan:i+c}),T(e.innerBlocks.map((e=>e.clientId)),e.clientId,t.clientId),k(e.clientId)},$=(e,t)=>{var o,n,r,l;const a=u(t.clientId),s=u(e.clientId);if(parseInt(null!==(o=null==a?void 0:a.colSpan)&&void 0!==o?o:1)!==parseInt(null!==(n=null==s?void 0:s.colSpan)&&void 0!==n?n:1))return;const i=parseInt(null!==(r=null==a?void 0:a.rowSpan)&&void 0!==r?r:1),c=parseInt(null!==(l=null==s?void 0:s.rowSpan)&&void 0!==l?l:1);O(t.clientId,{rowSpan:i+c}),T(e.innerBlocks.map((e=>e.clientId)),e.clientId,t.clientId),k(e.clientId)},W=[{icon:f,title:(0,i.__)("Insert row before","tp"),isDisabled:!e||"tfoot"===L||"thead"===L,onClick:()=>F(-1)},{icon:_,title:(0,i.__)("Insert row after","tp"),isDisabled:!e||"tfoot"===L||"thead"===L,onClick:F},{icon:g,title:(0,i.__)("Delete row","tp"),isDisabled:!e||"tfoot"===L||"thead"===L,onClick:()=>{var e;const n=p(t);if(!n)return;const l=p(r);if(!l)return;const a=l.innerBlocks[o-1];(null==a?void 0:a.clientId)&&b(a.clientId)&&(k(a.clientId),O(t,{rows:(null===(e=n.attributes)||void 0===e?void 0:e.rows)-1}))}},{icon:y,title:(0,i.__)("Insert column before","tp"),isDisabled:!e,onClick:()=>U(-1)},{icon:x,title:(0,i.__)("Insert column after","tp"),isDisabled:!e,onClick:U},{icon:B,title:(0,i.__)("Delete column","tp"),isDisabled:!e,onClick:()=>{var e;const o=p(t);if(!o)return;const r=[];o.innerBlocks.forEach((e=>{e.name===G&&e.innerBlocks.forEach((e=>{if(e.name!==A)return;const t=e.innerBlocks[n-1];(null==t?void 0:t.clientId)&&b(t.clientId)&&r.push(t.clientId)}))})),H(r),O(t,{columns:(null===(e=o.attributes)||void 0===e?void 0:e.columns)-1})}},{icon:I,title:(0,i.__)("Merge column left","tp"),isDisabled:n<2,onClick:()=>{if(!p(t))return;const e=p(l);if(!e)return;const o=w(l,-1);if(!o)return;const n=p(o);n&&Y(e,n)}},{icon:V,title:(0,i.__)("Merge column right","tp"),isDisabled:n===M,onClick:()=>{if(!p(t))return;const e=p(l);if(!e)return;const o=w(l,1);if(!o)return;const n=p(o);n&&Y(n,e)}},{icon:j,title:(0,i.__)("Merge column up","tp"),isDisabled:o<2||"tfoot"===L||"thead"===L,onClick:()=>{const e=p(t);if(!e)return;const l=p(r);if(!l)return;let a,s;e.innerBlocks.some((e=>{var t;if(e.name!==G)return!1;const r=u(e.clientId);return(null==r?void 0:r.type)===(null===(t=null==l?void 0:l.attributes)||void 0===t?void 0:t.type)&&e.innerBlocks.some(((e,t)=>{const r=t+1;return!(e.name!==A||r!==o&&r!==o-1||!e.innerBlocks.length)&&(e.innerBlocks.some(((e,t)=>{const l=t+1;return l===n&&r===o?s=e:l===n&&r===o-1&&(a=e),!(!a||!s)})),!(!s||!a)&&($(s,a),!0))}))}))}},{icon:S,title:(0,i.__)("Merge column down","tp"),isDisabled:o===N||"tfoot"===L||"thead"===L,onClick:()=>{const e=p(t);if(!e)return;const l=p(r);if(!l)return;let a,s;e.innerBlocks.some((e=>{var t;if(e.name!==G)return!1;const r=u(e.clientId);return(null==r?void 0:r.type)===(null===(t=null==l?void 0:l.attributes)||void 0===t?void 0:t.type)&&e.innerBlocks.some(((e,t)=>{const r=t+1;return!(e.name!==A||r!==o&&r!==o+1||!e.innerBlocks.length)&&(e.innerBlocks.some(((e,t)=>{const l=t+1;return l===n&&r===o?a=e:l===n&&r===o+1&&(s=e),!(!a||!s)})),!(!s||!a)&&($(s,a),!0))}))}))}}];return(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(c.BlockControls,{group:"other",children:(0,s.jsx)(h.ToolbarDropdownMenu,{icon:C,label:(0,i.__)("Edit table","tp"),controls:W})})})}const T=function({className:e,clientId:t,attributes:o,setAttributes:n,isSelected:r,context:l}){const a=(0,c.useBlockProps)({className:w()(e,"travelopia-table__column",{"travelopia-table__column--sticky":o.isSticky})}),p=l["travelopia/table-id"],d=l["travelopia/table-row-container-type"],u=l["travelopia/table-row-container-id"],b=(0,c.useInnerBlocksProps)(Object.assign(Object.assign({},a),{colSpan:o.colSpan,rowSpan:o.rowSpan}),{template:[[z]],templateLock:!1}),{row:k,column:f}=(0,m.useSelect)((e=>{const o=e(c.store).getBlockIndex(t),n=e(c.store).getBlockRootClientId(t);return{row:e(c.store).getBlockIndex(n)+1,column:o+1}}),[t]);(0,v.useEffect)((()=>{n({row:k,column:f})}),[k,f,n]),(0,v.useEffect)((()=>{n({blockId:t})}),[t,n]);let _="td";return"tbody"!==d&&(_="th"),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.InspectorControls,{children:(0,s.jsx)(h.PanelBody,{title:(0,i.__)("Column Options","tp"),children:(0,s.jsx)(h.ToggleControl,{label:(0,i.__)("Is Sticky","tp"),checked:o.isSticky,onChange:e=>n({isSticky:e}),help:(0,i.__)("Is this column sticky?","tp")})})}),(0,s.jsx)(O,{isSelected:r,tableRow:k,tableColumn:f,tableId:p,rowContainerId:u,columnId:t}),(0,s.jsx)(_,Object.assign({},b))]})},P="travelopia/table-column",M={apiVersion:3,icon:u,title:(0,i.__)("Column","tp"),description:(0,i.__)("Individual column of the table.","tp"),parent:["travelopia/table-row"],category:"text",keywords:[(0,i.__)("column","tp")],attributes:{row:{type:"number"},column:{type:"number"},colSpan:{type:"number"},rowSpan:{type:"number"},isSticky:{type:"boolean"},blockId:{type:"string"}},providesContext:{"travelopia/table-row":"row","travelopia/table-column":"column","travelopia/table-column-id":"blockId"},usesContext:["travelopia/table-row-container-type","travelopia/table-row-container-id"],supports:{html:!0,color:{text:!0,background:!0},align:["left","center","right"],__experimentalBorder:{color:!0,style:!0,width:!0,__experimentalDefaultControls:{color:!0,style:!0,width:!0}}},edit:T,save:()=>(0,s.jsx)(c.InnerBlocks.Content,{})};const D=function(e){const{className:t,clientId:o,setAttributes:n}=e,r=(0,c.useBlockProps)({className:w()(t,"travelopia-table__row")}),l=(0,c.useInnerBlocksProps)(Object.assign({},r),{allowedBlocks:[P],templateLock:!1});return(0,v.useEffect)((()=>{n({blockId:o})}),[o,n]),(0,s.jsx)("tr",Object.assign({},l))},A="travelopia/table-row",N={apiVersion:3,icon:u,title:(0,i.__)("Row","tp"),description:(0,i.__)("Individual row of the table.","tp"),parent:["travelopia/table-row-container"],category:"text",keywords:[(0,i.__)("row","tp")],attributes:{blockId:{type:"string"}},usesContext:["travelopia/table-row-container-type"],supports:{html:!0,color:{text:!0,background:!0},__experimentalBorder:{color:!0,style:!0,width:!0,__experimentalDefaultControls:{color:!0,style:!0,width:!0}}},edit:D,save:()=>(0,s.jsx)(c.InnerBlocks.Content,{})};const R=function(e){const{className:t,attributes:o,setAttributes:n,clientId:r}=e,l=(0,c.useBlockProps)({className:w()(t,"travelopia-table__row-container",{"travelopia-table__row-container--sticky":o.isSticky})}),a=(0,c.useInnerBlocksProps)(Object.assign({},l),{allowedBlocks:[A]}),p=o.type;return(0,v.useEffect)((()=>{n({blockId:r})}),[r,n]),(0,s.jsxs)(s.Fragment,{children:["thead"===o.type&&(0,s.jsx)(c.InspectorControls,{children:(0,s.jsx)(h.PanelBody,{title:(0,i.__)("Row Container Options","tp"),children:(0,s.jsx)(h.ToggleControl,{label:(0,i.__)("Is Sticky vertically","tp"),checked:o.isSticky,onChange:e=>n({isSticky:e}),help:(0,i.__)("Is this container sticky?","tp")})})}),(0,s.jsx)(p,Object.assign({},a))]})},G="travelopia/table-row-container",L={apiVersion:3,icon:u,title:(0,i.__)("Row Container","tp"),description:(0,i.__)("A container for a row (THEAD, TBODY, TFOOT).","tp"),parent:["travelopia/table"],category:"text",keywords:[(0,i.__)("thead","tp"),(0,i.__)("tbody","tp"),(0,i.__)("tfoot","tp")],attributes:{type:{type:"string",default:"tbody"},isSticky:{type:"boolean",default:!1},blockId:{type:"string"}},providesContext:{"travelopia/table-row-container-type":"type","travelopia/table-row-container-sticky":"isSticky","travelopia/table-row-container-id":"blockId"},supports:{html:!1},edit:R,save:()=>(0,s.jsx)(c.InnerBlocks.Content,{})},F=(e="tbody",t="")=>{const o=(0,m.select)("core/block-editor").getBlock(t);if(!o)return;const n=(0,a.createBlock)(G,{type:e});let r=o.attributes.rows;"tbody"!==e&&(r=1);for(let e=0;e{const o=(0,m.select)("core/block-editor").getBlock(t);o&&o.innerBlocks.length&&o.innerBlocks.forEach((t=>{var o;(null===(o=t.attributes)||void 0===o?void 0:o.type)===e&&(0,m.dispatch)("core/block-editor").removeBlock(t.clientId)}))};const Y=function(e){const{className:t,attributes:o,clientId:n,setAttributes:r}=e,l=(0,c.useBlockProps)({className:w()(t,"travelopia-table")}),a=(0,c.useInnerBlocksProps)({},{allowedBlocks:[G],renderAppender:void 0});return(0,v.useEffect)((()=>{r({blockId:n})}),[n,r]),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.InspectorControls,{children:(0,s.jsxs)(h.PanelBody,{title:(0,i.__)("Table Options","tp"),children:[(0,s.jsx)(h.ToggleControl,{label:(0,i.__)("Has THEAD","tp"),checked:o.hasThead,onChange:e=>{e?F("thead",n):U("thead",n),r({hasThead:e})},help:(0,i.__)("Does this table have a header?","tp")}),(0,s.jsx)(h.ToggleControl,{label:(0,i.__)("Has TFOOT","tp"),checked:o.hasTfoot,onChange:e=>{e?F("tfoot",n):U("tfoot",n),r({hasTfoot:e})},help:(0,i.__)("Does this table have a footer?","tp")})]})}),(0,s.jsxs)("figure",Object.assign({},l,{children:[(0===o.rows||0===o.columns)&&(0,s.jsx)(k,Object.assign({},e)),(0!==o.rows||0!==o.columns)&&(0,s.jsx)("table",Object.assign({},a))]}))]})},$="travelopia/table",W={apiVersion:3,icon:u,title:(0,i.__)("Table","tp"),description:(0,i.__)("Create structured content in rows and columns to display information.","tp"),category:"text",keywords:[(0,i.__)("table","tp")],attributes:{anchor:{type:"string"},rows:{type:"number",default:0},columns:{type:"number",default:0},blockId:{type:"string"},hasThead:{type:"boolean",default:!1},hasTfoot:{type:"boolean",default:!1}},providesContext:{"travelopia/table-id":"blockId","travelopia/table-total-rows":"rows","travelopia/table-total-columns":"columns","travelopia/table-has-thead":"hasThead","travelopia/table-has-tfoot":"hasTfoot"},supports:{anchor:!0},edit:Y,save:()=>(0,s.jsx)(c.InnerBlocks.Content,{})},q=window.wp.hooks;(0,q.addFilter)("blocks.registerBlockType","travelopia/table-row-column-context",(e=>{const t=["travelopia/table-row","travelopia/table-column","travelopia/table-id","travelopia/table-row-container-id","travelopia/table-column-id"];return e.usesContext&&Array.isArray(e.usesContext)&&t.forEach((t=>{var o,n;(null===(o=e.usesContext)||void 0===o?void 0:o.includes(t))||null===(n=e.usesContext)||void 0===n||n.push(t)})),e})),(0,q.addFilter)("editor.BlockEdit","travelopia/table-toolbar",(e=>t=>{const{context:o,isSelected:n}=t;if(!o)return(0,s.jsx)(e,Object.assign({},t));const r=o["travelopia/table-row"],l=o["travelopia/table-column"],a=o["travelopia/table-id"],i=o["travelopia/table-row-container-id"],c=o["travelopia/table-column-id"];return!r||!l||!a||l<1||r<1?(0,s.jsx)(e,Object.assign({},t)):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(O,{isSelected:n,tableRow:r,tableColumn:l,tableId:a,rowContainerId:i,columnId:c}),(0,s.jsx)(e,Object.assign({},t))]})}));[l,r,n,t,e].forEach((({name:e,settings:t})=>(0,a.registerBlockType)(e,t)))})()})(); \ No newline at end of file +(()=>{var e={251:(e,t,o)=>{"use strict";var n=o(196),r=Symbol.for("react.element"),l=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,o){var n,l={},c=null,u=null;for(n in void 0!==o&&(c=""+o),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)a.call(t,n)&&!i.hasOwnProperty(n)&&(l[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===l[n]&&(l[n]=t[n]);return{$$typeof:r,type:e,key:c,ref:u,props:l,_owner:s.current}}t.Fragment=l,t.jsx=c,t.jsxs=c},893:(e,t,o)=>{"use strict";e.exports=o(251)},196:e=>{"use strict";e.exports=window.React},967:(e,t)=>{var o;!function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e="",t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{"use strict";var e={};o.r(e),o.d(e,{init:()=>O,name:()=>H,settings:()=>z});const t=window.wp.blocks;var n=o(196);const r=window.wp.primitives,l=(0,n.createElement)(r.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,n.createElement)(r.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v3.5h-15V5c0-.3.2-.5.5-.5zm8 5.5h6.5v3.5H13V10zm-1.5 3.5h-7V10h7v3.5zm-7 5.5v-4h7v4.5H5c-.3 0-.5-.2-.5-.5zm14.5.5h-6V15h6.5v4c0 .3-.2.5-.5.5z"})),a=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"travelopia/table","title":"Table","description":"Create structured content in rows and columns to display information.","category":"text","textdomain":"tp","supports":{"anchor":true,"className":true,"customClassName":true,"html":false,"alignWide":false},"providesContext":{"travelopia/table-id":"blockId","travelopia/table-total-rows":"rows","travelopia/table-total-columns":"columns","travelopia/table-has-thead":"hasThead","travelopia/table-has-tfoot":"hasTfoot"},"attributes":{"anchor":{"type":"string","default":""},"rows":{"type":"number","default":0},"columns":{"type":"number","default":0},"blockId":{"type":"string","default":""},"hasThead":{"type":"boolean","default":false},"hasTfoot":{"type":"boolean","default":false}}}');var s=o(893);const i=window.wp.i18n,c=window.wp.blockEditor,u=window.wp.element,p=window.wp.components,d=window.wp.data;var v=o(967),h=o.n(v);function m(e){const{setAttributes:t,clientId:o}=e,[n,r]=(0,u.useState)(2),[a,d]=(0,u.useState)(2);return(0,s.jsx)(p.Placeholder,{label:(0,i.__)("Table","tp"),icon:(0,s.jsx)(c.BlockIcon,{icon:l,showColors:!0}),instructions:(0,i.__)("Insert a table for sharing data.","tp"),children:(0,s.jsxs)("form",{className:"travelopia-table__placeholder-form",onSubmit:e=>{e.preventDefault(),t({rows:n,columns:a}),S("tbody",o)},children:[(0,s.jsx)(p.TextControl,{type:"number",label:(0,i.__)("Column count","tp"),value:a,onChange:e=>d(parseInt(e)),min:"1",className:"travelopia-table__placeholder-input"}),(0,s.jsx)(p.TextControl,{type:"number",label:(0,i.__)("Row count","tp"),value:n,onChange:e=>r(parseInt(e)),min:"1",className:"travelopia-table__placeholder-input"}),(0,s.jsx)(p.Button,{variant:"primary",type:"submit",children:(0,i.__)("Create Table","tp")})]})})}const b=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"travelopia/table-row-container","title":"Row Container","description":"A container for a row (THEAD, TBODY, TFOOT).","parent":["travelopia/table"],"category":"text","textdomain":"tp","keywords":["thead","tbody","tfoot","table"],"supports":{"html":false},"providesContext":{"travelopia/table-row-container-type":"type","travelopia/table-row-container-sticky":"isSticky","travelopia/table-row-container-id":"blockId"},"attributes":{"type":{"type":"string","default":"tbody"},"isSticky":{"type":"boolean","default":false},"blockId":{"type":"string"}}}'),w=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"travelopia/table-row","title":"Row","description":"Individual row of the table.","parent":["travelopia/table-row-container"],"category":"text","textdomain":"tp","keywords":["row","table"],"supports":{"html":true,"color":{"text":true,"background":true},"__experimentalBorder":{"color":true,"style":true,"width":true,"__experimentalDefaultControls":{"color":true,"style":true,"width":true}}},"usesContext":["travelopia/table-row-container-type"],"attributes":{"blockId":{"type":"string"}}}'),f=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"travelopia/table-column","title":"Column","description":"Individual column of the table.","parent":["travelopia/table-row"],"category":"text","textdomain":"tp","keywords":["column","table"],"supports":{"html":true,"color":{"text":true,"background":true},"align":["left","center","right"],"__experimentalBorder":{"color":true,"style":true,"width":true,"__experimentalDefaultControls":{"color":true,"style":true,"width":true}}},"providesContext":{"travelopia/table-row":"row","travelopia/table-column":"column","travelopia/table-column-id":"blockId"},"usesContext":["travelopia/table-row-container-type","travelopia/table-row-container-id"],"attributes":{"row":{"type":"number"},"column":{"type":"number"},"colSpan":{"type":"number"},"rowSpan":{"type":"number"},"isSticky":{"type":"boolean"},"blockId":{"type":"string"}}}'),k=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"travelopia/table-cell","title":"Cell","description":"Individual cell of the table.","parent":["travelopia/table-column"],"category":"text","textdomain":"tp","keywords":["cell","table"],"supports":{"anchor":false,"className":false,"customClassName":false,"html":true,"alignWide":false},"attributes":{"content":{"type":"string","source":"html"}}}');const{name:g}=k,y=Object.assign(Object.assign({},k),{icon:l,edit:function(e){const{attributes:t,setAttributes:o}=e,n=(0,c.useBlockProps)({className:"travelopia-table__cell"});return(0,s.jsx)(c.RichText,Object.assign({tagName:"span"},n,{placeholder:(0,i.__)("Cell content","tp"),onChange:e=>o({content:e}),value:t.content}))},save:function({attributes:e}){return(0,s.jsx)(c.RichText.Content,{value:e.content})}});const{name:x}=f,_=Object.assign(Object.assign({},f),{icon:l,edit:function({className:e,clientId:t,attributes:o,setAttributes:n,context:r}){const l=(0,c.useBlockProps)({className:h()(e,"travelopia-table__column",{"travelopia-table__column--sticky":o.isSticky})}),a=r["travelopia/table-row-container-type"],v=(0,c.useInnerBlocksProps)(Object.assign(Object.assign({},l),{colSpan:o.colSpan,rowSpan:o.rowSpan}),{template:[[g]],templateLock:!1}),{row:m,column:b}=(0,d.useSelect)((e=>{const o=e(c.store).getBlockIndex(t),n=e(c.store).getBlockRootClientId(t);return{row:e(c.store).getBlockIndex(n)+1,column:o+1}}),[t]);(0,u.useEffect)((()=>{n({row:m,column:b})}),[m,b,n]),(0,u.useEffect)((()=>{n({blockId:t})}),[t,n]);let w="td";return"tbody"!==a&&(w="th"),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.InspectorControls,{children:(0,s.jsx)(p.PanelBody,{title:(0,i.__)("Column Options","tp"),children:(0,s.jsx)(p.ToggleControl,{label:(0,i.__)("Is Sticky","tp"),checked:o.isSticky,onChange:e=>n({isSticky:e}),help:(0,i.__)("Is this column sticky?","tp")})})}),(0,s.jsx)(w,Object.assign({},v))]})},save:function(){return(0,s.jsx)(c.InnerBlocks.Content,{})}});const{name:B}=w,I=Object.assign(Object.assign({},w),{icon:l,edit:function(e){const{className:t,clientId:o,setAttributes:n}=e,r=(0,c.useBlockProps)({className:h()(t,"travelopia-table__row")}),l=(0,c.useInnerBlocksProps)(Object.assign({},r),{allowedBlocks:[x],templateLock:!1});return(0,u.useEffect)((()=>{n({blockId:o})}),[o,n]),(0,s.jsx)("tr",Object.assign({},l))},save:function(){return(0,s.jsx)(c.InnerBlocks.Content,{})}});const{name:j}=b,V=Object.assign(Object.assign({},b),{icon:l,edit:function(e){const{className:t,attributes:o,setAttributes:n,clientId:r}=e,l=(0,c.useBlockProps)({className:h()(t,"travelopia-table__row-container",{"travelopia-table__row-container--sticky":o.isSticky})}),a=(0,c.useInnerBlocksProps)(Object.assign({},l),{allowedBlocks:[B]}),d=o.type;return(0,u.useEffect)((()=>{n({blockId:r})}),[r,n]),(0,s.jsxs)(s.Fragment,{children:["thead"===o.type&&(0,s.jsx)(c.InspectorControls,{children:(0,s.jsx)(p.PanelBody,{title:(0,i.__)("Row Container Options","tp"),children:(0,s.jsx)(p.ToggleControl,{label:(0,i.__)("Is Sticky vertically","tp"),checked:o.isSticky,onChange:e=>n({isSticky:e}),help:(0,i.__)("Is this container sticky?","tp")})})}),(0,s.jsx)(d,Object.assign({},a))]})},save:function(){return(0,s.jsx)(c.InnerBlocks.Content,{})}}),S=(e="tbody",o="")=>{const n=(0,d.select)("core/block-editor").getBlock(o);if(!n)return;const r=(0,t.createBlock)(j,{type:e});let l=n.attributes.rows;"tbody"!==e&&(l=1);for(let e=0;e{const o=(0,d.select)("core/block-editor").getBlock(t);o&&o.innerBlocks.length&&o.innerBlocks.forEach((t=>{var o;(null===(o=t.attributes)||void 0===o?void 0:o.type)===e&&(0,d.dispatch)("core/block-editor").removeBlock(t.clientId)}))};const{name:H}=a,z=Object.assign(Object.assign({},a),{icon:l,edit:function(e){const{className:t,attributes:o,clientId:n,setAttributes:r}=e,l=(0,c.useBlockProps)({className:h()(t,"travelopia-table")}),a=(0,c.useInnerBlocksProps)({},{allowedBlocks:[j],renderAppender:void 0});return(0,u.useEffect)((()=>{r({blockId:n})}),[n,r]),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.InspectorControls,{children:(0,s.jsxs)(p.PanelBody,{title:(0,i.__)("Table Options","tp"),children:[(0,s.jsx)(p.ToggleControl,{label:(0,i.__)("Has THEAD","tp"),checked:o.hasThead,onChange:e=>{e?S("thead",n):C("thead",n),r({hasThead:e})},help:(0,i.__)("Does this table have a header?","tp")}),(0,s.jsx)(p.ToggleControl,{label:(0,i.__)("Has TFOOT","tp"),checked:o.hasTfoot,onChange:e=>{e?S("tfoot",n):C("tfoot",n),r({hasTfoot:e})},help:(0,i.__)("Does this table have a footer?","tp")})]})}),(0,s.jsxs)("figure",Object.assign({},l,{children:[(0===o.rows||0===o.columns)&&(0,s.jsx)(m,Object.assign({},e)),(0!==o.rows||0!==o.columns)&&(0,s.jsx)("table",Object.assign({},a))]}))]})},save:function(){return(0,s.jsx)(c.InnerBlocks.Content,{})}}),O=()=>{(0,t.registerBlockType)(H,z),(0,t.registerBlockType)(B,I),(0,t.registerBlockType)(j,V),(0,t.registerBlockType)(x,_),(0,t.registerBlockType)(g,y)},E=window.wp.hooks,T=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84zM6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84z"})),P=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M13.824 10.176h-2.88v-2.88H9.536v2.88h-2.88v1.344h2.88v2.88h1.408v-2.88h2.88zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm6.4 0H7.68v3.84h5.12V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.056H1.28v9.024H19.2V6.336z"})),M=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M17.728 11.456L14.592 8.32l3.2-3.2-1.536-1.536-3.2 3.2L9.92 3.648 8.384 5.12l3.2 3.2-3.264 3.264 1.536 1.536 3.264-3.264 3.136 3.136 1.472-1.536zM0 17.92V0h20.48v17.92H0zm19.2-6.4h-.448l-1.28-1.28H19.2V6.4h-1.792l1.28-1.28h.512V1.28H1.28v3.84h6.208l1.28 1.28H1.28v3.84h7.424l-1.28 1.28H1.28v3.84H19.2v-3.84z"})),N=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M6.4 3.776v3.648H2.752v1.792H6.4v3.648h1.728V9.216h3.712V7.424H8.128V3.776zM0 17.92V0h20.48v17.92H0zM12.8 1.28H1.28v14.08H12.8V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.12h-5.12v3.84h5.12V6.4zm0 5.12h-5.12v3.84h5.12v-3.84z"})),D=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M14.08 12.864V9.216h3.648V7.424H14.08V3.776h-1.728v3.648H8.64v1.792h3.712v3.648zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm0 5.12H1.28v3.84H6.4V6.4zm0 5.12H1.28v3.84H6.4v-3.84zM19.2 1.28H7.68v14.08H19.2V1.28z"})),A=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},(0,n.createElement)(r.Path,{d:"M6.4 9.98L7.68 8.7v-.256L6.4 7.164V9.98zm6.4-1.532l1.28-1.28V9.92L12.8 8.64v-.192zm7.68 9.472V0H0v17.92h20.48zm-1.28-2.56h-5.12v-1.024l-.256.256-1.024-1.024v1.792H7.68v-1.792l-1.024 1.024-.256-.256v1.024H1.28V1.28H6.4v2.368l.704-.704.576.576V1.216h5.12V3.52l.96-.96.32.32V1.216h5.12V15.36zm-5.76-2.112l-3.136-3.136-3.264 3.264-1.536-1.536 3.264-3.264L5.632 5.44l1.536-1.536 3.136 3.136 3.2-3.2 1.536 1.536-3.2 3.2 3.136 3.136-1.536 1.536z"})),R=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(r.Path,{d:"M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z"})),G=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(r.Path,{d:"m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z"})),L=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(r.Path,{d:"M12 3.9 6.5 9.5l1 1 3.8-3.7V20h1.5V6.8l3.7 3.7 1-1z"})),F=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(r.Path,{d:"m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z"})),$=(0,n.createElement)(r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(r.Path,{d:"M4 6v11.5h16V6H4zm1.5 1.5h6V11h-6V7.5zm0 8.5v-3.5h6V16h-6zm13 0H13v-3.5h5.5V16zM13 11V7.5h5.5V11H13z"}));function J({isSelected:e,tableId:o,tableRow:n,tableColumn:r,rowContainerId:l,columnId:a}){const{getBlock:v,canInsertBlockType:h,getBlockAttributes:m,getAdjacentBlockClientId:b,canRemoveBlock:w}=(0,d.select)("core/block-editor"),{removeBlock:f,removeBlocks:k,insertBlock:y,updateBlockAttributes:_,moveBlocksToPosition:I}=(0,d.dispatch)("core/block-editor"),[V,S]=(0,u.useState)(0),[C,H]=(0,u.useState)(0),z=(0,u.useMemo)((()=>{var e,t;return null===(t=null===(e=v(l))||void 0===e?void 0:e.attributes)||void 0===t?void 0:t.type}),[l,v]);(0,u.useEffect)((()=>{const e=v(o);e?e.innerBlocks.some((e=>{if(e.name!==j||!e.innerBlocks.length)return!1;let t=0;return e.innerBlocks.forEach(((e,o)=>{e.name===B&&e.innerBlocks.length&&(o+1===n&&S(e.innerBlocks.length),e.innerBlocks.forEach(((e,o)=>{e.name===x&&o+1===r&&t++})))})),H(t),!0})):S(0)}),[n,r,v,o]);const O=(e=0)=>{var r,a;const s=v(o);if(!s)return;if(!h(B,l))return;const i=[];for(let e=0;e<(null===(r=s.attributes)||void 0===r?void 0:r.columns);e++)i.push((0,t.createBlock)(x,{},[(0,t.createBlock)(g)]));const c=(0,t.createBlock)(B,{},i);y(c,n+e,l),_(o,{rows:(null===(a=s.attributes)||void 0===a?void 0:a.rows)+1})},E=(e=0)=>{var n;const a=v(o);if(!a)return;v(l)&&(a.innerBlocks.forEach((o=>{o.name===j&&o.innerBlocks.forEach((o=>{if(o.name!==B)return;if(!h(x,o.clientId))return;const n=(0,t.createBlock)(x,{},[(0,t.createBlock)(g)]);y(n,r+e,o.clientId)}))})),_(o,{columns:(null===(n=a.attributes)||void 0===n?void 0:n.columns)+1}))},J=(e,t)=>{var o,n,r,l;const a=m(t.clientId),s=m(e.clientId);if(parseInt(null!==(o=null==a?void 0:a.rowSpan)&&void 0!==o?o:1)!==parseInt(null!==(n=null==s?void 0:s.rowSpan)&&void 0!==n?n:1))return;const i=parseInt(null!==(r=null==a?void 0:a.colSpan)&&void 0!==r?r:1),c=parseInt(null!==(l=null==s?void 0:s.colSpan)&&void 0!==l?l:1);_(t.clientId,{colSpan:i+c}),I(e.innerBlocks.map((e=>e.clientId)),e.clientId,t.clientId),f(e.clientId)},W=(e,t)=>{var o,n,r,l;const a=m(t.clientId),s=m(e.clientId);if(parseInt(null!==(o=null==a?void 0:a.colSpan)&&void 0!==o?o:1)!==parseInt(null!==(n=null==s?void 0:s.colSpan)&&void 0!==n?n:1))return;const i=parseInt(null!==(r=null==a?void 0:a.rowSpan)&&void 0!==r?r:1),c=parseInt(null!==(l=null==s?void 0:s.rowSpan)&&void 0!==l?l:1);_(t.clientId,{rowSpan:i+c}),I(e.innerBlocks.map((e=>e.clientId)),e.clientId,t.clientId),f(e.clientId)},U=[{icon:T,title:(0,i.__)("Insert row before","tp"),isDisabled:!e||"tfoot"===z||"thead"===z,onClick:()=>O(-1)},{icon:P,title:(0,i.__)("Insert row after","tp"),isDisabled:!e||"tfoot"===z||"thead"===z,onClick:O},{icon:M,title:(0,i.__)("Delete row","tp"),isDisabled:!e||"tfoot"===z||"thead"===z,onClick:()=>{var e;const t=v(o);if(!t)return;const r=v(l);if(!r)return;const a=r.innerBlocks[n-1];(null==a?void 0:a.clientId)&&w(a.clientId)&&(f(a.clientId),_(o,{rows:(null===(e=t.attributes)||void 0===e?void 0:e.rows)-1}))}},{icon:N,title:(0,i.__)("Insert column before","tp"),isDisabled:!e,onClick:()=>E(-1)},{icon:D,title:(0,i.__)("Insert column after","tp"),isDisabled:!e,onClick:E},{icon:A,title:(0,i.__)("Delete column","tp"),isDisabled:!e,onClick:()=>{var e;const t=v(o);if(!t)return;const n=[];t.innerBlocks.forEach((e=>{e.name===j&&e.innerBlocks.forEach((e=>{if(e.name!==B)return;const t=e.innerBlocks[r-1];(null==t?void 0:t.clientId)&&w(t.clientId)&&n.push(t.clientId)}))})),k(n),_(o,{columns:(null===(e=t.attributes)||void 0===e?void 0:e.columns)-1})}},{icon:R,title:(0,i.__)("Merge column left","tp"),isDisabled:r<2,onClick:()=>{if(!v(o))return;const e=v(a);if(!e)return;const t=b(a,-1);if(!t)return;const n=v(t);n&&J(e,n)}},{icon:G,title:(0,i.__)("Merge column right","tp"),isDisabled:r===V,onClick:()=>{if(!v(o))return;const e=v(a);if(!e)return;const t=b(a,1);if(!t)return;const n=v(t);n&&J(n,e)}},{icon:L,title:(0,i.__)("Merge column up","tp"),isDisabled:n<2||"tfoot"===z||"thead"===z,onClick:()=>{const e=v(o);if(!e)return;const t=v(l);if(!t)return;let a,s;e.innerBlocks.some((e=>{var o;if(e.name!==j)return!1;const l=m(e.clientId);return(null==l?void 0:l.type)===(null===(o=null==t?void 0:t.attributes)||void 0===o?void 0:o.type)&&e.innerBlocks.some(((e,t)=>{const o=t+1;return!(e.name!==B||o!==n&&o!==n-1||!e.innerBlocks.length)&&(e.innerBlocks.some(((e,t)=>{const l=t+1;return l===r&&o===n?s=e:l===r&&o===n-1&&(a=e),!(!a||!s)})),!(!s||!a)&&(W(s,a),!0))}))}))}},{icon:F,title:(0,i.__)("Merge column down","tp"),isDisabled:n===C||"tfoot"===z||"thead"===z,onClick:()=>{const e=v(o);if(!e)return;const t=v(l);if(!t)return;let a,s;e.innerBlocks.some((e=>{var o;if(e.name!==j)return!1;const l=m(e.clientId);return(null==l?void 0:l.type)===(null===(o=null==t?void 0:t.attributes)||void 0===o?void 0:o.type)&&e.innerBlocks.some(((e,t)=>{const o=t+1;return!(e.name!==B||o!==n&&o!==n+1||!e.innerBlocks.length)&&(e.innerBlocks.some(((e,t)=>{const l=t+1;return l===r&&o===n?a=e:l===r&&o===n+1&&(s=e),!(!a||!s)})),!(!s||!a)&&(W(s,a),!0))}))}))}}];return(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(c.BlockControls,{group:"other",children:(0,s.jsx)(p.ToolbarDropdownMenu,{icon:$,label:(0,i.__)("Edit table","tp"),controls:U})})})}(0,E.addFilter)("blocks.registerBlockType","travelopia/table-row-column-context",(e=>{const t=["travelopia/table-row","travelopia/table-column","travelopia/table-id","travelopia/table-row-container-id","travelopia/table-column-id"];return e.usesContext&&Array.isArray(e.usesContext)&&t.forEach((t=>{var o,n;(null===(o=e.usesContext)||void 0===o?void 0:o.includes(t))||null===(n=e.usesContext)||void 0===n||n.push(t)})),e})),(0,E.addFilter)("editor.BlockEdit","travelopia/table-toolbar",(e=>t=>{const{context:o,isSelected:n}=t;if(!o)return(0,s.jsx)(e,Object.assign({},t));const r=o["travelopia/table-row"],l=o["travelopia/table-column"],a=o["travelopia/table-id"],i=o["travelopia/table-row-container-id"],c=o["travelopia/table-column-id"];return!r||!l||!a||l<1||r<1?(0,s.jsx)(e,Object.assign({},t)):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(J,{isSelected:n,tableRow:r,tableColumn:l,tableId:a,rowContainerId:i,columnId:c}),(0,s.jsx)(e,Object.assign({},t))]})}));[e].forEach((({init:e})=>e()))})()})(); \ No newline at end of file diff --git a/dist/editor/blocks.js.map b/dist/editor/blocks.js.map index 1f7bb2c..5edd902 100644 --- a/dist/editor/blocks.js.map +++ b/dist/editor/blocks.js.map @@ -1 +1 @@ -{"version":3,"file":"./dist/editor/blocks.js","mappings":"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","sources":["webpack://travelopia-wordpress-blocks/./node_modules/react/cjs/react-jsx-runtime.production.min.js","webpack://travelopia-wordpress-blocks/./node_modules/react/jsx-runtime.js","webpack://travelopia-wordpress-blocks/external window \"React\"","webpack://travelopia-wordpress-blocks/./node_modules/classnames/index.js","webpack://travelopia-wordpress-blocks/webpack/bootstrap","webpack://travelopia-wordpress-blocks/webpack/runtime/compat get default export","webpack://travelopia-wordpress-blocks/webpack/runtime/define property getters","webpack://travelopia-wordpress-blocks/webpack/runtime/hasOwnProperty shorthand","webpack://travelopia-wordpress-blocks/webpack/runtime/make namespace object","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"blocks\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"i18n\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"blockEditor\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"primitives\"]","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/block-table.js","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"element\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"components\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"data\"]","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/placeholder.tsx","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-before.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-after.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-delete.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-before.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-after.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-delete.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-left.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-right.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-up.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-down.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table.js","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-cell/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-cell/index.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-column/toolbar.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-column/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-column/index.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-row/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-row/index.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-row-container/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table-row-container/index.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/index.tsx","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"hooks\"]","webpack://travelopia-wordpress-blocks/./src/editor/blocks/block-toolbar.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/index.ts"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var f=require(\"react\"),k=Symbol.for(\"react.element\"),l=Symbol.for(\"react.fragment\"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};\nfunction q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=\"\"+g);void 0!==a.key&&(e=\"\"+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.min.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","module.exports = window[\"React\"];","/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (arg) {\n\t\t\t\tclasses = appendClass(classes, parseValue(arg));\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction parseValue (arg) {\n\t\tif (typeof arg === 'string' || typeof arg === 'number') {\n\t\t\treturn arg;\n\t\t}\n\n\t\tif (typeof arg !== 'object') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (Array.isArray(arg)) {\n\t\t\treturn classNames.apply(null, arg);\n\t\t}\n\n\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\treturn arg.toString();\n\t\t}\n\n\t\tvar classes = '';\n\n\t\tfor (var key in arg) {\n\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\tclasses = appendClass(classes, key);\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction appendClass (value, newClass) {\n\t\tif (!newClass) {\n\t\t\treturn value;\n\t\t}\n\t\n\t\tif (value) {\n\t\t\treturn value + ' ' + newClass;\n\t\t}\n\t\n\t\treturn value + newClass;\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"blocks\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"i18n\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"blockEditor\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"primitives\"];","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { Path, SVG } from '@wordpress/primitives';\nconst blockTable = createElement(SVG, {\n viewBox: \"0 0 24 24\",\n xmlns: \"http://www.w3.org/2000/svg\"\n}, createElement(Path, {\n d: \"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v3.5h-15V5c0-.3.2-.5.5-.5zm8 5.5h6.5v3.5H13V10zm-1.5 3.5h-7V10h7v3.5zm-7 5.5v-4h7v4.5H5c-.3 0-.5-.2-.5-.5zm14.5.5h-6V15h6.5v4c0 .3-.2.5-.5.5z\"\n}));\nexport default blockTable;\n//# sourceMappingURL=block-table.js.map","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"element\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"components\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"data\"];","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockIcon } from '@wordpress/block-editor';\nimport { blockTable as icon } from '@wordpress/icons';\nimport {\n\tButton,\n\tTextControl,\n\tPlaceholder,\n} from '@wordpress/components';\nimport { useState } from '@wordpress/element';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * Internal dependencies.\n */\nimport { createAndInsertRowContainer } from './edit';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport function TablePlaceholder( props: BlockEditProps ): JSX.Element {\n\tconst { setAttributes, clientId } = props;\n\tconst [ rows, setRows ] = useState( 2 );\n\tconst [ columns, setColumns ] = useState( 2 );\n\n\treturn (\n\t\t }\n\t\t\tinstructions={ __( 'Insert a table for sharing data.', 'tp' ) }\n\t\t>\n\t\t\t {\n\t\t\t\t\t// Prevent form submission.\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t// Set attributes.\n\t\t\t\t\tsetAttributes( { rows, columns } );\n\n\t\t\t\t\t// Create and insert row container.\n\t\t\t\t\tcreateAndInsertRowContainer( 'tbody', clientId );\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t setColumns( parseInt( totalColumns ) ) }\n\t\t\t\t\tmin=\"1\"\n\t\t\t\t\tclassName=\"travelopia-table__placeholder-input\"\n\t\t\t\t/>\n\t\t\t\t setRows( parseInt( totalRows ) ) }\n\t\t\t\t\tmin=\"1\"\n\t\t\t\t\tclassName=\"travelopia-table__placeholder-input\"\n\t\t\t\t/>\n\t\t\t\t\n\t\t\t\t\t{ __( 'Create Table', 'tp' ) }\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowBefore = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84zM6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84z\"\n}));\nexport default tableRowBefore;\n//# sourceMappingURL=table-row-before.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowAfter = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M13.824 10.176h-2.88v-2.88H9.536v2.88h-2.88v1.344h2.88v2.88h1.408v-2.88h2.88zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm6.4 0H7.68v3.84h5.12V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.056H1.28v9.024H19.2V6.336z\"\n}));\nexport default tableRowAfter;\n//# sourceMappingURL=table-row-after.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowDelete = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M17.728 11.456L14.592 8.32l3.2-3.2-1.536-1.536-3.2 3.2L9.92 3.648 8.384 5.12l3.2 3.2-3.264 3.264 1.536 1.536 3.264-3.264 3.136 3.136 1.472-1.536zM0 17.92V0h20.48v17.92H0zm19.2-6.4h-.448l-1.28-1.28H19.2V6.4h-1.792l1.28-1.28h.512V1.28H1.28v3.84h6.208l1.28 1.28H1.28v3.84h7.424l-1.28 1.28H1.28v3.84H19.2v-3.84z\"\n}));\nexport default tableRowDelete;\n//# sourceMappingURL=table-row-delete.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnBefore = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.4 3.776v3.648H2.752v1.792H6.4v3.648h1.728V9.216h3.712V7.424H8.128V3.776zM0 17.92V0h20.48v17.92H0zM12.8 1.28H1.28v14.08H12.8V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.12h-5.12v3.84h5.12V6.4zm0 5.12h-5.12v3.84h5.12v-3.84z\"\n}));\nexport default tableColumnBefore;\n//# sourceMappingURL=table-column-before.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnAfter = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M14.08 12.864V9.216h3.648V7.424H14.08V3.776h-1.728v3.648H8.64v1.792h3.712v3.648zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm0 5.12H1.28v3.84H6.4V6.4zm0 5.12H1.28v3.84H6.4v-3.84zM19.2 1.28H7.68v14.08H19.2V1.28z\"\n}));\nexport default tableColumnAfter;\n//# sourceMappingURL=table-column-after.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnDelete = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.4 9.98L7.68 8.7v-.256L6.4 7.164V9.98zm6.4-1.532l1.28-1.28V9.92L12.8 8.64v-.192zm7.68 9.472V0H0v17.92h20.48zm-1.28-2.56h-5.12v-1.024l-.256.256-1.024-1.024v1.792H7.68v-1.792l-1.024 1.024-.256-.256v1.024H1.28V1.28H6.4v2.368l.704-.704.576.576V1.216h5.12V3.52l.96-.96.32.32V1.216h5.12V15.36zm-5.76-2.112l-3.136-3.136-3.264 3.264-1.536-1.536 3.264-3.264L5.632 5.44l1.536-1.536 3.136 3.136 3.2-3.2 1.536 1.536-3.2 3.2 3.136 3.136-1.536 1.536z\"\n}));\nexport default tableColumnDelete;\n//# sourceMappingURL=table-column-delete.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowLeft = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z\"\n}));\nexport default arrowLeft;\n//# sourceMappingURL=arrow-left.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowRight = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z\"\n}));\nexport default arrowRight;\n//# sourceMappingURL=arrow-right.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowUp = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M12 3.9 6.5 9.5l1 1 3.8-3.7V20h1.5V6.8l3.7 3.7 1-1z\"\n}));\nexport default arrowUp;\n//# sourceMappingURL=arrow-up.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowDown = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z\"\n}));\nexport default arrowDown;\n//# sourceMappingURL=arrow-down.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst table = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M4 6v11.5h16V6H4zm1.5 1.5h6V11h-6V7.5zm0 8.5v-3.5h6V16h-6zm13 0H13v-3.5h5.5V16zM13 11V7.5h5.5V11H13z\"\n}));\nexport default table;\n//# sourceMappingURL=table.js.map","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockEditProps } from '@wordpress/blocks';\nimport {\n\tRichText,\n\tuseBlockProps,\n} from '@wordpress/block-editor';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nfunction TableCellEdit( props: BlockEditProps ): JSX.Element {\n\tconst { attributes, setAttributes } = props;\n\tconst blockProps = useBlockProps( {\n\t\tclassName: 'travelopia-table__cell',\n\t} );\n\n\treturn (\n\t\t setAttributes( { content } ) }\n\t\t\tvalue={ attributes.content }\n\t\t/>\n\t);\n}\n\nexport default TableCellEdit;\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { RichText } from '@wordpress/block-editor';\nimport {\n\tBlockConfiguration,\n\tBlockInstance,\n\tBlockSaveProps,\n\tcreateBlock,\n\tTransformBlock,\n} from '@wordpress/blocks';\nimport {\n\tblockTable as icon,\n} from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport edit from './edit';\n\n/**\n * Block data.\n */\nexport const name: string = 'travelopia/table-cell';\n\nexport const settings: BlockConfiguration = {\n\tapiVersion: 3,\n\ticon,\n\ttitle: __( 'Cell', 'tp' ),\n\tdescription: __( 'Individual cell of the table.', 'tp' ),\n\tparent: [ 'travelopia/table-column' ],\n\tcategory: 'text',\n\tkeywords: [ __( 'cell', 'tp' ) ],\n\tattributes: {\n\t\tcontent: {\n\t\t\ttype: 'string',\n\t\t\tsource: 'html',\n\t\t},\n\t},\n\tsupports: {\n\t\thtml: true,\n\t\tclassName: false,\n\t},\n\ttransforms: {\n\t\tto: [\n\t\t\t{\n\t\t\t\ttype: 'block',\n\t\t\t\tblocks: [ 'core/heading' ],\n\t\t\t\ttransform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => {\n\t\t\t\t\treturn createBlock(\n\t\t\t\t\t\t'core/heading', { ...attributes, level: '3' }, innerBlocks\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t} as unknown as TransformBlock,\n\t\t\t{\n\t\t\t\ttype: 'block',\n\t\t\t\tblocks: [ 'core/paragraph' ],\n\t\t\t\ttransform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => {\n\t\t\t\t\treturn createBlock( 'core/paragraph', attributes, innerBlocks );\n\t\t\t\t},\n\t\t\t} as unknown as TransformBlock,\n\t\t\t{\n\t\t\t\ttype: 'block',\n\t\t\t\tblocks: [ 'core/list' ],\n\t\t\t\ttransform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => {\n\t\t\t\t\treturn createBlock(\n\t\t\t\t\t\t'core/list',\n\t\t\t\t\t\t{},\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tcreateBlock( 'core/list-item', attributes, innerBlocks ),\n\t\t\t\t\t\t]\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t} as unknown as TransformBlock,\n\t\t],\n\t},\n\tedit,\n\tsave( { attributes }: BlockSaveProps ) {\n\t\treturn (\n\t\t\t\n\t\t);\n\t},\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockInstance, createBlock } from '@wordpress/blocks';\nimport { BlockControls } from '@wordpress/block-editor';\nimport { ToolbarDropdownMenu } from '@wordpress/components';\nimport { select, dispatch } from '@wordpress/data';\nimport { DropdownOption } from '@wordpress/components/build-types/dropdown-menu/types';\nimport {\n\tarrowLeft,\n\tarrowRight,\n\tarrowUp,\n\tarrowDown,\n\ttableColumnAfter,\n\ttableColumnBefore,\n\ttableColumnDelete,\n\ttableRowAfter,\n\ttableRowBefore,\n\ttableRowDelete,\n\ttable,\n} from '@wordpress/icons';\nimport {\n\tuseState,\n\tuseEffect,\n\tuseMemo,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies.\n */\nimport { name as columnBlockName } from './index';\nimport { name as rowBlockName } from '../table-row';\nimport { name as cellBlockName } from '../table-cell';\nimport { name as rowContainerBlockName } from '../table-row-container';\n\n/**\n * Column block toolbar.\n *\n * @param {Object} props Block properties.\n * @param {boolean} props.isSelected Is block selected.\n * @param {string} props.tableId Table block ID.\n * @param {number} props.tableRow Table row index.\n * @param {number} props.tableColumn Table column index.\n * @param {string} props.rowContainerId Table row container ID.\n * @param {string} props.columnId Column block ID.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Toolbar( {\n\tisSelected,\n\ttableId,\n\ttableRow,\n\ttableColumn,\n\trowContainerId,\n\tcolumnId,\n}: {\n\tisSelected: boolean;\n\ttableId: string;\n\ttableRow: number;\n\ttableColumn: number;\n\trowContainerId: string;\n\tcolumnId: string;\n} ): JSX.Element {\n\tconst {\n\t\tgetBlock,\n\t\tcanInsertBlockType,\n\t\tgetBlockAttributes,\n\t\t// @ts-ignore\n\t\tcanRemoveBlock,\n\t\tgetAdjacentBlockClientId,\n\t} = select( 'core/block-editor' );\n\n\tconst {\n\t\tremoveBlock,\n\t\tremoveBlocks,\n\t\tinsertBlock,\n\t\tupdateBlockAttributes,\n\t\t// @ts-ignore\n\t\tmoveBlocksToPosition,\n\t} = dispatch( 'core/block-editor' );\n\n\tconst [ maximumColumnsInCurrentRow, setMaximumColumnsInCurrentRow ] = useState( 0 );\n\tconst [ maximumRowsInCurrentColumn, setMaximumRowsInCurrentColumn ] = useState( 0 );\n\n\tconst rowContainerBlockType = useMemo( () => getBlock( rowContainerId )?.attributes?.type, [ rowContainerId, getBlock ] );\n\n\t/**\n\t * Set maximum columns in current row.\n\t */\n\tuseEffect( (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if we have a block.\n\t\tif ( ! tableBlock ) {\n\t\t\tsetMaximumColumnsInCurrentRow( 0 );\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse table.\n\t\ttableBlock.innerBlocks.some( ( rowContainerBlock ): boolean => {\n\n\t\t\tif ( rowContainerBlock.name !== rowContainerBlockName || ! rowContainerBlock.innerBlocks.length ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tlet maxRows = 0;\n\t\t\trowContainerBlock.innerBlocks.forEach( ( rowBlock, rowIndex ) => {\n\t\t\t\tif ( rowBlock.name !== rowBlockName || ! rowBlock.innerBlocks.length ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Set maximum columns in current row.\n\t\t\t\tif ( rowIndex + 1 === tableRow ) {\n\t\t\t\t\tsetMaximumColumnsInCurrentRow( rowBlock.innerBlocks.length );\n\t\t\t\t}\n\n\t\t\t\trowBlock.innerBlocks.forEach( ( columnBlock, columnIndex ) => {\n\t\t\t\t\tif ( columnBlock.name !== columnBlockName || columnIndex + 1 !== tableColumn ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tmaxRows++;\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\tsetMaximumRowsInCurrentColumn( maxRows );\n\t\t\treturn true;\n\t\t});\n\t}, [ tableRow, tableColumn, getBlock, tableId ] );\n\n\t/**\n\t * Insert row.\n\t *\n\t * @param {0|-1} insertionIndex Insertion index. -1 for before and 0 for after.\n\t */\n\tconst onInsertRow = ( insertionIndex: 0 | -1 = 0 ) => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if the row block can be inserted.\n\t\tif ( ! canInsertBlockType( rowBlockName, rowContainerId ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create column blocks.\n\t\tconst columnBlocks = [];\n\n\t\t// Loop through the table columns count attribute.\n\t\tfor ( let i = 0; i < tableBlock.attributes?.columns || 0; i++ ) {\n\t\t\tcolumnBlocks.push(\n\t\t\t\tcreateBlock( columnBlockName, {}, [ createBlock( cellBlockName ) ] ),\n\t\t\t);\n\t\t}\n\n\t\t// Create a new row block.\n\t\tconst newRowBlock = createBlock( rowBlockName, {}, columnBlocks );\n\n\t\t// Insert the new row block.\n\t\tinsertBlock( newRowBlock, tableRow + insertionIndex, rowContainerId );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\trows: tableBlock.attributes?.rows + 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Delete row.\n\t */\n\tconst onDeleteRow = () => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row block.\n\t\tconst currentRowBlock = rowContainerBlock.innerBlocks[ tableRow - 1 ];\n\n\t\t// Check if the current row block is removable.\n\t\tif (\n\t\t\t! currentRowBlock?.clientId ||\n\t\t\t! canRemoveBlock( currentRowBlock.clientId )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the current row block.\n\t\tremoveBlock( currentRowBlock.clientId );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\trows: tableBlock.attributes?.rows - 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Insert column.\n\t *\n\t * @param {0|-1} insertionIndex Insertion index. -1 for before and 0 for after.\n\t */\n\tconst onInsertColumn = ( insertionIndex: 0 | -1 = 0 ) => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Loop through the table row blocks and insert a new column block.\n\t\ttableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => {\n\t\t\t// Check the name of the row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\tcurrentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => {\n\t\t\t\t// Check the name of the row block.\n\t\t\t\tif ( rowBlock.name !== rowBlockName ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check if the column block can be inserted.\n\t\t\t\tif ( ! canInsertBlockType( columnBlockName, rowBlock.clientId ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Create a new column block.\n\t\t\t\tconst newColumnBlock = createBlock( columnBlockName, {}, [\n\t\t\t\t\tcreateBlock( cellBlockName ),\n\t\t\t\t] );\n\n\t\t\t\t// Insert the new column block.\n\t\t\t\tinsertBlock( newColumnBlock, tableColumn + insertionIndex, rowBlock.clientId );\n\t\t\t} );\n\t\t} );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\tcolumns: tableBlock.attributes?.columns + 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Delete column.\n\t */\n\tconst onDeleteColumn = () => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Columns to be removed.\n\t\tconst columnsToRemove: string[] = [];\n\n\t\t// Loop through the table row blocks.\n\t\ttableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => {\n\t\t\t// Check the name of the row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\tcurrentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => {\n\t\t\t\t// Check the name of the row block.\n\t\t\t\tif ( rowBlock.name !== rowBlockName ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Get the current column block.\n\t\t\t\tconst currentColumnBlock = rowBlock.innerBlocks[ tableColumn - 1 ];\n\n\t\t\t\t// Check if the current column block is removable.\n\t\t\t\tif (\n\t\t\t\t\tcurrentColumnBlock?.clientId &&\n\t\t\t\t\tcanRemoveBlock( currentColumnBlock.clientId )\n\t\t\t\t) {\n\t\t\t\t\tcolumnsToRemove.push( currentColumnBlock.clientId );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\n\t\t// Remove the columns.\n\t\tremoveBlocks( columnsToRemove );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\tcolumns: tableBlock.attributes?.columns - 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Merge column left.\n\t */\n\tconst onMergeColumnLeft = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentBlock = getBlock( columnId );\n\t\tif ( ! currentBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst previousBlockClientId = getAdjacentBlockClientId( columnId, -1 );\n\t\tif ( ! previousBlockClientId ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst previousBlock = getBlock( previousBlockClientId );\n\t\tif ( ! previousBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Merge columns.\n\t\tmergeColumnsHorizontally( currentBlock, previousBlock );\n\t};\n\n\t/**\n\t * Merge column right.\n\t */\n\tconst onMergeColumnRight = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentBlock = getBlock( columnId );\n\t\tif ( ! currentBlock ) {\n\t\t\treturn;\n\t\t}\n\t\tconst nextBlockClientId = getAdjacentBlockClientId( columnId, 1 );\n\t\tif ( ! nextBlockClientId ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextBlock = getBlock( nextBlockClientId );\n\t\tif ( ! nextBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Merge columns.\n\t\tmergeColumnsHorizontally( nextBlock, currentBlock );\n\t};\n\n\t/**\n\t * Merge column up.\n\t */\n\tconst onMergeColumnUp = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare variables.\n\t\tlet columnToMergeInto: BlockInstance | undefined;\n\t\tlet columnToMergeFrom: BlockInstance | undefined;\n\n\t\t// Traverse rows.\n\t\ttableBlock.innerBlocks.some( ( currentRowContainerBlock ) => {\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Avoid merging thead/tfoot row with tbody row.\n\t\t\tconst currentRowContainerBlockAttributes = getBlockAttributes( currentRowContainerBlock.clientId );\n\t\t\tif ( currentRowContainerBlockAttributes?.type !== rowContainerBlock?.attributes?.type ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn currentRowContainerBlock.innerBlocks.some( ( rowBlock, rowIndex ): boolean => {\n\t\t\t\t// Get current row.\n\t\t\t\tconst rowNumber: number = rowIndex + 1;\n\t\t\t\tif ( rowBlock.name !== rowBlockName || ( rowNumber !== tableRow && rowNumber !== tableRow - 1 ) || ! rowBlock.innerBlocks.length ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Traverse columns in current row.\n\t\t\t\trowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => {\n\t\t\t\t\t// Get column to merge from and into.\n\t\t\t\t\tconst columnNumber: number = columnIndex + 1;\n\t\t\t\t\tif ( columnNumber === tableColumn && rowNumber === tableRow ) {\n\t\t\t\t\t\tcolumnToMergeFrom = columnBlock;\n\t\t\t\t\t} else if ( columnNumber === tableColumn && rowNumber === tableRow - 1 ) {\n\t\t\t\t\t\tcolumnToMergeInto = columnBlock;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Short circuit if we found them.\n\t\t\t\t\tif ( columnToMergeInto && columnToMergeFrom ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We haven't found them, loop some more.\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\n\t\t\t\t// Check if we have a \"to\" and \"from\" column.\n\t\t\t\tif ( ! columnToMergeFrom || ! columnToMergeInto ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Merge columns.\n\t\t\t\tmergeColumnsVertically( columnToMergeFrom, columnToMergeInto );\n\n\t\t\t\t// Short-circuit loop.\n\t\t\t\treturn true;\n\t\t\t} );\n\t\t} );\n\t};\n\n\t/**\n\t * Merge column down.\n\t */\n\tconst onMergeColumnDown = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare variables.\n\t\tlet columnToMergeInto: BlockInstance | undefined;\n\t\tlet columnToMergeFrom: BlockInstance | undefined;\n\n\t\t// Traverse rows.\n\t\ttableBlock.innerBlocks.some( ( currentRowContainerBlock ) => {\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Avoid merging thead/tfoot row with tbody row.\n\t\t\tconst currentRowContainerBlockAttributes = getBlockAttributes( currentRowContainerBlock.clientId );\n\t\t\tif ( currentRowContainerBlockAttributes?.type !== rowContainerBlock?.attributes?.type ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn currentRowContainerBlock.innerBlocks.some( ( rowBlock, rowIndex ): boolean => {\n\t\t\t\t// Get current row.\n\t\t\t\tconst rowNumber: number = rowIndex + 1;\n\t\t\t\tif ( rowBlock.name !== rowBlockName || ( rowNumber !== tableRow && rowNumber !== tableRow + 1 ) || ! rowBlock.innerBlocks.length ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Traverse columns in current row.\n\t\t\t\trowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => {\n\t\t\t\t\t// Get column to merge from and into.\n\t\t\t\t\tconst columnNumber: number = columnIndex + 1;\n\t\t\t\t\tif ( columnNumber === tableColumn && rowNumber === tableRow ) {\n\t\t\t\t\t\tcolumnToMergeInto = columnBlock;\n\t\t\t\t\t} else if ( columnNumber === tableColumn && rowNumber === tableRow + 1 ) {\n\t\t\t\t\t\tcolumnToMergeFrom = columnBlock;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Short circuit if we found them.\n\t\t\t\t\tif ( columnToMergeInto && columnToMergeFrom ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We haven't found them, loop some more.\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\n\t\t\t\t// Check if we have a \"to\" and \"from\" column.\n\t\t\t\tif ( ! columnToMergeFrom || ! columnToMergeInto ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Merge columns.\n\t\t\t\tmergeColumnsVertically( columnToMergeFrom, columnToMergeInto );\n\n\t\t\t\t// Short-circuit loop.\n\t\t\t\treturn true;\n\t\t\t} );\n\t\t} );\n\t};\n\n\t/**\n\t * Merge columns horizontally.\n\t *\n\t * @param {Object} fromColumn From column block instance.\n\t * @param {Object} toColumn To column block instance.\n\t */\n\tconst mergeColumnsHorizontally = ( fromColumn: BlockInstance, toColumn: BlockInstance ): void => {\n\t\t// Get colspans.\n\t\tconst mergeIntoAttributes = getBlockAttributes( toColumn.clientId );\n\t\tconst mergeFromAttributes = getBlockAttributes( fromColumn.clientId );\n\n\t\t// Get rowspans.\n\t\tconst mergeIntoRowspan: number = parseInt( mergeIntoAttributes?.rowSpan ?? 1 );\n\t\tconst mergeFromRowspan: number = parseInt( mergeFromAttributes?.rowSpan ?? 1 );\n\n\t\t// Invalid merge.\n\t\tif ( mergeIntoRowspan !== mergeFromRowspan ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergeIntoColspan: number = parseInt( mergeIntoAttributes?.colSpan ?? 1 );\n\t\tconst mergeFromColspan: number = parseInt( mergeFromAttributes?.colSpan ?? 1 );\n\n\t\t// Update colspan.\n\t\tupdateBlockAttributes( toColumn.clientId, { colSpan: mergeIntoColspan + mergeFromColspan } );\n\n\t\t// If it is the current column, move children to previous column and delete current column.\n\t\tmoveBlocksToPosition(\n\t\t\tfromColumn.innerBlocks.map( ( block ) => block.clientId ),\n\t\t\tfromColumn.clientId,\n\t\t\ttoColumn.clientId\n\t\t);\n\n\t\t// Remove block that is being merged from.\n\t\tremoveBlock( fromColumn.clientId );\n\t};\n\n\t/**\n\t * Merge columns vertically.\n\t *\n\t * @param {Object} fromColumn From column block instance.\n\t * @param {Object} toColumn To column block instance.\n\t */\n\tconst mergeColumnsVertically = ( fromColumn: BlockInstance, toColumn: BlockInstance ): void => {\n\t\t// Get rowspans.\n\t\tconst mergeIntoAttributes = getBlockAttributes( toColumn.clientId );\n\t\tconst mergeFromAttributes = getBlockAttributes( fromColumn.clientId );\n\n\t\t// Get colspans.\n\t\tconst mergeIntoColspan: number = parseInt( mergeIntoAttributes?.colSpan ?? 1 );\n\t\tconst mergeFromColspan: number = parseInt( mergeFromAttributes?.colSpan ?? 1 );\n\n\t\t// Invalid merge.\n\t\tif ( mergeIntoColspan !== mergeFromColspan ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergeIntoRowspan: number = parseInt( mergeIntoAttributes?.rowSpan ?? 1 );\n\t\tconst mergeFromRowspan: number = parseInt( mergeFromAttributes?.rowSpan ?? 1 );\n\n\t\t// Update rowspan.\n\t\tupdateBlockAttributes( toColumn.clientId, { rowSpan: mergeIntoRowspan + mergeFromRowspan } );\n\n\t\t// If it is the current column, move children to previous column and delete current column.\n\t\tmoveBlocksToPosition(\n\t\t\tfromColumn.innerBlocks.map( ( block ) => block.clientId ),\n\t\t\tfromColumn.clientId,\n\t\t\ttoColumn.clientId\n\t\t);\n\n\t\t// Remove block that is being merged from.\n\t\tremoveBlock( fromColumn.clientId );\n\t};\n\n\t/**\n\t * Table controls.\n\t */\n\tconst tableControls = [\n\t\t{\n\t\t\ticon: tableRowBefore,\n\t\t\ttitle: __( 'Insert row before', 'tp' ),\n\t\t\tisDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ),\n\t\t\tonClick: () => onInsertRow( -1 ),\n\t\t},\n\t\t{\n\t\t\ticon: tableRowAfter,\n\t\t\ttitle: __( 'Insert row after', 'tp' ),\n\t\t\tisDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ),\n\t\t\tonClick: onInsertRow,\n\t\t},\n\t\t{\n\t\t\ticon: tableRowDelete,\n\t\t\ttitle: __( 'Delete row', 'tp' ),\n\t\t\tisDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ),\n\t\t\tonClick: onDeleteRow,\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnBefore,\n\t\t\ttitle: __( 'Insert column before', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: () => onInsertColumn( -1 ),\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnAfter,\n\t\t\ttitle: __( 'Insert column after', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: onInsertColumn,\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnDelete,\n\t\t\ttitle: __( 'Delete column', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: onDeleteColumn,\n\t\t},\n\t\t{\n\t\t\ticon: arrowLeft,\n\t\t\ttitle: __( 'Merge column left', 'tp' ),\n\t\t\tisDisabled: tableColumn < 2,\n\t\t\tonClick: onMergeColumnLeft,\n\t\t},\n\t\t{\n\t\t\ticon: arrowRight,\n\t\t\ttitle: __( 'Merge column right', 'tp' ),\n\t\t\tisDisabled: tableColumn === maximumColumnsInCurrentRow,\n\t\t\tonClick: onMergeColumnRight,\n\t\t},\n\t\t{\n\t\t\ticon: arrowUp,\n\t\t\ttitle: __( 'Merge column up', 'tp' ),\n\t\t\tisDisabled: ( tableRow < 2 || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ),\n\t\t\tonClick: onMergeColumnUp,\n\t\t},\n\t\t{\n\t\t\ticon: arrowDown,\n\t\t\ttitle: __( 'Merge column down', 'tp' ),\n\t\t\tisDisabled: ( tableRow === maximumRowsInCurrentColumn || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ),\n\t\t\tonClick: onMergeColumnDown,\n\t\t},\n\t] as DropdownOption[];\n\n\t/**\n\t * Return block controls.\n\t */\n\treturn (\n\t\t<>\n\t\t\t{ /* @ts-ignore - Group is not defined in the prop-type. */ }\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n\tstore as blockEditorStore,\n\tInspectorControls,\n} from '@wordpress/block-editor';\nimport { useEffect } from '@wordpress/element';\nimport { useSelect } from '@wordpress/data';\nimport { BlockEditProps } from '@wordpress/blocks';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport Toolbar from './toolbar';\nimport { name as cellBlockName } from '../table-cell';\nimport { PanelBody, ToggleControl } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n * @param {string} props.className Class name.\n * @param {string} props.clientId Client ID.\n * @param {Object} props.attributes Attributes.\n * @param {Function} props.setAttributes Set attributes.\n * @param {boolean} props.isSelected Is block selected.\n * @param {Object} props.context Block context.\n *\n * @return {JSX.Element} JSX Component.\n */\nfunction TableColumnEdit( {\n\tclassName,\n\tclientId,\n\tattributes,\n\tsetAttributes,\n\tisSelected,\n\tcontext,\n}: BlockEditProps ): JSX.Element {\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__column', {\n\t\t\t'travelopia-table__column--sticky': attributes.isSticky,\n\t\t} ),\n\t} );\n\n\tconst tableId: string = context[ 'travelopia/table-id' ] as string;\n\tconst rowContainerType: string = context[ 'travelopia/table-row-container-type' ] as string;\n\tconst rowContainerId: string = context[ 'travelopia/table-row-container-id' ] as string;\n\n\tconst innerBlocksProps = useInnerBlocksProps(\n\t\t{\n\t\t\t...blockProps,\n\t\t\tcolSpan: attributes.colSpan,\n\t\t\trowSpan: attributes.rowSpan,\n\t\t},\n\t\t{\n\t\t\ttemplate: [ [ cellBlockName ] ],\n\t\t\ttemplateLock: false,\n\t\t},\n\t);\n\n\t// Get the row and column index.\n\tconst { row, column } = useSelect(\n\t\t( select: any ) => {\n\t\t\t// Calculate the row and column index.\n\t\t\tconst columnIndex = select( blockEditorStore ).getBlockIndex( clientId );\n\t\t\tconst rowClientId =\n\t\t\t\tselect( blockEditorStore ).getBlockRootClientId( clientId );\n\t\t\tconst rowIndex = select( blockEditorStore ).getBlockIndex( rowClientId );\n\n\t\t\treturn {\n\t\t\t\trow: rowIndex + 1, // Start index at 1.\n\t\t\t\tcolumn: columnIndex + 1,\n\t\t\t};\n\t\t},\n\t\t[ clientId ],\n\t);\n\n\t// Update the row and column index.\n\tuseEffect( () => {\n\t\tsetAttributes( { row, column } );\n\t}, [ row, column, setAttributes ] );\n\n\tuseEffect( () => {\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t// Determine tag.\n\tlet Tag: string = 'td';\n\tif ( 'tbody' !== rowContainerType ) {\n\t\tTag = 'th';\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t setAttributes( { isSticky } ) }\n\t\t\t\t\t\thelp={ __( 'Is this column sticky?', 'tp' ) }\n\t\t\t\t\t/>\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n\nexport default TableColumnEdit;\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport {\n\tInnerBlocks,\n} from '@wordpress/block-editor';\nimport {\n\tblockTable as icon,\n} from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport edit from './edit';\n\n/**\n * Block data.\n */\nexport const name: string = 'travelopia/table-column';\n\nexport const settings: BlockConfiguration = {\n\tapiVersion: 3,\n\ticon,\n\ttitle: __( 'Column', 'tp' ),\n\tdescription: __( 'Individual column of the table.', 'tp' ),\n\tparent: [ 'travelopia/table-row' ],\n\tcategory: 'text',\n\tkeywords: [ __( 'column', 'tp' ) ],\n\tattributes: {\n\t\trow: {\n\t\t\ttype: 'number',\n\t\t},\n\t\tcolumn: {\n\t\t\ttype: 'number',\n\t\t},\n\t\tcolSpan: {\n\t\t\ttype: 'number',\n\t\t},\n\t\trowSpan: {\n\t\t\ttype: 'number',\n\t\t},\n\t\tisSticky: {\n\t\t\ttype: 'boolean',\n\t\t},\n\t\tblockId: {\n\t\t\ttype: 'string',\n\t\t},\n\t},\n\tprovidesContext: {\n\t\t'travelopia/table-row': 'row' as never,\n\t\t'travelopia/table-column': 'column' as never,\n\t\t'travelopia/table-column-id': 'blockId' as never,\n\t},\n\tusesContext: [\n\t\t'travelopia/table-row-container-type',\n\t\t'travelopia/table-row-container-id',\n\t],\n\tsupports: {\n\t\thtml: true,\n\t\tcolor: {\n\t\t\ttext: true,\n\t\t\tbackground: true,\n\t\t},\n\t\talign: [ 'left', 'center', 'right' ],\n\t\t// @ts-ignore\n\t\t__experimentalBorder: {\n\t\t\tcolor: true,\n\t\t\tstyle: true,\n\t\t\twidth: true,\n\t\t\t__experimentalDefaultControls: {\n\t\t\t\tcolor: true,\n\t\t\t\tstyle: true,\n\t\t\t\twidth: true,\n\t\t\t},\n\t\t},\n\t},\n\tedit,\n\tsave() {\n\t\treturn ;\n\t},\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { name as columnBlockName } from '../table-column';\nimport { useEffect } from '@wordpress/element';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nfunction TableRowEdit( props: BlockEditProps ): JSX.Element {\n\t// Block props.\n\tconst { className, clientId, setAttributes } = props;\n\n\t// Inner block props.\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__row' ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps( { ...blockProps }, {\n\t\tallowedBlocks: [ columnBlockName ],\n\t\ttemplateLock: false,\n\t} );\n\n\tuseEffect( () => {\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\treturn (\n\t\t\n\t);\n}\n\nexport default TableRowEdit;\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport {\n\tInnerBlocks,\n} from '@wordpress/block-editor';\nimport {\n\tblockTable as icon,\n} from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport edit from './edit';\n\n/**\n * Block data.\n */\nexport const name: string = 'travelopia/table-row';\n\nexport const settings: BlockConfiguration = {\n\tapiVersion: 3,\n\ticon,\n\ttitle: __( 'Row', 'tp' ),\n\tdescription: __( 'Individual row of the table.', 'tp' ),\n\tparent: [ 'travelopia/table-row-container' ],\n\tcategory: 'text',\n\tkeywords: [ __( 'row', 'tp' ) ],\n\tattributes: {\n\t\tblockId: {\n\t\t\ttype: 'string',\n\t\t},\n\t},\n\tusesContext: [\n\t\t'travelopia/table-row-container-type',\n\t],\n\tsupports: {\n\t\thtml: true,\n\t\tcolor: {\n\t\t\ttext: true,\n\t\t\tbackground: true,\n\t\t},\n\t\t// @ts-ignore\n\t\t__experimentalBorder: {\n\t\t\tcolor: true,\n\t\t\tstyle: true,\n\t\t\twidth: true,\n\t\t\t__experimentalDefaultControls: {\n\t\t\t\tcolor: true,\n\t\t\t\tstyle: true,\n\t\t\t\twidth: true,\n\t\t\t},\n\t\t},\n\t},\n\tedit,\n\tsave() {\n\t\treturn ;\n\t},\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport {\n\tPanelBody,\n\tToggleControl,\n} from '@wordpress/components';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { name as rowBlockName } from '../table-row';\nimport { useEffect } from '@wordpress/element';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nfunction TableRowContainerEdit( props: BlockEditProps ): JSX.Element {\n\t// Block props.\n\tconst { className, attributes, setAttributes, clientId } = props;\n\n\t// Inner block props.\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__row-container', {\n\t\t\t'travelopia-table__row-container--sticky': attributes.isSticky,\n\t\t} ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps( { ...blockProps }, {\n\t\tallowedBlocks: [ rowBlockName ],\n\t} );\n\n\t// Determine tag.\n\tconst Tag: string = attributes.type;\n\n\tuseEffect( () => {\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t// Return component.\n\treturn (\n\t\t<>\n\t\t\t{ 'thead' === attributes.type &&\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t setAttributes( { isSticky } ) }\n\t\t\t\t\t\t\thelp={ __( 'Is this container sticky?', 'tp' ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\n\t);\n}\n\nexport default TableRowContainerEdit;\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport {\n\tInnerBlocks,\n} from '@wordpress/block-editor';\nimport {\n\tblockTable as icon,\n} from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport edit from './edit';\n\n/**\n * Block data.\n */\nexport const name: string = 'travelopia/table-row-container';\n\nexport const settings: BlockConfiguration = {\n\tapiVersion: 3,\n\ticon,\n\ttitle: __( 'Row Container', 'tp' ),\n\tdescription: __( 'A container for a row (THEAD, TBODY, TFOOT).', 'tp' ),\n\tparent: [ 'travelopia/table' ],\n\tcategory: 'text',\n\tkeywords: [\n\t\t__( 'thead', 'tp' ),\n\t\t__( 'tbody', 'tp' ),\n\t\t__( 'tfoot', 'tp' ),\n\t],\n\tattributes: {\n\t\ttype: {\n\t\t\ttype: 'string',\n\t\t\tdefault: 'tbody',\n\t\t},\n\t\tisSticky: {\n\t\t\ttype: 'boolean',\n\t\t\tdefault: false,\n\t\t},\n\t\tblockId: {\n\t\t\ttype: 'string',\n\t\t},\n\t},\n\tprovidesContext: {\n\t\t'travelopia/table-row-container-type': 'type' as never,\n\t\t'travelopia/table-row-container-sticky': 'isSticky' as never,\n\t\t'travelopia/table-row-container-id': 'blockId' as never,\n\t},\n\tsupports: {\n\t\thtml: false,\n\t},\n\tedit,\n\tsave() {\n\t\treturn ;\n\t},\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport {\n\tBlockEditProps,\n\tcreateBlock,\n} from '@wordpress/blocks';\nimport { useEffect } from '@wordpress/element';\nimport {\n\tPanelBody,\n\tToggleControl,\n} from '@wordpress/components';\nimport {\n\tselect,\n\tdispatch,\n} from '@wordpress/data';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { TablePlaceholder } from './placeholder';\nimport { name as rowContainerBlockName } from '../table-row-container';\nimport { name as rowBlockName } from '../table-row';\nimport { name as columnBlockName } from '../table-column';\nimport { name as cellBlockName } from '../table-cell';\n\n/**\n * Create and insert a row container.\n *\n * @param {string} type Row container type.\n * @param {string} tableClientId The table block's client ID.\n */\nexport const createAndInsertRowContainer = ( type: string = 'tbody', tableClientId: string = '' ): void => {\n\t// Get table block.\n\tconst tableBlock = select( 'core/block-editor' ).getBlock( tableClientId );\n\tif ( ! tableBlock ) {\n\t\treturn;\n\t}\n\n\t// Create row container.\n\tconst rowContainerBlock = createBlock( rowContainerBlockName, { type } );\n\n\t// Determine number of rows to create.\n\tlet totalRows = tableBlock.attributes.rows;\n\tif ( 'tbody' !== type ) {\n\t\ttotalRows = 1;\n\t}\n\n\t// Add rows and columns to it.\n\tfor ( let i: number = 0; i < totalRows; i++ ) {\n\t\tconst columnBlocks = [];\n\t\tfor ( let j: number = 0; j < tableBlock.attributes.columns; j++ ) {\n\t\t\tcolumnBlocks.push(\n\t\t\t\tcreateBlock( columnBlockName, {}, [\n\t\t\t\t\tcreateBlock( cellBlockName ),\n\t\t\t\t] )\n\t\t\t);\n\t\t}\n\n\t\trowContainerBlock.innerBlocks.push(\n\t\t\tcreateBlock( rowBlockName, {}, columnBlocks )\n\t\t);\n\t}\n\n\t// Add newly created row and column blocks to the table.\n\tif ( 'tbody' === type ) {\n\t\tdispatch( 'core/block-editor' ).replaceInnerBlocks( tableClientId, [ rowContainerBlock ] );\n\t} else {\n\t\tconst position = 'thead' === type ? 0 : tableBlock.innerBlocks.length;\n\t\tdispatch( 'core/block-editor' ).insertBlock( rowContainerBlock, position, tableClientId );\n\t}\n};\n\n/**\n * Delete row container child block.\n *\n * @param {string} type Row container type.\n * @param {string} tableClientId The table block's client ID.\n */\nexport const deleteRowContainer = ( type: string = 'thead', tableClientId: string = '' ): void => {\n\t// Get table block.\n\tconst tableBlock = select( 'core/block-editor' ).getBlock( tableClientId );\n\tif ( ! tableBlock || ! tableBlock.innerBlocks.length ) {\n\t\treturn;\n\t}\n\n\t// Find the child block and delete it.\n\ttableBlock.innerBlocks.forEach( ( innerBlock ) => {\n\t\tif ( innerBlock.attributes?.type === type ) {\n\t\t\tdispatch( 'core/block-editor' ).removeBlock( innerBlock.clientId );\n\t\t}\n\t} );\n};\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nfunction TableEdit( props: BlockEditProps ): JSX.Element {\n\tconst { className, attributes, clientId, setAttributes } = props;\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table' ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps( {}, {\n\t\tallowedBlocks: [ rowContainerBlockName ],\n\t\trenderAppender: undefined,\n\t} );\n\n\t// Set blockId attribute.\n\tuseEffect( () => {\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t/**\n\t * Handle THEAD change.\n\t *\n\t * @param {boolean} hasThead Has THEAD.\n\t */\n\tconst handleTheadChange = ( hasThead: boolean ): void => {\n\t\tif ( hasThead ) {\n\t\t\tcreateAndInsertRowContainer( 'thead', clientId );\n\t\t} else {\n\t\t\tdeleteRowContainer( 'thead', clientId );\n\t\t}\n\t\tsetAttributes( { hasThead } );\n\t};\n\n\t/**\n\t * Handle TFOOT change.\n\t *\n\t * @param {boolean} hasTfoot Has TFOOT.\n\t */\n\tconst handleTfootChange = ( hasTfoot: boolean ): void => {\n\t\tif ( hasTfoot ) {\n\t\t\tcreateAndInsertRowContainer( 'tfoot', clientId );\n\t\t} else {\n\t\t\tdeleteRowContainer( 'tfoot', clientId );\n\t\t}\n\t\tsetAttributes( { hasTfoot } );\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t
\n\t\t\t\t{\n\t\t\t\t\t/* Placeholder for initial state. */\n\t\t\t\t\t( 0 === attributes.rows || 0 === attributes.columns ) &&\n\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t{\n\t\t\t\t\t( 0 !== attributes.rows || 0 !== attributes.columns ) &&\n\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\n\t\t\n\t);\n}\n\nexport default TableEdit;\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport {\n\tInnerBlocks,\n} from '@wordpress/block-editor';\nimport {\n\tblockTable as icon,\n} from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport edit from './edit';\n\n/**\n * Styles.\n */\nimport './editor.scss';\n\n/**\n * Frontend styles.\n */\nimport '../../../front-end/table/index.scss';\n\n/**\n * Block data.\n */\nexport const name: string = 'travelopia/table';\n\nexport const settings: BlockConfiguration = {\n\tapiVersion: 3,\n\ticon,\n\ttitle: __( 'Table', 'tp' ),\n\tdescription: __( 'Create structured content in rows and columns to display information.', 'tp' ),\n\tcategory: 'text',\n\tkeywords: [ __( 'table', 'tp' ) ],\n\tattributes: {\n\t\tanchor: {\n\t\t\ttype: 'string',\n\t\t},\n\t\trows: {\n\t\t\ttype: 'number',\n\t\t\tdefault: 0,\n\t\t},\n\t\tcolumns: {\n\t\t\ttype: 'number',\n\t\t\tdefault: 0,\n\t\t},\n\t\tblockId: {\n\t\t\ttype: 'string',\n\t\t},\n\t\thasThead: {\n\t\t\ttype: 'boolean',\n\t\t\tdefault: false,\n\t\t},\n\t\thasTfoot: {\n\t\t\ttype: 'boolean',\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tprovidesContext: {\n\t\t'travelopia/table-id': 'blockId' as never,\n\t\t'travelopia/table-total-rows': 'rows' as never,\n\t\t'travelopia/table-total-columns': 'columns' as never,\n\t\t'travelopia/table-has-thead': 'hasThead' as never,\n\t\t'travelopia/table-has-tfoot': 'hasTfoot' as never,\n\t},\n\tsupports: {\n\t\tanchor: true,\n\t},\n\tedit,\n\tsave() {\n\t\treturn ;\n\t},\n};\n","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"hooks\"];","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration, BlockEditProps } from '@wordpress/blocks';\nimport { addFilter } from '@wordpress/hooks';\n\n/**\n * Internal dependencies.\n */\nimport Toolbar from './table-column/toolbar';\n\n/**\n * Add context of table row and column to the block.\n */\naddFilter(\n\t'blocks.registerBlockType',\n\t'travelopia/table-row-column-context',\n\t( settings: BlockConfiguration ) => {\n\t\tconst requiredContexts = [\n\t\t\t'travelopia/table-row',\n\t\t\t'travelopia/table-column',\n\t\t\t'travelopia/table-id',\n\t\t\t'travelopia/table-row-container-id',\n\t\t\t'travelopia/table-column-id',\n\t\t];\n\n\t\tif ( settings.usesContext && Array.isArray( settings.usesContext ) ) {\n\t\t\trequiredContexts.forEach( ( context ) => {\n\t\t\t\tif ( ! settings.usesContext?.includes( context ) ) {\n\t\t\t\t\tsettings.usesContext?.push( context );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn settings;\n\t},\n);\n\n/**\n * Add toolbar to the table block.\n */\naddFilter( 'editor.BlockEdit', 'travelopia/table-toolbar', ( BlockEdit ) => {\n\treturn ( props: BlockEditProps ) => {\n\t\tconst { context, isSelected } = props;\n\n\t\tif ( ! context ) {\n\t\t\treturn ;\n\t\t}\n\n\t\tconst tableRow = context[ 'travelopia/table-row' ] as number;\n\t\tconst tableColumn = context[ 'travelopia/table-column' ] as number;\n\t\tconst tableId = context[ 'travelopia/table-id' ] as string;\n\t\tconst tableRowContainerId = context[ 'travelopia/table-row-container-id' ] as string;\n\t\tconst tableColumnId = context[ 'travelopia/table-column-id' ] as string;\n\n\t\tif (\n\t\t\t! tableRow ||\n\t\t\t! tableColumn ||\n\t\t\t! tableId ||\n\t\t\ttableColumn < 1 ||\n\t\t\ttableRow < 1\n\t\t) {\n\t\t\treturn ;\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t);\n\t};\n} );\n","/**\n * WordPress dependencies.\n */\nimport { registerBlockType } from '@wordpress/blocks';\n\n/**\n * Import blocks.\n */\nimport * as table from './table';\nimport * as tableRowContainer from './table-row-container';\nimport * as tableRow from './table-row';\nimport * as tableColumn from './table-column';\nimport * as tableCell from './table-cell';\n\n/**\n * Internal dependencies.\n */\nimport './block-toolbar';\n\n/**\n * Add blocks.\n */\nconst blocks = [\n\ttable,\n\ttableRowContainer,\n\ttableRow,\n\ttableColumn,\n\ttableCell,\n];\n\n/**\n * Register blocks.\n */\nblocks.forEach( ( { name, settings } ) => registerBlockType( name, settings ) );\n"],"names":["f","k","Symbol","for","l","m","Object","prototype","hasOwnProperty","n","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","p","key","ref","__self","__source","q","c","a","g","b","d","e","h","call","defaultProps","$$typeof","type","props","_owner","current","exports","Fragment","jsx","jsxs","module","window","hasOwn","classNames","classes","i","arguments","length","arg","appendClass","parseValue","Array","isArray","apply","toString","includes","value","newClass","default","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","getter","__esModule","definition","o","defineProperty","enumerable","get","obj","prop","r","toStringTag","createElement","SVG","viewBox","xmlns","Path","TablePlaceholder","setAttributes","clientId","rows","setRows","useState","columns","setColumns","Placeholder","label","__","icon","BlockIcon","showColors","instructions","className","onSubmit","preventDefault","createAndInsertRowContainer","TextControl","onChange","totalColumns","parseInt","min","totalRows","Button","variant","attributes","blockProps","useBlockProps","RichText","tagName","placeholder","content","settings","apiVersion","title","description","parent","category","keywords","source","supports","html","transforms","to","blocks","transform","innerBlocks","createBlock","level","edit","save","Content","Toolbar","isSelected","tableId","tableRow","tableColumn","rowContainerId","columnId","getBlock","canInsertBlockType","getBlockAttributes","canRemoveBlock","getAdjacentBlockClientId","select","removeBlock","removeBlocks","insertBlock","updateBlockAttributes","moveBlocksToPosition","dispatch","maximumColumnsInCurrentRow","setMaximumColumnsInCurrentRow","maximumRowsInCurrentColumn","setMaximumRowsInCurrentColumn","rowContainerBlockType","useMemo","useEffect","tableBlock","some","rowContainerBlock","name","maxRows","forEach","rowBlock","rowIndex","columnBlock","columnIndex","onInsertRow","insertionIndex","columnBlocks","push","newRowBlock","onInsertColumn","currentRowContainerBlock","newColumnBlock","mergeColumnsHorizontally","fromColumn","toColumn","mergeIntoAttributes","mergeFromAttributes","rowSpan","mergeIntoColspan","colSpan","mergeFromColspan","map","block","mergeColumnsVertically","mergeIntoRowspan","mergeFromRowspan","tableControls","isDisabled","onClick","currentRowBlock","columnsToRemove","currentColumnBlock","currentBlock","previousBlockClientId","previousBlock","nextBlockClientId","nextBlock","columnToMergeInto","columnToMergeFrom","currentRowContainerBlockAttributes","rowNumber","columnNumber","BlockControls","group","ToolbarDropdownMenu","controls","context","isSticky","rowContainerType","innerBlocksProps","useInnerBlocksProps","template","templateLock","row","column","useSelect","getBlockIndex","rowClientId","getBlockRootClientId","blockId","Tag","InspectorControls","PanelBody","ToggleControl","checked","help","providesContext","usesContext","color","text","background","align","__experimentalBorder","style","width","__experimentalDefaultControls","InnerBlocks","allowedBlocks","tableClientId","j","replaceInnerBlocks","position","deleteRowContainer","innerBlock","renderAppender","hasThead","hasTfoot","anchor","addFilter","requiredContexts","BlockEdit","tableRowContainerId","tableColumnId","registerBlockType"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./dist/editor/blocks.js","mappings":"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","sources":["webpack://travelopia-wordpress-blocks/./node_modules/react/cjs/react-jsx-runtime.production.min.js","webpack://travelopia-wordpress-blocks/./node_modules/react/jsx-runtime.js","webpack://travelopia-wordpress-blocks/external window \"React\"","webpack://travelopia-wordpress-blocks/./node_modules/classnames/index.js","webpack://travelopia-wordpress-blocks/webpack/bootstrap","webpack://travelopia-wordpress-blocks/webpack/runtime/compat get default export","webpack://travelopia-wordpress-blocks/webpack/runtime/define property getters","webpack://travelopia-wordpress-blocks/webpack/runtime/hasOwnProperty shorthand","webpack://travelopia-wordpress-blocks/webpack/runtime/make namespace object","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"blocks\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"primitives\"]","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/block-table.js","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"i18n\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"blockEditor\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"element\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"components\"]","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"data\"]","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/placeholder.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/cell/index.ts","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/cell/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/cell/save.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/column/index.ts","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/column/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/column/save.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row/index.ts","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row/save.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row-container/index.ts","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row-container/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/children/row-container/save.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/edit.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/index.ts","webpack://travelopia-wordpress-blocks/./src/editor/blocks/table/save.tsx","webpack://travelopia-wordpress-blocks/external window [\"wp\",\"hooks\"]","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-before.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-after.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-row-delete.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-before.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-after.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table-column-delete.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-left.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-right.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-up.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/arrow-down.js","webpack://travelopia-wordpress-blocks/./node_modules/@wordpress/icons/build-module/library/table.js","webpack://travelopia-wordpress-blocks/./src/editor/blocks/toolbar.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/block-toolbar.tsx","webpack://travelopia-wordpress-blocks/./src/editor/blocks/index.ts"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var f=require(\"react\"),k=Symbol.for(\"react.element\"),l=Symbol.for(\"react.fragment\"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};\nfunction q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=\"\"+g);void 0!==a.key&&(e=\"\"+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.min.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","module.exports = window[\"React\"];","/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (arg) {\n\t\t\t\tclasses = appendClass(classes, parseValue(arg));\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction parseValue (arg) {\n\t\tif (typeof arg === 'string' || typeof arg === 'number') {\n\t\t\treturn arg;\n\t\t}\n\n\t\tif (typeof arg !== 'object') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (Array.isArray(arg)) {\n\t\t\treturn classNames.apply(null, arg);\n\t\t}\n\n\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\treturn arg.toString();\n\t\t}\n\n\t\tvar classes = '';\n\n\t\tfor (var key in arg) {\n\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\tclasses = appendClass(classes, key);\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction appendClass (value, newClass) {\n\t\tif (!newClass) {\n\t\t\treturn value;\n\t\t}\n\t\n\t\tif (value) {\n\t\t\treturn value + ' ' + newClass;\n\t\t}\n\t\n\t\treturn value + newClass;\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"blocks\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"primitives\"];","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { Path, SVG } from '@wordpress/primitives';\nconst blockTable = createElement(SVG, {\n viewBox: \"0 0 24 24\",\n xmlns: \"http://www.w3.org/2000/svg\"\n}, createElement(Path, {\n d: \"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v3.5h-15V5c0-.3.2-.5.5-.5zm8 5.5h6.5v3.5H13V10zm-1.5 3.5h-7V10h7v3.5zm-7 5.5v-4h7v4.5H5c-.3 0-.5-.2-.5-.5zm14.5.5h-6V15h6.5v4c0 .3-.2.5-.5.5z\"\n}));\nexport default blockTable;\n//# sourceMappingURL=block-table.js.map","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"i18n\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"blockEditor\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"element\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"components\"];","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"data\"];","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockIcon } from '@wordpress/block-editor';\nimport { blockTable as icon } from '@wordpress/icons';\nimport {\n\tButton,\n\tTextControl,\n\tPlaceholder,\n} from '@wordpress/components';\nimport { useState } from '@wordpress/element';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * Internal dependencies.\n */\nimport { createAndInsertRowContainer } from './edit';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport function TablePlaceholder( props: BlockEditProps ): JSX.Element {\n\t// Destructure properties.\n\tconst { setAttributes, clientId } = props;\n\tconst [ rows, setRows ] = useState( 2 );\n\tconst [ columns, setColumns ] = useState( 2 );\n\n\t// Return placeholder.\n\treturn (\n\t\t }\n\t\t\tinstructions={ __( 'Insert a table for sharing data.', 'tp' ) }\n\t\t>\n\t\t\t {\n\t\t\t\t\t// Prevent form submission.\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t// Set attributes.\n\t\t\t\t\tsetAttributes( { rows, columns } );\n\n\t\t\t\t\t// Create and insert row container.\n\t\t\t\t\tcreateAndInsertRowContainer( 'tbody', clientId );\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t setColumns( parseInt( totalColumns ) ) }\n\t\t\t\t\tmin=\"1\"\n\t\t\t\t\tclassName=\"travelopia-table__placeholder-input\"\n\t\t\t\t/>\n\t\t\t\t setRows( parseInt( totalRows ) ) }\n\t\t\t\t\tmin=\"1\"\n\t\t\t\t\tclassName=\"travelopia-table__placeholder-input\"\n\t\t\t\t/>\n\t\t\t\t\n\t\t\t\t\t{ __( 'Create Table', 'tp' ) }\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport { blockTable as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport metadata from './block.json';\nimport edit from './edit';\nimport save from './save';\n\n/**\n * Block name.\n */\nexport const { name }: { name: string } = metadata;\n\n/**\n * Block configuration settings.\n */\nexport const settings: BlockConfiguration = {\n\t...metadata,\n\ticon,\n\tedit,\n\tsave,\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockEditProps } from '@wordpress/blocks';\nimport {\n\tRichText,\n\tuseBlockProps,\n} from '@wordpress/block-editor';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Edit( props: BlockEditProps ): JSX.Element {\n\t// Destructure properties.\n\tconst { attributes, setAttributes } = props;\n\tconst blockProps = useBlockProps( {\n\t\tclassName: 'travelopia-table__cell',\n\t} );\n\n\t// Return cell content.\n\treturn (\n\t\t setAttributes( { content } ) }\n\t\t\tvalue={ attributes.content }\n\t\t/>\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { RichText } from '@wordpress/block-editor';\nimport { BlockSaveProps } from '@wordpress/blocks';\n\n/**\n * Save component.\n *\n * @param {Object} props Component properties.\n * @param {Object} props.attributes Component attributes.\n */\nexport default function Save( {\n\tattributes,\n}: BlockSaveProps> ) {\n\t// Save content.\n\treturn ;\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport { blockTable as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport metadata from './block.json';\nimport edit from './edit';\nimport save from './save';\n\n/**\n * Block name.\n */\nexport const { name }: { name: string } = metadata;\n\n// @ts-ignore Ignore BlockConfiguration type error for providesContext.\nexport const settings: BlockConfiguration = {\n\t...metadata,\n\ticon,\n\tedit,\n\tsave,\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n\tstore as blockEditorStore,\n\tInspectorControls,\n} from '@wordpress/block-editor';\nimport { useEffect } from '@wordpress/element';\nimport { useSelect } from '@wordpress/data';\nimport { BlockEditProps } from '@wordpress/blocks';\nimport { PanelBody, ToggleControl } from '@wordpress/components';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { name as cellBlockName } from '../cell';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n * @param {string} props.className Class name.\n * @param {string} props.clientId Client ID.\n * @param {Object} props.attributes Attributes.\n * @param {Function} props.setAttributes Set attributes.\n * @param {Object} props.context Block context.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Edit( {\n\tclassName,\n\tclientId,\n\tattributes,\n\tsetAttributes,\n\tcontext,\n}: BlockEditProps ): JSX.Element {\n\t// Get block props.\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__column', {\n\t\t\t'travelopia-table__column--sticky': attributes.isSticky,\n\t\t} ),\n\t} );\n\n\t// Get context.\n\tconst rowContainerType: string = context[ 'travelopia/table-row-container-type' ] as string;\n\n\t// Get inner blocks props.\n\tconst innerBlocksProps = useInnerBlocksProps(\n\t\t{\n\t\t\t...blockProps,\n\t\t\tcolSpan: attributes.colSpan,\n\t\t\trowSpan: attributes.rowSpan,\n\t\t},\n\t\t{\n\t\t\ttemplate: [ [ cellBlockName ] ],\n\t\t\ttemplateLock: false,\n\t\t},\n\t);\n\n\t// Get the row and column index.\n\tconst { row, column } = useSelect(\n\t\t( select: any ) => {\n\t\t\t// Calculate the row and column index.\n\t\t\tconst columnIndex = select( blockEditorStore ).getBlockIndex( clientId );\n\t\t\tconst rowClientId =\n\t\t\t\tselect( blockEditorStore ).getBlockRootClientId( clientId );\n\t\t\tconst rowIndex = select( blockEditorStore ).getBlockIndex( rowClientId );\n\n\t\t\t// Return the row and column index.\n\t\t\treturn {\n\t\t\t\trow: rowIndex + 1, // Start index at 1.\n\t\t\t\tcolumn: columnIndex + 1,\n\t\t\t};\n\t\t},\n\t\t[ clientId ],\n\t);\n\n\t// Update the row and column index.\n\tuseEffect( () => {\n\t\t// Set the row and column index.\n\t\tsetAttributes( { row, column } );\n\t}, [ row, column, setAttributes ] );\n\n\t// Set the block ID.\n\tuseEffect( () => {\n\t\t// Set the block ID.\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t// Determine tag.\n\tlet Tag: string = 'td';\n\n\t// Check if the row container type is not tbody.\n\tif ( 'tbody' !== rowContainerType ) {\n\t\tTag = 'th';\n\t}\n\n\t// Return the column block.\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t setAttributes( { isSticky } ) }\n\t\t\t\t\t\thelp={ __( 'Is this column sticky?', 'tp' ) }\n\t\t\t\t\t/>\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { InnerBlocks } from '@wordpress/block-editor';\n\n/**\n * Save component.\n */\nexport default function Save() {\n\t// Save inner content.\n\treturn ;\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport { blockTable as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport metadata from './block.json';\nimport edit from './edit';\nimport save from './save';\n\n/**\n * Block name.\n */\nexport const { name }: { name: string } = metadata;\n\n/**\n * Block settings.\n */\nexport const settings: BlockConfiguration = {\n\t...metadata,\n\ticon,\n\tedit,\n\tsave,\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { name as columnBlockName } from '../column';\nimport { useEffect } from '@wordpress/element';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Edit( props: BlockEditProps ): JSX.Element {\n\t// Block props.\n\tconst { className, clientId, setAttributes } = props;\n\n\t// Inner block props.\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__row' ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps( { ...blockProps }, {\n\t\tallowedBlocks: [ columnBlockName ],\n\t\ttemplateLock: false,\n\t} );\n\n\t// Set block id.\n\tuseEffect( () => {\n\t\t// Set block attributes.\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t// Return inner blocks.\n\treturn (\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { InnerBlocks } from '@wordpress/block-editor';\n\n/**\n * Save component.\n */\nexport default function Save() {\n\t// Save inner content.\n\treturn ;\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration } from '@wordpress/blocks';\nimport { blockTable as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport metadata from './block.json';\nimport edit from './edit';\nimport save from './save';\n\n/**\n * Block name.\n */\nexport const { name }: { name: string } = metadata;\n\n// @ts-ignore Ignore BlockConfiguration type error for providesContext.\nexport const settings: BlockConfiguration = {\n\t...metadata,\n\ticon,\n\tedit,\n\tsave,\n};\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport {\n\tPanelBody,\n\tToggleControl,\n} from '@wordpress/components';\nimport {\n\tBlockEditProps,\n} from '@wordpress/blocks';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { name as rowBlockName } from '../row';\nimport { useEffect } from '@wordpress/element';\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Edit( props: BlockEditProps ): JSX.Element {\n\t// Block props.\n\tconst { className, attributes, setAttributes, clientId } = props;\n\n\t// Inner block props.\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table__row-container', {\n\t\t\t'travelopia-table__row-container--sticky': attributes.isSticky,\n\t\t} ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps( { ...blockProps }, {\n\t\tallowedBlocks: [ rowBlockName ],\n\t} );\n\n\t// Determine tag.\n\tconst Tag: string = attributes.type;\n\n\t// Set block id.\n\tuseEffect( () => {\n\t\t// Set block attributes.\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t// Return component.\n\treturn (\n\t\t<>\n\t\t\t{ 'thead' === attributes.type &&\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t setAttributes( { isSticky } ) }\n\t\t\t\t\t\t\thelp={ __( 'Is this container sticky?', 'tp' ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { InnerBlocks } from '@wordpress/block-editor';\n\n/**\n * Save component.\n */\nexport default function Save() {\n\t// Save inner content.\n\treturn ;\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n} from '@wordpress/block-editor';\nimport { BlockEditProps, createBlock } from '@wordpress/blocks';\nimport { useEffect } from '@wordpress/element';\nimport { PanelBody, ToggleControl } from '@wordpress/components';\nimport { select, dispatch } from '@wordpress/data';\n\n/**\n * External dependencies.\n */\nimport classnames from 'classnames';\n\n/**\n * Internal dependencies.\n */\nimport { TablePlaceholder } from './placeholder';\nimport { name as rowContainerBlockName } from './children/row-container';\nimport { name as rowBlockName } from './children/row';\nimport { name as columnBlockName } from './children/column';\nimport { name as cellBlockName } from './children/cell';\n\n/**\n * Create and insert a row container.\n *\n * @param {string} type Row container type.\n * @param {string} tableClientId The table block's client ID.\n */\nexport const createAndInsertRowContainer = (\n\ttype: string = 'tbody',\n\ttableClientId: string = '',\n): void => {\n\t// Get table block.\n\tconst tableBlock = select( 'core/block-editor' ).getBlock( tableClientId );\n\n\t// Return if table block is not found.\n\tif ( ! tableBlock ) {\n\t\t// Exit early.\n\t\treturn;\n\t}\n\n\t// Create row container.\n\tconst rowContainerBlock = createBlock( rowContainerBlockName, { type } );\n\n\t// Determine number of rows to create.\n\tlet totalRows = tableBlock.attributes.rows;\n\n\t// Check if the type is not tbody.\n\tif ( 'tbody' !== type ) {\n\t\ttotalRows = 1;\n\t}\n\n\t// Add rows and columns to it.\n\tfor ( let i: number = 0; i < totalRows; i++ ) {\n\t\tconst columnBlocks = [];\n\n\t\t// Loop through columns.\n\t\tfor ( let j: number = 0; j < tableBlock.attributes.columns; j++ ) {\n\t\t\tcolumnBlocks.push(\n\t\t\t\tcreateBlock( columnBlockName, {}, [ createBlock( cellBlockName ) ] ),\n\t\t\t);\n\t\t}\n\n\t\t// Create row block.\n\t\trowContainerBlock.innerBlocks.push(\n\t\t\tcreateBlock( rowBlockName, {}, columnBlocks ),\n\t\t);\n\t}\n\n\t// Add newly created row and column blocks to the table.\n\tif ( 'tbody' === type ) {\n\t\tdispatch( 'core/block-editor' ).replaceInnerBlocks( tableClientId, [\n\t\t\trowContainerBlock,\n\t\t] );\n\t} else {\n\t\tconst position = 'thead' === type ? 0 : tableBlock.innerBlocks.length;\n\t\tdispatch( 'core/block-editor' ).insertBlock(\n\t\t\trowContainerBlock,\n\t\t\tposition,\n\t\t\ttableClientId,\n\t\t);\n\t}\n};\n\n/**\n * Delete row container child block.\n *\n * @param {string} type Row container type.\n * @param {string} tableClientId The table block's client ID.\n */\nexport const deleteRowContainer = (\n\ttype: string = 'thead',\n\ttableClientId: string = '',\n): void => {\n\t// Get table block.\n\tconst tableBlock = select( 'core/block-editor' ).getBlock( tableClientId );\n\n\t// Return if table block is not found.\n\tif ( ! tableBlock || ! tableBlock.innerBlocks.length ) {\n\t\t// Exit early.\n\t\treturn;\n\t}\n\n\t// Find the child block and delete it.\n\ttableBlock.innerBlocks.forEach( ( innerBlock ) => {\n\t\t// Check if the block type matches.\n\t\tif ( innerBlock.attributes?.type === type ) {\n\t\t\tdispatch( 'core/block-editor' ).removeBlock( innerBlock.clientId );\n\t\t}\n\t} );\n};\n\n/**\n * Edit function.\n *\n * @param {Object} props Edit properties.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Edit( props: BlockEditProps ): JSX.Element {\n\t// Destructure properties.\n\tconst { className, attributes, clientId, setAttributes } = props;\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classnames( className, 'travelopia-table' ),\n\t} );\n\tconst innerBlocksProps = useInnerBlocksProps(\n\t\t{},\n\t\t{\n\t\t\tallowedBlocks: [ rowContainerBlockName ],\n\t\t\trenderAppender: undefined,\n\t\t},\n\t);\n\n\t// Set blockId attribute.\n\tuseEffect( () => {\n\t\t// Set blockId attribute.\n\t\tsetAttributes( { blockId: clientId } );\n\t}, [ clientId, setAttributes ] );\n\n\t/**\n\t * Handle THEAD change.\n\t *\n\t * @param {boolean} hasThead Has THEAD.\n\t */\n\tconst handleTheadChange = ( hasThead: boolean ): void => {\n\t\t// Create or delete THEAD row container.\n\t\tif ( hasThead ) {\n\t\t\tcreateAndInsertRowContainer( 'thead', clientId );\n\t\t} else {\n\t\t\tdeleteRowContainer( 'thead', clientId );\n\t\t}\n\t\tsetAttributes( { hasThead } );\n\t};\n\n\t/**\n\t * Handle TFOOT change.\n\t *\n\t * @param {boolean} hasTfoot Has TFOOT.\n\t */\n\tconst handleTfootChange = ( hasTfoot: boolean ): void => {\n\t\t// Create or delete TFOOT row container.\n\t\tif ( hasTfoot ) {\n\t\t\tcreateAndInsertRowContainer( 'tfoot', clientId );\n\t\t} else {\n\t\t\tdeleteRowContainer( 'tfoot', clientId );\n\t\t}\n\t\tsetAttributes( { hasTfoot } );\n\t};\n\n\t// Return the component.\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t
\n\t\t\t\t{\n\t\t\t\t\t/* Placeholder for initial state. */\n\t\t\t\t\t( 0 === attributes.rows || 0 === attributes.columns ) && (\n\t\t\t\t\t\t\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\t{ ( 0 !== attributes.rows || 0 !== attributes.columns ) && (\n\t\t\t\t\t
\n\t\t\t\t) }\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration, registerBlockType } from '@wordpress/blocks';\nimport { blockTable as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies.\n */\nimport metadata from './block.json';\nimport edit from './edit';\nimport save from './save';\n\n/**\n * Block name.\n */\nexport const { name }: { name: string } = metadata;\n\n/**\n * Styles.\n */\nimport '../../../front-end/table/index.scss';\nimport './editor.scss';\n\n// @ts-ignore Ignore BlockConfiguration type error for providesContext.\nexport const settings: BlockConfiguration = {\n\t...metadata,\n\ticon,\n\tedit,\n\tsave,\n};\n\n/**\n * Children blocks.\n */\nimport * as row from './children/row';\nimport * as rowContainer from './children/row-container';\nimport * as column from './children/column';\nimport * as cell from './children/cell';\n\n/**\n * Initialization.\n */\nexport const init = (): void => {\n\t// Register block.\n\tregisterBlockType( name, settings );\n\n\t// Register children blocks.\n\tregisterBlockType( row.name, row.settings );\n\tregisterBlockType( rowContainer.name, rowContainer.settings );\n\tregisterBlockType( column.name, column.settings );\n\tregisterBlockType( cell.name, cell.settings );\n};\n","/**\n * WordPress dependencies.\n */\nimport { InnerBlocks } from '@wordpress/block-editor';\n\n/**\n * Save component.\n */\nexport default function Save() {\n\t// Save inner content.\n\treturn ;\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = window[\"wp\"][\"hooks\"];","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowBefore = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84zM6.656 6.464h2.88v2.88h1.408v-2.88h2.88V5.12h-2.88V2.24H9.536v2.88h-2.88zM0 17.92V0h20.48v17.92H0zm7.68-2.56h5.12v-3.84H7.68v3.84zm-6.4 0H6.4v-3.84H1.28v3.84zM19.2 1.28H1.28v9.024H19.2V1.28zm0 10.24h-5.12v3.84h5.12v-3.84z\"\n}));\nexport default tableRowBefore;\n//# sourceMappingURL=table-row-before.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowAfter = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M13.824 10.176h-2.88v-2.88H9.536v2.88h-2.88v1.344h2.88v2.88h1.408v-2.88h2.88zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm6.4 0H7.68v3.84h5.12V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.056H1.28v9.024H19.2V6.336z\"\n}));\nexport default tableRowAfter;\n//# sourceMappingURL=table-row-after.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableRowDelete = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M17.728 11.456L14.592 8.32l3.2-3.2-1.536-1.536-3.2 3.2L9.92 3.648 8.384 5.12l3.2 3.2-3.264 3.264 1.536 1.536 3.264-3.264 3.136 3.136 1.472-1.536zM0 17.92V0h20.48v17.92H0zm19.2-6.4h-.448l-1.28-1.28H19.2V6.4h-1.792l1.28-1.28h.512V1.28H1.28v3.84h6.208l1.28 1.28H1.28v3.84h7.424l-1.28 1.28H1.28v3.84H19.2v-3.84z\"\n}));\nexport default tableRowDelete;\n//# sourceMappingURL=table-row-delete.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnBefore = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.4 3.776v3.648H2.752v1.792H6.4v3.648h1.728V9.216h3.712V7.424H8.128V3.776zM0 17.92V0h20.48v17.92H0zM12.8 1.28H1.28v14.08H12.8V1.28zm6.4 0h-5.12v3.84h5.12V1.28zm0 5.12h-5.12v3.84h5.12V6.4zm0 5.12h-5.12v3.84h5.12v-3.84z\"\n}));\nexport default tableColumnBefore;\n//# sourceMappingURL=table-column-before.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnAfter = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M14.08 12.864V9.216h3.648V7.424H14.08V3.776h-1.728v3.648H8.64v1.792h3.712v3.648zM0 17.92V0h20.48v17.92H0zM6.4 1.28H1.28v3.84H6.4V1.28zm0 5.12H1.28v3.84H6.4V6.4zm0 5.12H1.28v3.84H6.4v-3.84zM19.2 1.28H7.68v14.08H19.2V1.28z\"\n}));\nexport default tableColumnAfter;\n//# sourceMappingURL=table-column-after.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst tableColumnDelete = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"-2 -2 24 24\"\n}, createElement(Path, {\n d: \"M6.4 9.98L7.68 8.7v-.256L6.4 7.164V9.98zm6.4-1.532l1.28-1.28V9.92L12.8 8.64v-.192zm7.68 9.472V0H0v17.92h20.48zm-1.28-2.56h-5.12v-1.024l-.256.256-1.024-1.024v1.792H7.68v-1.792l-1.024 1.024-.256-.256v1.024H1.28V1.28H6.4v2.368l.704-.704.576.576V1.216h5.12V3.52l.96-.96.32.32V1.216h5.12V15.36zm-5.76-2.112l-3.136-3.136-3.264 3.264-1.536-1.536 3.264-3.264L5.632 5.44l1.536-1.536 3.136 3.136 3.2-3.2 1.536 1.536-3.2 3.2 3.136 3.136-1.536 1.536z\"\n}));\nexport default tableColumnDelete;\n//# sourceMappingURL=table-column-delete.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowLeft = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z\"\n}));\nexport default arrowLeft;\n//# sourceMappingURL=arrow-left.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowRight = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z\"\n}));\nexport default arrowRight;\n//# sourceMappingURL=arrow-right.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowUp = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M12 3.9 6.5 9.5l1 1 3.8-3.7V20h1.5V6.8l3.7 3.7 1-1z\"\n}));\nexport default arrowUp;\n//# sourceMappingURL=arrow-up.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst arrowDown = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z\"\n}));\nexport default arrowDown;\n//# sourceMappingURL=arrow-down.js.map","import { createElement } from \"react\";\n/**\n * WordPress dependencies\n */\nimport { SVG, Path } from '@wordpress/primitives';\nconst table = createElement(SVG, {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\"\n}, createElement(Path, {\n d: \"M4 6v11.5h16V6H4zm1.5 1.5h6V11h-6V7.5zm0 8.5v-3.5h6V16h-6zm13 0H13v-3.5h5.5V16zM13 11V7.5h5.5V11H13z\"\n}));\nexport default table;\n//# sourceMappingURL=table.js.map","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockInstance, createBlock } from '@wordpress/blocks';\nimport { BlockControls } from '@wordpress/block-editor';\nimport { ToolbarDropdownMenu } from '@wordpress/components';\nimport { select, dispatch } from '@wordpress/data';\nimport { DropdownOption } from '@wordpress/components/build-types/dropdown-menu/types';\nimport {\n\tarrowLeft,\n\tarrowRight,\n\tarrowUp,\n\tarrowDown,\n\ttableColumnAfter,\n\ttableColumnBefore,\n\ttableColumnDelete,\n\ttableRowAfter,\n\ttableRowBefore,\n\ttableRowDelete,\n\ttable,\n} from '@wordpress/icons';\nimport { useState, useEffect, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies.\n */\nimport { name as columnBlockName } from './table/children/column';\nimport { name as rowBlockName } from './table/children/row';\nimport { name as cellBlockName } from './table/children/cell';\nimport { name as rowContainerBlockName } from './table/children/row-container';\n\n/**\n * Column block toolbar.\n *\n * @param {Object} props Block properties.\n * @param {boolean} props.isSelected Is block selected.\n * @param {string} props.tableId Table block ID.\n * @param {number} props.tableRow Table row index.\n * @param {number} props.tableColumn Table column index.\n * @param {string} props.rowContainerId Table row container ID.\n * @param {string} props.columnId Column block ID.\n *\n * @return {JSX.Element} JSX Component.\n */\nexport default function Toolbar( {\n\tisSelected,\n\ttableId,\n\ttableRow,\n\ttableColumn,\n\trowContainerId,\n\tcolumnId,\n}: {\n\tisSelected: boolean;\n\ttableId: string;\n\ttableRow: number;\n\ttableColumn: number;\n\trowContainerId: string;\n\tcolumnId: string;\n} ): JSX.Element {\n\t// Get block editor select and dispatch.\n\tconst {\n\t\tgetBlock,\n\t\tcanInsertBlockType,\n\t\tgetBlockAttributes,\n\t\tgetAdjacentBlockClientId,\n\n\t\t// @ts-ignore - Property 'canRemoveBlock' does not exist on type 'Store'.\n\t\tcanRemoveBlock,\n\t} = select( 'core/block-editor' );\n\n\t// Get block editor dispatch.\n\tconst {\n\t\tremoveBlock,\n\t\tremoveBlocks,\n\t\tinsertBlock,\n\t\tupdateBlockAttributes,\n\n\t\t// @ts-ignore - Property 'moveBlocksToPosition' does not exist on type 'Store'.\n\t\tmoveBlocksToPosition,\n\t} = dispatch( 'core/block-editor' );\n\n\t// State variables.\n\tconst [ maximumColumnsInCurrentRow, setMaximumColumnsInCurrentRow ] =\n\t\tuseState( 0 );\n\tconst [ maximumRowsInCurrentColumn, setMaximumRowsInCurrentColumn ] =\n\t\tuseState( 0 );\n\n\t// Get row container block type.\n\tconst rowContainerBlockType = useMemo(\n\t\t() => getBlock( rowContainerId )?.attributes?.type,\n\t\t[ rowContainerId, getBlock ],\n\t);\n\n\t/**\n\t * Set maximum columns in current row.\n\t */\n\tuseEffect( (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if we have a block.\n\t\tif ( ! tableBlock ) {\n\t\t\tsetMaximumColumnsInCurrentRow( 0 );\n\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse table.\n\t\ttableBlock.innerBlocks.some( ( rowContainerBlock ): boolean => {\n\t\t\t// Check if the block is a row container.\n\t\t\tif (\n\t\t\t\trowContainerBlock.name !== rowContainerBlockName ||\n\t\t\t\t! rowContainerBlock.innerBlocks.length\n\t\t\t) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Traverse row container.\n\t\t\tlet maxRows = 0;\n\t\t\trowContainerBlock.innerBlocks.forEach( ( rowBlock, rowIndex ) => {\n\t\t\t\t// Check if the block is a row.\n\t\t\t\tif ( rowBlock.name !== rowBlockName || ! rowBlock.innerBlocks.length ) {\n\t\t\t\t\t// Continue loop.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Set maximum columns in current row.\n\t\t\t\tif ( rowIndex + 1 === tableRow ) {\n\t\t\t\t\tsetMaximumColumnsInCurrentRow( rowBlock.innerBlocks.length );\n\t\t\t\t}\n\n\t\t\t\t// Set maximum rows in current column.\n\t\t\t\trowBlock.innerBlocks.forEach( ( columnBlock, columnIndex ) => {\n\t\t\t\t\t// Check if the block is a column.\n\t\t\t\t\tif (\n\t\t\t\t\t\tcolumnBlock.name !== columnBlockName ||\n\t\t\t\t\t\tcolumnIndex + 1 !== tableColumn\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Continue loop.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Increment maximum rows.\n\t\t\t\t\tmaxRows++;\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t// Set maximum rows in current column.\n\t\t\tsetMaximumRowsInCurrentColumn( maxRows );\n\n\t\t\t// Short-circuit loop.\n\t\t\treturn true;\n\t\t} );\n\t}, [ tableRow, tableColumn, getBlock, tableId ] );\n\n\t/**\n\t * Insert row.\n\t *\n\t * @param {0|-1} insertionIndex Insertion index. -1 for before and 0 for after.\n\t */\n\tconst onInsertRow = ( insertionIndex: 0 | -1 = 0 ) => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if the row block can be inserted.\n\t\tif ( ! canInsertBlockType( rowBlockName, rowContainerId ) ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Create column blocks.\n\t\tconst columnBlocks = [];\n\n\t\t// Loop through the table columns count attribute.\n\t\tfor ( let i = 0; i < tableBlock.attributes?.columns || 0; i++ ) {\n\t\t\tcolumnBlocks.push(\n\t\t\t\tcreateBlock( columnBlockName, {}, [ createBlock( cellBlockName ) ] ),\n\t\t\t);\n\t\t}\n\n\t\t// Create a new row block.\n\t\tconst newRowBlock = createBlock( rowBlockName, {}, columnBlocks );\n\n\t\t// Insert the new row block.\n\t\tinsertBlock( newRowBlock, tableRow + insertionIndex, rowContainerId );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\trows: tableBlock.attributes?.rows + 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Delete row.\n\t */\n\tconst onDeleteRow = () => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row block.\n\t\tconst currentRowBlock = rowContainerBlock.innerBlocks[ tableRow - 1 ];\n\n\t\t// Check if the current row block is removable.\n\t\tif (\n\t\t\t! currentRowBlock?.clientId ||\n\t\t\t! canRemoveBlock( currentRowBlock.clientId )\n\t\t) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the current row block.\n\t\tremoveBlock( currentRowBlock.clientId );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\trows: tableBlock.attributes?.rows - 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Insert column.\n\t *\n\t * @param {0|-1} insertionIndex Insertion index. -1 for before and 0 for after.\n\t */\n\tconst onInsertColumn = ( insertionIndex: 0 | -1 = 0 ) => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Loop through the table row blocks and insert a new column block.\n\t\ttableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => {\n\t\t\t// Check the name of the row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\tcurrentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => {\n\t\t\t\t// Check the name of the row block.\n\t\t\t\tif ( rowBlock.name !== rowBlockName ) {\n\t\t\t\t\t// Continue loop.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check if the column block can be inserted.\n\t\t\t\tif ( ! canInsertBlockType( columnBlockName, rowBlock.clientId ) ) {\n\t\t\t\t\t// Continue loop.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Create a new column block.\n\t\t\t\tconst newColumnBlock = createBlock( columnBlockName, {}, [\n\t\t\t\t\tcreateBlock( cellBlockName ),\n\t\t\t\t] );\n\n\t\t\t\t// Insert the new column block.\n\t\t\t\tinsertBlock(\n\t\t\t\t\tnewColumnBlock,\n\t\t\t\t\ttableColumn + insertionIndex,\n\t\t\t\t\trowBlock.clientId,\n\t\t\t\t);\n\t\t\t} );\n\t\t} );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\tcolumns: tableBlock.attributes?.columns + 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Delete column.\n\t */\n\tconst onDeleteColumn = () => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Columns to be removed.\n\t\tconst columnsToRemove: string[] = [];\n\n\t\t// Loop through the table row blocks.\n\t\ttableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => {\n\t\t\t// Check the name of the row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\tcurrentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => {\n\t\t\t\t// Check the name of the row block.\n\t\t\t\tif ( rowBlock.name !== rowBlockName ) {\n\t\t\t\t\t// Continue loop.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Get the current column block.\n\t\t\t\tconst currentColumnBlock = rowBlock.innerBlocks[ tableColumn - 1 ];\n\n\t\t\t\t// Check if the current column block is removable.\n\t\t\t\tif (\n\t\t\t\t\tcurrentColumnBlock?.clientId &&\n\t\t\t\t\tcanRemoveBlock( currentColumnBlock.clientId )\n\t\t\t\t) {\n\t\t\t\t\tcolumnsToRemove.push( currentColumnBlock.clientId );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\n\t\t// Remove the columns.\n\t\tremoveBlocks( columnsToRemove );\n\n\t\t// Update the table block attributes.\n\t\tupdateBlockAttributes( tableId, {\n\t\t\tcolumns: tableBlock.attributes?.columns - 1,\n\t\t} );\n\t};\n\n\t/**\n\t * Merge column left.\n\t */\n\tconst onMergeColumnLeft = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current column block.\n\t\tconst currentBlock = getBlock( columnId );\n\n\t\t// Check if the current column block exists.\n\t\tif ( ! currentBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get previous block client ID.\n\t\tconst previousBlockClientId = getAdjacentBlockClientId( columnId, -1 );\n\n\t\t// Check if the previous block client ID exists.\n\t\tif ( ! previousBlockClientId ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Previous block.\n\t\tconst previousBlock = getBlock( previousBlockClientId );\n\n\t\t// Check if the previous block exists.\n\t\tif ( ! previousBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Merge columns.\n\t\tmergeColumnsHorizontally( currentBlock, previousBlock );\n\t};\n\n\t/**\n\t * Merge column right.\n\t */\n\tconst onMergeColumnRight = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current column block.\n\t\tconst currentBlock = getBlock( columnId );\n\n\t\t// Check if the current column block exists.\n\t\tif ( ! currentBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get next block client ID.\n\t\tconst nextBlockClientId = getAdjacentBlockClientId( columnId, 1 );\n\n\t\t// Check if the next block client ID exists.\n\t\tif ( ! nextBlockClientId ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Next block.\n\t\tconst nextBlock = getBlock( nextBlockClientId );\n\n\t\t// Check if the next block exists.\n\t\tif ( ! nextBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Merge columns.\n\t\tmergeColumnsHorizontally( nextBlock, currentBlock );\n\t};\n\n\t/**\n\t * Merge column up.\n\t */\n\tconst onMergeColumnUp = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare variables.\n\t\tlet columnToMergeInto: BlockInstance | undefined;\n\t\tlet columnToMergeFrom: BlockInstance | undefined;\n\n\t\t// Traverse rows.\n\t\ttableBlock.innerBlocks.some( ( currentRowContainerBlock ) => {\n\t\t\t// Check if the row container block is the current row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Avoid merging thead/tfoot row with tbody row.\n\t\t\tconst currentRowContainerBlockAttributes = getBlockAttributes(\n\t\t\t\tcurrentRowContainerBlock.clientId,\n\t\t\t);\n\n\t\t\t// Check if the row container block attributes are the same.\n\t\t\tif (\n\t\t\t\tcurrentRowContainerBlockAttributes?.type !==\n\t\t\t\trowContainerBlock?.attributes?.type\n\t\t\t) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\treturn currentRowContainerBlock.innerBlocks.some(\n\t\t\t\t( rowBlock, rowIndex ): boolean => {\n\t\t\t\t\t// Get current row.\n\t\t\t\t\tconst rowNumber: number = rowIndex + 1;\n\n\t\t\t\t\t// Check if the row block is the current row block.\n\t\t\t\t\tif (\n\t\t\t\t\t\trowBlock.name !== rowBlockName ||\n\t\t\t\t\t\t( rowNumber !== tableRow && rowNumber !== tableRow - 1 ) ||\n\t\t\t\t\t\t! rowBlock.innerBlocks.length\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Continue loop.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Traverse columns in current row.\n\t\t\t\t\trowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => {\n\t\t\t\t\t\t// Get column to merge from and into.\n\t\t\t\t\t\tconst columnNumber: number = columnIndex + 1;\n\n\t\t\t\t\t\t// Check if the column block is the current column block.\n\t\t\t\t\t\tif ( columnNumber === tableColumn && rowNumber === tableRow ) {\n\t\t\t\t\t\t\tcolumnToMergeFrom = columnBlock;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tcolumnNumber === tableColumn &&\n\t\t\t\t\t\t\trowNumber === tableRow - 1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcolumnToMergeInto = columnBlock;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Short circuit if we found them.\n\t\t\t\t\t\tif ( columnToMergeInto && columnToMergeFrom ) {\n\t\t\t\t\t\t\t// Exit early.\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We haven't found them, loop some more.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Check if we have a \"to\" and \"from\" column.\n\t\t\t\t\tif ( ! columnToMergeFrom || ! columnToMergeInto ) {\n\t\t\t\t\t\t// Exit early.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Merge columns.\n\t\t\t\t\tmergeColumnsVertically( columnToMergeFrom, columnToMergeInto );\n\n\t\t\t\t\t// Short-circuit loop.\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t);\n\t\t} );\n\t};\n\n\t/**\n\t * Merge column down.\n\t */\n\tconst onMergeColumnDown = (): void => {\n\t\t// Get table block.\n\t\tconst tableBlock = getBlock( tableId );\n\n\t\t// Check if the table block exists.\n\t\tif ( ! tableBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current row container block.\n\t\tconst rowContainerBlock = getBlock( rowContainerId );\n\n\t\t// Check if the row container block exists.\n\t\tif ( ! rowContainerBlock ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare variables.\n\t\tlet columnToMergeInto: BlockInstance | undefined;\n\t\tlet columnToMergeFrom: BlockInstance | undefined;\n\n\t\t// Traverse rows.\n\t\ttableBlock.innerBlocks.some( ( currentRowContainerBlock ) => {\n\t\t\t// Check if the row container block is the current row container block.\n\t\t\tif ( currentRowContainerBlock.name !== rowContainerBlockName ) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Avoid merging thead/tfoot row with tbody row.\n\t\t\tconst currentRowContainerBlockAttributes = getBlockAttributes(\n\t\t\t\tcurrentRowContainerBlock.clientId,\n\t\t\t);\n\n\t\t\t// Check if the row container block attributes are the same.\n\t\t\tif (\n\t\t\t\tcurrentRowContainerBlockAttributes?.type !==\n\t\t\t\trowContainerBlock?.attributes?.type\n\t\t\t) {\n\t\t\t\t// Continue loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Loop through the row container blocks.\n\t\t\treturn currentRowContainerBlock.innerBlocks.some(\n\t\t\t\t( rowBlock, rowIndex ): boolean => {\n\t\t\t\t\t// Get current row.\n\t\t\t\t\tconst rowNumber: number = rowIndex + 1;\n\n\t\t\t\t\t// Check if the row block is the current row block.\n\t\t\t\t\tif (\n\t\t\t\t\t\trowBlock.name !== rowBlockName ||\n\t\t\t\t\t\t( rowNumber !== tableRow && rowNumber !== tableRow + 1 ) ||\n\t\t\t\t\t\t! rowBlock.innerBlocks.length\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Continue loop.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Traverse columns in current row.\n\t\t\t\t\trowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => {\n\t\t\t\t\t\t// Get column to merge from and into.\n\t\t\t\t\t\tconst columnNumber: number = columnIndex + 1;\n\n\t\t\t\t\t\t// Check if the column block is the current column block.\n\t\t\t\t\t\tif ( columnNumber === tableColumn && rowNumber === tableRow ) {\n\t\t\t\t\t\t\tcolumnToMergeInto = columnBlock;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tcolumnNumber === tableColumn &&\n\t\t\t\t\t\t\trowNumber === tableRow + 1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcolumnToMergeFrom = columnBlock;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Short circuit if we found them.\n\t\t\t\t\t\tif ( columnToMergeInto && columnToMergeFrom ) {\n\t\t\t\t\t\t\t// Exit early.\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We haven't found them, loop some more.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Check if we have a \"to\" and \"from\" column.\n\t\t\t\t\tif ( ! columnToMergeFrom || ! columnToMergeInto ) {\n\t\t\t\t\t\t// Exit early.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Merge columns.\n\t\t\t\t\tmergeColumnsVertically( columnToMergeFrom, columnToMergeInto );\n\n\t\t\t\t\t// Short-circuit loop.\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t);\n\t\t} );\n\t};\n\n\t/**\n\t * Merge columns horizontally.\n\t *\n\t * @param {Object} fromColumn From column block instance.\n\t * @param {Object} toColumn To column block instance.\n\t */\n\tconst mergeColumnsHorizontally = (\n\t\tfromColumn: BlockInstance,\n\t\ttoColumn: BlockInstance,\n\t): void => {\n\t\t// Get colspans.\n\t\tconst mergeIntoAttributes = getBlockAttributes( toColumn.clientId );\n\t\tconst mergeFromAttributes = getBlockAttributes( fromColumn.clientId );\n\n\t\t// Get rowspans.\n\t\tconst mergeIntoRowspan: number = parseInt(\n\t\t\tmergeIntoAttributes?.rowSpan ?? 1,\n\t\t);\n\t\tconst mergeFromRowspan: number = parseInt(\n\t\t\tmergeFromAttributes?.rowSpan ?? 1,\n\t\t);\n\n\t\t// Invalid merge.\n\t\tif ( mergeIntoRowspan !== mergeFromRowspan ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get colspans.\n\t\tconst mergeIntoColspan: number = parseInt(\n\t\t\tmergeIntoAttributes?.colSpan ?? 1,\n\t\t);\n\t\tconst mergeFromColspan: number = parseInt(\n\t\t\tmergeFromAttributes?.colSpan ?? 1,\n\t\t);\n\n\t\t// Update colspan.\n\t\tupdateBlockAttributes( toColumn.clientId, {\n\t\t\tcolSpan: mergeIntoColspan + mergeFromColspan,\n\t\t} );\n\n\t\t// If it is the current column, move children to previous column and delete current column.\n\t\tmoveBlocksToPosition(\n\t\t\tfromColumn.innerBlocks.map( ( block ) => block.clientId ),\n\t\t\tfromColumn.clientId,\n\t\t\ttoColumn.clientId,\n\t\t);\n\n\t\t// Remove block that is being merged from.\n\t\tremoveBlock( fromColumn.clientId );\n\t};\n\n\t/**\n\t * Merge columns vertically.\n\t *\n\t * @param {Object} fromColumn From column block instance.\n\t * @param {Object} toColumn To column block instance.\n\t */\n\tconst mergeColumnsVertically = (\n\t\tfromColumn: BlockInstance,\n\t\ttoColumn: BlockInstance,\n\t): void => {\n\t\t// Get rowspans.\n\t\tconst mergeIntoAttributes = getBlockAttributes( toColumn.clientId );\n\t\tconst mergeFromAttributes = getBlockAttributes( fromColumn.clientId );\n\n\t\t// Get colspans.\n\t\tconst mergeIntoColspan: number = parseInt(\n\t\t\tmergeIntoAttributes?.colSpan ?? 1,\n\t\t);\n\t\tconst mergeFromColspan: number = parseInt(\n\t\t\tmergeFromAttributes?.colSpan ?? 1,\n\t\t);\n\n\t\t// Invalid merge.\n\t\tif ( mergeIntoColspan !== mergeFromColspan ) {\n\t\t\t// Exit early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get rowspans.\n\t\tconst mergeIntoRowspan: number = parseInt(\n\t\t\tmergeIntoAttributes?.rowSpan ?? 1,\n\t\t);\n\t\tconst mergeFromRowspan: number = parseInt(\n\t\t\tmergeFromAttributes?.rowSpan ?? 1,\n\t\t);\n\n\t\t// Update rowspan.\n\t\tupdateBlockAttributes( toColumn.clientId, {\n\t\t\trowSpan: mergeIntoRowspan + mergeFromRowspan,\n\t\t} );\n\n\t\t// If it is the current column, move children to previous column and delete current column.\n\t\tmoveBlocksToPosition(\n\t\t\tfromColumn.innerBlocks.map( ( block ) => block.clientId ),\n\t\t\tfromColumn.clientId,\n\t\t\ttoColumn.clientId,\n\t\t);\n\n\t\t// Remove block that is being merged from.\n\t\tremoveBlock( fromColumn.clientId );\n\t};\n\n\t/**\n\t * Table controls.\n\t */\n\tconst tableControls = [\n\t\t{\n\t\t\ticon: tableRowBefore,\n\t\t\ttitle: __( 'Insert row before', 'tp' ),\n\t\t\tisDisabled:\n\t\t\t\t! isSelected ||\n\t\t\t\trowContainerBlockType === 'tfoot' ||\n\t\t\t\trowContainerBlockType === 'thead',\n\t\t\tonClick: () => onInsertRow( -1 ),\n\t\t},\n\t\t{\n\t\t\ticon: tableRowAfter,\n\t\t\ttitle: __( 'Insert row after', 'tp' ),\n\t\t\tisDisabled:\n\t\t\t\t! isSelected ||\n\t\t\t\trowContainerBlockType === 'tfoot' ||\n\t\t\t\trowContainerBlockType === 'thead',\n\t\t\tonClick: onInsertRow,\n\t\t},\n\t\t{\n\t\t\ticon: tableRowDelete,\n\t\t\ttitle: __( 'Delete row', 'tp' ),\n\t\t\tisDisabled:\n\t\t\t\t! isSelected ||\n\t\t\t\trowContainerBlockType === 'tfoot' ||\n\t\t\t\trowContainerBlockType === 'thead',\n\t\t\tonClick: onDeleteRow,\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnBefore,\n\t\t\ttitle: __( 'Insert column before', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: () => onInsertColumn( -1 ),\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnAfter,\n\t\t\ttitle: __( 'Insert column after', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: onInsertColumn,\n\t\t},\n\t\t{\n\t\t\ticon: tableColumnDelete,\n\t\t\ttitle: __( 'Delete column', 'tp' ),\n\t\t\tisDisabled: ! isSelected,\n\t\t\tonClick: onDeleteColumn,\n\t\t},\n\t\t{\n\t\t\ticon: arrowLeft,\n\t\t\ttitle: __( 'Merge column left', 'tp' ),\n\t\t\tisDisabled: tableColumn < 2,\n\t\t\tonClick: onMergeColumnLeft,\n\t\t},\n\t\t{\n\t\t\ticon: arrowRight,\n\t\t\ttitle: __( 'Merge column right', 'tp' ),\n\t\t\tisDisabled: tableColumn === maximumColumnsInCurrentRow,\n\t\t\tonClick: onMergeColumnRight,\n\t\t},\n\t\t{\n\t\t\ticon: arrowUp,\n\t\t\ttitle: __( 'Merge column up', 'tp' ),\n\t\t\tisDisabled:\n\t\t\t\ttableRow < 2 ||\n\t\t\t\trowContainerBlockType === 'tfoot' ||\n\t\t\t\trowContainerBlockType === 'thead',\n\t\t\tonClick: onMergeColumnUp,\n\t\t},\n\t\t{\n\t\t\ticon: arrowDown,\n\t\t\ttitle: __( 'Merge column down', 'tp' ),\n\t\t\tisDisabled:\n\t\t\t\ttableRow === maximumRowsInCurrentColumn ||\n\t\t\t\trowContainerBlockType === 'tfoot' ||\n\t\t\t\trowContainerBlockType === 'thead',\n\t\t\tonClick: onMergeColumnDown,\n\t\t},\n\t] as DropdownOption[];\n\n\t/**\n\t * Return block controls.\n\t */\n\treturn (\n\t\t<>\n\t\t\t{ /* @ts-ignore - Group is not defined in the prop-type. */ }\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n","/**\n * WordPress dependencies.\n */\nimport { __ } from '@wordpress/i18n';\nimport { BlockConfiguration, BlockEditProps } from '@wordpress/blocks';\nimport { addFilter } from '@wordpress/hooks';\n\n/**\n * Internal dependencies.\n */\nimport Toolbar from './toolbar';\n\n/**\n * Add context of table row and column to the block.\n */\naddFilter(\n\t'blocks.registerBlockType',\n\t'travelopia/table-row-column-context',\n\t( settings: BlockConfiguration ) => {\n\t\t// Contexts required for the block.\n\t\tconst requiredContexts = [\n\t\t\t'travelopia/table-row',\n\t\t\t'travelopia/table-column',\n\t\t\t'travelopia/table-id',\n\t\t\t'travelopia/table-row-container-id',\n\t\t\t'travelopia/table-column-id',\n\t\t];\n\n\t\t// Add context to the block.\n\t\tif ( settings.usesContext && Array.isArray( settings.usesContext ) ) {\n\t\t\trequiredContexts.forEach( ( context ) => {\n\t\t\t\t// Check if the context is already added.\n\t\t\t\tif ( ! settings.usesContext?.includes( context ) ) {\n\t\t\t\t\tsettings.usesContext?.push( context );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Add context to the block.\n\t\treturn settings;\n\t},\n);\n\n/**\n * Add toolbar to the table block.\n */\naddFilter( 'editor.BlockEdit', 'travelopia/table-toolbar', ( BlockEdit ) => {\n\t// Return the block edit component.\n\treturn ( props: BlockEditProps ) => {\n\t\t// Get the block context and isSelected prop.\n\t\tconst { context, isSelected } = props;\n\n\t\t// Check if the block has context.\n\t\tif ( ! context ) {\n\t\t\t// Return the block edit component.\n\t\t\treturn ;\n\t\t}\n\n\t\t// Get the table row and column from the block context.\n\t\tconst tableRow = context[ 'travelopia/table-row' ] as number;\n\t\tconst tableColumn = context[ 'travelopia/table-column' ] as number;\n\t\tconst tableId = context[ 'travelopia/table-id' ] as string;\n\t\tconst tableRowContainerId = context[ 'travelopia/table-row-container-id' ] as string;\n\t\tconst tableColumnId = context[ 'travelopia/table-column-id' ] as string;\n\n\t\t// Check if the table row and column are valid.\n\t\tif (\n\t\t\t! tableRow ||\n\t\t\t! tableColumn ||\n\t\t\t! tableId ||\n\t\t\ttableColumn < 1 ||\n\t\t\ttableRow < 1\n\t\t) {\n\t\t\t// Return the block edit component.\n\t\t\treturn ;\n\t\t}\n\n\t\t// Return the block edit component with toolbar.\n\t\treturn (\n\t\t\t<>\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t);\n\t};\n} );\n","/**\n * Import blocks.\n */\nimport * as table from './table';\n\n/**\n * Add blocks.\n */\nconst blocks = [\n\ttable,\n];\n\n/**\n * Register blocks.\n */\nblocks.forEach( ( { init } ) => init() );\n\n/**\n * Add block toolbar.\n */\nimport './block-toolbar';\n"],"names":["f","k","Symbol","for","l","m","Object","prototype","hasOwnProperty","n","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","p","key","ref","__self","__source","q","c","a","g","b","d","e","h","call","defaultProps","$$typeof","type","props","_owner","current","exports","Fragment","jsx","jsxs","module","window","hasOwn","classNames","classes","i","arguments","length","arg","appendClass","parseValue","Array","isArray","apply","toString","includes","value","newClass","default","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","getter","__esModule","definition","o","defineProperty","enumerable","get","obj","prop","r","toStringTag","createElement","SVG","viewBox","xmlns","Path","TablePlaceholder","setAttributes","clientId","rows","setRows","useState","columns","setColumns","Placeholder","label","__","icon","BlockIcon","showColors","instructions","className","onSubmit","preventDefault","createAndInsertRowContainer","TextControl","onChange","totalColumns","parseInt","min","totalRows","Button","variant","name","settings","edit","attributes","blockProps","useBlockProps","RichText","tagName","placeholder","content","save","Content","context","isSticky","rowContainerType","innerBlocksProps","useInnerBlocksProps","colSpan","rowSpan","template","templateLock","row","column","useSelect","select","columnIndex","getBlockIndex","rowClientId","getBlockRootClientId","useEffect","blockId","Tag","InspectorControls","PanelBody","title","ToggleControl","checked","help","InnerBlocks","allowedBlocks","tableClientId","tableBlock","getBlock","rowContainerBlock","createBlock","columnBlocks","j","push","innerBlocks","dispatch","replaceInnerBlocks","position","insertBlock","deleteRowContainer","forEach","innerBlock","removeBlock","renderAppender","hasThead","hasTfoot","init","registerBlockType","Toolbar","isSelected","tableId","tableRow","tableColumn","rowContainerId","columnId","canInsertBlockType","getBlockAttributes","getAdjacentBlockClientId","canRemoveBlock","removeBlocks","updateBlockAttributes","moveBlocksToPosition","maximumColumnsInCurrentRow","setMaximumColumnsInCurrentRow","maximumRowsInCurrentColumn","setMaximumRowsInCurrentColumn","rowContainerBlockType","useMemo","some","maxRows","rowBlock","rowIndex","columnBlock","onInsertRow","insertionIndex","newRowBlock","onInsertColumn","currentRowContainerBlock","newColumnBlock","mergeColumnsHorizontally","fromColumn","toColumn","mergeIntoAttributes","mergeFromAttributes","mergeIntoColspan","mergeFromColspan","map","block","mergeColumnsVertically","mergeIntoRowspan","mergeFromRowspan","tableControls","isDisabled","onClick","currentRowBlock","columnsToRemove","currentColumnBlock","currentBlock","previousBlockClientId","previousBlock","nextBlockClientId","nextBlock","columnToMergeInto","columnToMergeFrom","currentRowContainerBlockAttributes","rowNumber","columnNumber","BlockControls","group","ToolbarDropdownMenu","controls","addFilter","requiredContexts","usesContext","BlockEdit","tableRowContainerId","tableColumnId"],"sourceRoot":""} \ No newline at end of file diff --git a/inc/blocks/table-cell.php b/inc/blocks/table-cell.php deleted file mode 100644 index 7cd3391..0000000 --- a/inc/blocks/table-cell.php +++ /dev/null @@ -1,54 +0,0 @@ - get_css_classes( - $block['attrs'], - [ - 'travelopia-table__column', - ! empty( $block['attrs']['isSticky'] ) ? 'travelopia-table__column--sticky' : '', - $border_styles['css_classes'], - ] - ), - 'style' => get_css_styles( $block['attrs'] ) . $border_styles['inline_styles'], - 'colspan' => $block['attrs']['colSpan'] ?? '', - 'rowspan' => $block['attrs']['rowSpan'] ?? '', - ] - ); - - $html_tag = 'td'; - if ( ! empty( $block['attrs']['type'] ) ) { - $html_tag = 'th'; - } - - $cells_content = ''; - foreach ( $block['innerBlocks'] as $cell_block ) { - $cells_content .= render_block( $cell_block ); - } - - $column_content = sprintf( '<%1$s %2$s>%3$s', $html_tag, wp_kses_data( $column_attributes ), $cells_content ); - return $column_content; -} diff --git a/inc/blocks/table-row-container.php b/inc/blocks/table-row-container.php deleted file mode 100644 index 398fefc..0000000 --- a/inc/blocks/table-row-container.php +++ /dev/null @@ -1,89 +0,0 @@ - get_css_classes( - $block['attrs'], - [ - 'travelopia-table__row-container', - ! empty( $block['attrs']['isSticky'] ) ? 'travelopia-table__row-container--sticky' : '', - ] - ), - ] - ); - - $row_block_content = ''; - foreach ( $block['innerBlocks'] as $row_block ) { - $row_block_content .= render_block( $row_block ); - } - - $html_tag = 'tbody'; - if ( ! empty( $block['attrs']['type'] ) ) { - $html_tag = $block['attrs']['type']; - } - - $row_container_content = sprintf( - '<%1$s %2$s>%3$s', - $html_tag, - wp_kses_data( $block_attributes ), - $row_block_content - ); - - return $row_container_content; -} diff --git a/inc/blocks/table-row.php b/inc/blocks/table-row.php deleted file mode 100644 index 2baba6a..0000000 --- a/inc/blocks/table-row.php +++ /dev/null @@ -1,86 +0,0 @@ - get_css_classes( - $block['attrs'] ?? [], - [ - 'travelopia-table__row ', - $border_styles['css_classes'], - ] - ), - 'style' => get_css_styles( $block['attrs'] ?? [] ) . $border_styles['inline_styles'], - ] - ); - - $columns_content = ''; - foreach ( $block['innerBlocks'] as $column_block ) { - $columns_content .= render_block( $column_block ); - } - - $row_content = sprintf( - '%2$s', - wp_kses_data( $row_attributes ), - $columns_content - ); - return $row_content; -} diff --git a/inc/blocks/table.php b/inc/blocks/table.php deleted file mode 100644 index de17283..0000000 --- a/inc/blocks/table.php +++ /dev/null @@ -1,73 +0,0 @@ - get_css_classes( $block['attrs'] ), - 'style' => get_css_styles( $block['attrs'] ), - ] - ); - - $row_containers_content = ''; - foreach ( $block['innerBlocks'] as $row_container_block ) { - $row_containers_content .= render_block( $row_container_block ); - } - - $table_content = sprintf( - '
%2$s
', - wp_kses_data( $table_attributes ), - $row_containers_content - ); - return $table_content; -} diff --git a/inc/namespace.php b/inc/namespace.php index 311844d..e0f6277 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -89,26 +89,42 @@ function register_blocks(): void { // Include helper functions. require_once __DIR__ . '/blocks/helpers.php'; - // List of blocks to register. - $blocks = [ - 'Table' => 'table.php', - 'TableRowContainer' => 'table-row-container.php', - 'TableRow' => 'table-row.php', - 'TableColumn' => 'table-column.php', - 'TableCell' => 'table-cell.php', - ]; + // Path to blocks file. + $blocks_path = dirname( __DIR__ ) . '/dist/blocks.php'; + + // Get blocks from file, if it exists. + if ( ! file_exists( $blocks_path ) ) { + // Block file does not exist, bail. + return; + } + + // Load blocks. + $blocks = require $blocks_path; + + // Check if we have blocks. + if ( empty( $blocks ) || ! is_array( $blocks ) ) { + return; + } // Register blocks. - foreach ( $blocks as $namespace => $file_name ) { + foreach ( $blocks as $path => $namespace ) { // Include and bootstrap blocks. - require_once __DIR__ . '/blocks/' . $file_name; + $block_path = dirname( __DIR__ ) . '/' . $path; + + // Check if block file exists. + if ( ! file_exists( $block_path ) ) { + continue; + } + + // Require block. + require_once $block_path; // Get callable function name. - $callable = __NAMESPACE__ . '\\' . $namespace . '\\bootstrap'; + $_function = $namespace . '\\bootstrap'; - // If the function is callable, then call the function. - if ( is_callable( $callable ) ) { - call_user_func( $callable ); + // Execute the function if it exists. + if ( function_exists( $_function ) ) { + $_function(); } } } diff --git a/src/editor/blocks/block-toolbar.tsx b/src/editor/blocks/block-toolbar.tsx index 1f46d88..5576428 100644 --- a/src/editor/blocks/block-toolbar.tsx +++ b/src/editor/blocks/block-toolbar.tsx @@ -8,7 +8,7 @@ import { addFilter } from '@wordpress/hooks'; /** * Internal dependencies. */ -import Toolbar from './table-column/toolbar'; +import Toolbar from './toolbar'; /** * Add context of table row and column to the block. @@ -17,6 +17,7 @@ addFilter( 'blocks.registerBlockType', 'travelopia/table-row-column-context', ( settings: BlockConfiguration ) => { + // Contexts required for the block. const requiredContexts = [ 'travelopia/table-row', 'travelopia/table-column', @@ -25,14 +26,17 @@ addFilter( 'travelopia/table-column-id', ]; + // Add context to the block. if ( settings.usesContext && Array.isArray( settings.usesContext ) ) { requiredContexts.forEach( ( context ) => { + // Check if the context is already added. if ( ! settings.usesContext?.includes( context ) ) { settings.usesContext?.push( context ); } } ); } + // Add context to the block. return settings; }, ); @@ -41,19 +45,25 @@ addFilter( * Add toolbar to the table block. */ addFilter( 'editor.BlockEdit', 'travelopia/table-toolbar', ( BlockEdit ) => { + // Return the block edit component. return ( props: BlockEditProps ) => { + // Get the block context and isSelected prop. const { context, isSelected } = props; + // Check if the block has context. if ( ! context ) { + // Return the block edit component. return ; } + // Get the table row and column from the block context. const tableRow = context[ 'travelopia/table-row' ] as number; const tableColumn = context[ 'travelopia/table-column' ] as number; const tableId = context[ 'travelopia/table-id' ] as string; const tableRowContainerId = context[ 'travelopia/table-row-container-id' ] as string; const tableColumnId = context[ 'travelopia/table-column-id' ] as string; + // Check if the table row and column are valid. if ( ! tableRow || ! tableColumn || @@ -61,9 +71,11 @@ addFilter( 'editor.BlockEdit', 'travelopia/table-toolbar', ( BlockEdit ) => { tableColumn < 1 || tableRow < 1 ) { + // Return the block edit component. return ; } + // Return the block edit component with toolbar. return ( <> registerBlockType( name, settings ) ); +blocks.forEach( ( { init } ) => init() ); + +/** + * Add block toolbar. + */ +import './block-toolbar'; diff --git a/src/editor/blocks/table-cell/index.tsx b/src/editor/blocks/table-cell/index.tsx deleted file mode 100644 index 9ccffbc..0000000 --- a/src/editor/blocks/table-cell/index.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/** - * WordPress dependencies. - */ -import { __ } from '@wordpress/i18n'; -import { RichText } from '@wordpress/block-editor'; -import { - BlockConfiguration, - BlockInstance, - BlockSaveProps, - createBlock, - TransformBlock, -} from '@wordpress/blocks'; -import { - blockTable as icon, -} from '@wordpress/icons'; - -/** - * Internal dependencies. - */ -import edit from './edit'; - -/** - * Block data. - */ -export const name: string = 'travelopia/table-cell'; - -export const settings: BlockConfiguration = { - apiVersion: 3, - icon, - title: __( 'Cell', 'tp' ), - description: __( 'Individual cell of the table.', 'tp' ), - parent: [ 'travelopia/table-column' ], - category: 'text', - keywords: [ __( 'cell', 'tp' ) ], - attributes: { - content: { - type: 'string', - source: 'html', - }, - }, - supports: { - html: true, - className: false, - }, - transforms: { - to: [ - { - type: 'block', - blocks: [ 'core/heading' ], - transform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => { - return createBlock( - 'core/heading', { ...attributes, level: '3' }, innerBlocks - ); - }, - } as unknown as TransformBlock, - { - type: 'block', - blocks: [ 'core/paragraph' ], - transform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => { - return createBlock( 'core/paragraph', attributes, innerBlocks ); - }, - } as unknown as TransformBlock, - { - type: 'block', - blocks: [ 'core/list' ], - transform: ( attributes: string[], innerBlocks: BlockInstance<{ [k: string]: any; }>[] | undefined ) => { - return createBlock( - 'core/list', - {}, - [ - createBlock( 'core/list-item', attributes, innerBlocks ), - ] - ); - }, - } as unknown as TransformBlock, - ], - }, - edit, - save( { attributes }: BlockSaveProps ) { - return ( - - ); - }, -}; diff --git a/src/editor/blocks/table-column/index.tsx b/src/editor/blocks/table-column/index.tsx deleted file mode 100644 index b6cba23..0000000 --- a/src/editor/blocks/table-column/index.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/** - * WordPress dependencies. - */ -import { __ } from '@wordpress/i18n'; -import { BlockConfiguration } from '@wordpress/blocks'; -import { - InnerBlocks, -} from '@wordpress/block-editor'; -import { - blockTable as icon, -} from '@wordpress/icons'; - -/** - * Internal dependencies. - */ -import edit from './edit'; - -/** - * Block data. - */ -export const name: string = 'travelopia/table-column'; - -export const settings: BlockConfiguration = { - apiVersion: 3, - icon, - title: __( 'Column', 'tp' ), - description: __( 'Individual column of the table.', 'tp' ), - parent: [ 'travelopia/table-row' ], - category: 'text', - keywords: [ __( 'column', 'tp' ) ], - attributes: { - row: { - type: 'number', - }, - column: { - type: 'number', - }, - colSpan: { - type: 'number', - }, - rowSpan: { - type: 'number', - }, - isSticky: { - type: 'boolean', - }, - blockId: { - type: 'string', - }, - }, - providesContext: { - 'travelopia/table-row': 'row' as never, - 'travelopia/table-column': 'column' as never, - 'travelopia/table-column-id': 'blockId' as never, - }, - usesContext: [ - 'travelopia/table-row-container-type', - 'travelopia/table-row-container-id', - ], - supports: { - html: true, - color: { - text: true, - background: true, - }, - align: [ 'left', 'center', 'right' ], - // @ts-ignore - __experimentalBorder: { - color: true, - style: true, - width: true, - __experimentalDefaultControls: { - color: true, - style: true, - width: true, - }, - }, - }, - edit, - save() { - return ; - }, -}; diff --git a/src/editor/blocks/table-row-container/index.tsx b/src/editor/blocks/table-row-container/index.tsx deleted file mode 100644 index 8804fa7..0000000 --- a/src/editor/blocks/table-row-container/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/** - * WordPress dependencies. - */ -import { __ } from '@wordpress/i18n'; -import { BlockConfiguration } from '@wordpress/blocks'; -import { - InnerBlocks, -} from '@wordpress/block-editor'; -import { - blockTable as icon, -} from '@wordpress/icons'; - -/** - * Internal dependencies. - */ -import edit from './edit'; - -/** - * Block data. - */ -export const name: string = 'travelopia/table-row-container'; - -export const settings: BlockConfiguration = { - apiVersion: 3, - icon, - title: __( 'Row Container', 'tp' ), - description: __( 'A container for a row (THEAD, TBODY, TFOOT).', 'tp' ), - parent: [ 'travelopia/table' ], - category: 'text', - keywords: [ - __( 'thead', 'tp' ), - __( 'tbody', 'tp' ), - __( 'tfoot', 'tp' ), - ], - attributes: { - type: { - type: 'string', - default: 'tbody', - }, - isSticky: { - type: 'boolean', - default: false, - }, - blockId: { - type: 'string', - }, - }, - providesContext: { - 'travelopia/table-row-container-type': 'type' as never, - 'travelopia/table-row-container-sticky': 'isSticky' as never, - 'travelopia/table-row-container-id': 'blockId' as never, - }, - supports: { - html: false, - }, - edit, - save() { - return ; - }, -}; diff --git a/src/editor/blocks/table-row/index.tsx b/src/editor/blocks/table-row/index.tsx deleted file mode 100644 index 647ae96..0000000 --- a/src/editor/blocks/table-row/index.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/** - * WordPress dependencies. - */ -import { __ } from '@wordpress/i18n'; -import { BlockConfiguration } from '@wordpress/blocks'; -import { - InnerBlocks, -} from '@wordpress/block-editor'; -import { - blockTable as icon, -} from '@wordpress/icons'; - -/** - * Internal dependencies. - */ -import edit from './edit'; - -/** - * Block data. - */ -export const name: string = 'travelopia/table-row'; - -export const settings: BlockConfiguration = { - apiVersion: 3, - icon, - title: __( 'Row', 'tp' ), - description: __( 'Individual row of the table.', 'tp' ), - parent: [ 'travelopia/table-row-container' ], - category: 'text', - keywords: [ __( 'row', 'tp' ) ], - attributes: { - blockId: { - type: 'string', - }, - }, - usesContext: [ - 'travelopia/table-row-container-type', - ], - supports: { - html: true, - color: { - text: true, - background: true, - }, - // @ts-ignore - __experimentalBorder: { - color: true, - style: true, - width: true, - __experimentalDefaultControls: { - color: true, - style: true, - width: true, - }, - }, - }, - edit, - save() { - return ; - }, -}; diff --git a/src/editor/blocks/table/block.json b/src/editor/blocks/table/block.json new file mode 100644 index 0000000..4b16001 --- /dev/null +++ b/src/editor/blocks/table/block.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "travelopia/table", + "title": "Table", + "description": "Create structured content in rows and columns to display information.", + "category": "text", + "textdomain": "tp", + "supports": { + "anchor": true, + "className": true, + "customClassName": true, + "html": false, + "alignWide": false + }, + "providesContext": { + "travelopia/table-id": "blockId", + "travelopia/table-total-rows": "rows", + "travelopia/table-total-columns": "columns", + "travelopia/table-has-thead": "hasThead", + "travelopia/table-has-tfoot": "hasTfoot" + }, + "attributes": { + "anchor": { + "type": "string", + "default": "" + }, + "rows": { + "type": "number", + "default": 0 + }, + "columns": { + "type": "number", + "default": 0 + }, + "blockId": { + "type": "string", + "default": "" + }, + "hasThead": { + "type": "boolean", + "default": false + }, + "hasTfoot": { + "type": "boolean", + "default": false + } + } +} diff --git a/src/editor/blocks/table/children/cell/block.json b/src/editor/blocks/table/children/cell/block.json new file mode 100644 index 0000000..f4abd57 --- /dev/null +++ b/src/editor/blocks/table/children/cell/block.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "travelopia/table-cell", + "title": "Cell", + "description": "Individual cell of the table.", + "parent": ["travelopia/table-column"], + "category": "text", + "textdomain": "tp", + "keywords": ["cell", "table"], + "supports": { + "anchor": false, + "className": false, + "customClassName": false, + "html": true, + "alignWide": false + }, + "attributes": { + "content": { + "type": "string", + "source": "html" + } + } +} diff --git a/src/editor/blocks/table-cell/edit.tsx b/src/editor/blocks/table/children/cell/edit.tsx similarity index 83% rename from src/editor/blocks/table-cell/edit.tsx rename to src/editor/blocks/table/children/cell/edit.tsx index 3c03637..541e1bb 100644 --- a/src/editor/blocks/table-cell/edit.tsx +++ b/src/editor/blocks/table/children/cell/edit.tsx @@ -15,12 +15,14 @@ import { * * @return {JSX.Element} JSX Component. */ -function TableCellEdit( props: BlockEditProps ): JSX.Element { +export default function Edit( props: BlockEditProps ): JSX.Element { + // Destructure properties. const { attributes, setAttributes } = props; const blockProps = useBlockProps( { className: 'travelopia-table__cell', } ); + // Return cell content. return ( ): JSX.Element { /> ); } - -export default TableCellEdit; diff --git a/src/editor/blocks/table/children/cell/index.php b/src/editor/blocks/table/children/cell/index.php new file mode 100644 index 0000000..8c916bd --- /dev/null +++ b/src/editor/blocks/table/children/cell/index.php @@ -0,0 +1,18 @@ +> ) { + // Save content. + return ; +} diff --git a/src/editor/blocks/table/children/column/block.json b/src/editor/blocks/table/children/column/block.json new file mode 100644 index 0000000..b8f4de3 --- /dev/null +++ b/src/editor/blocks/table/children/column/block.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "travelopia/table-column", + "title": "Column", + "description": "Individual column of the table.", + "parent": ["travelopia/table-row"], + "category": "text", + "textdomain": "tp", + "keywords": ["column", "table"], + "supports": { + "html": true, + "color": { + "text": true, + "background": true + }, + "align": ["left", "center", "right"], + "__experimentalBorder": { + "color": true, + "style": true, + "width": true, + "__experimentalDefaultControls": { + "color": true, + "style": true, + "width": true + } + } + }, + "providesContext": { + "travelopia/table-row": "row", + "travelopia/table-column": "column", + "travelopia/table-column-id": "blockId" + }, + "usesContext": [ + "travelopia/table-row-container-type", + "travelopia/table-row-container-id" + ], + "attributes": { + "row": { + "type": "number" + }, + "column": { + "type": "number" + }, + "colSpan": { + "type": "number" + }, + "rowSpan": { + "type": "number" + }, + "isSticky": { + "type": "boolean" + }, + "blockId": { + "type": "string" + } + } +} diff --git a/src/editor/blocks/table-column/edit.tsx b/src/editor/blocks/table/children/column/edit.tsx similarity index 83% rename from src/editor/blocks/table-column/edit.tsx rename to src/editor/blocks/table/children/column/edit.tsx index f8a77fa..3812728 100644 --- a/src/editor/blocks/table-column/edit.tsx +++ b/src/editor/blocks/table/children/column/edit.tsx @@ -1,6 +1,7 @@ /** * WordPress dependencies. */ +import { __ } from '@wordpress/i18n'; import { useBlockProps, useInnerBlocksProps, @@ -10,6 +11,7 @@ import { import { useEffect } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { BlockEditProps } from '@wordpress/blocks'; +import { PanelBody, ToggleControl } from '@wordpress/components'; /** * External dependencies. @@ -19,10 +21,7 @@ import classnames from 'classnames'; /** * Internal dependencies. */ -import Toolbar from './toolbar'; -import { name as cellBlockName } from '../table-cell'; -import { PanelBody, ToggleControl } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { name as cellBlockName } from '../cell'; /** * Edit function. @@ -32,29 +31,28 @@ import { __ } from '@wordpress/i18n'; * @param {string} props.clientId Client ID. * @param {Object} props.attributes Attributes. * @param {Function} props.setAttributes Set attributes. - * @param {boolean} props.isSelected Is block selected. * @param {Object} props.context Block context. * * @return {JSX.Element} JSX Component. */ -function TableColumnEdit( { +export default function Edit( { className, clientId, attributes, setAttributes, - isSelected, context, }: BlockEditProps ): JSX.Element { + // Get block props. const blockProps = useBlockProps( { className: classnames( className, 'travelopia-table__column', { 'travelopia-table__column--sticky': attributes.isSticky, } ), } ); - const tableId: string = context[ 'travelopia/table-id' ] as string; + // Get context. const rowContainerType: string = context[ 'travelopia/table-row-container-type' ] as string; - const rowContainerId: string = context[ 'travelopia/table-row-container-id' ] as string; + // Get inner blocks props. const innerBlocksProps = useInnerBlocksProps( { ...blockProps, @@ -76,6 +74,7 @@ function TableColumnEdit( { select( blockEditorStore ).getBlockRootClientId( clientId ); const rowIndex = select( blockEditorStore ).getBlockIndex( rowClientId ); + // Return the row and column index. return { row: rowIndex + 1, // Start index at 1. column: columnIndex + 1, @@ -86,19 +85,25 @@ function TableColumnEdit( { // Update the row and column index. useEffect( () => { + // Set the row and column index. setAttributes( { row, column } ); }, [ row, column, setAttributes ] ); + // Set the block ID. useEffect( () => { + // Set the block ID. setAttributes( { blockId: clientId } ); }, [ clientId, setAttributes ] ); // Determine tag. let Tag: string = 'td'; + + // Check if the row container type is not tbody. if ( 'tbody' !== rowContainerType ) { Tag = 'th'; } + // Return the column block. return ( <> @@ -111,19 +116,9 @@ function TableColumnEdit( { /> - ); } - -export default TableColumnEdit; diff --git a/src/editor/blocks/table/children/column/index.php b/src/editor/blocks/table/children/column/index.php new file mode 100644 index 0000000..8f6a338 --- /dev/null +++ b/src/editor/blocks/table/children/column/index.php @@ -0,0 +1,64 @@ + __NAMESPACE__ . '\\render', + ] + ); +} + +/** + * Render this block. + * + * @param mixed[] $attributes The block attributes. + * @param string $content The block default content. + * + * @return string + */ +function render( array $attributes = [], string $content = '' ): string { + $border_styles = get_border_styles( $attributes ); + + // Get block attributes. + $column_attributes = get_block_wrapper_attributes( + [ + 'class' => get_css_classes( + $attributes, + [ + 'travelopia-table__column', + ! empty( $attributes['isSticky'] ) ? 'travelopia-table__column--sticky' : '', + $border_styles['css_classes'], + ] + ), + 'style' => get_css_styles( $attributes ) . $border_styles['inline_styles'], + 'colspan' => $attributes['colSpan'] ?? '', + 'rowspan' => $attributes['rowSpan'] ?? '', + ] + ); + + $html_tag = 'td'; + if ( ! empty( $attributes['type'] ) ) { + $html_tag = 'th'; + } + + return sprintf( '<%1$s %2$s>%3$s', $html_tag, wp_kses_data( $column_attributes ), $content ); +} diff --git a/src/editor/blocks/table/children/column/index.ts b/src/editor/blocks/table/children/column/index.ts new file mode 100644 index 0000000..d6b4977 --- /dev/null +++ b/src/editor/blocks/table/children/column/index.ts @@ -0,0 +1,26 @@ +/** + * WordPress dependencies. + */ +import { __ } from '@wordpress/i18n'; +import { BlockConfiguration } from '@wordpress/blocks'; +import { blockTable as icon } from '@wordpress/icons'; + +/** + * Internal dependencies. + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +/** + * Block name. + */ +export const { name }: { name: string } = metadata; + +// @ts-ignore Ignore BlockConfiguration type error for providesContext. +export const settings: BlockConfiguration = { + ...metadata, + icon, + edit, + save, +}; diff --git a/src/editor/blocks/table/children/column/save.tsx b/src/editor/blocks/table/children/column/save.tsx new file mode 100644 index 0000000..23bf612 --- /dev/null +++ b/src/editor/blocks/table/children/column/save.tsx @@ -0,0 +1,12 @@ +/** + * WordPress dependencies. + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +/** + * Save component. + */ +export default function Save() { + // Save inner content. + return ; +} diff --git a/src/editor/blocks/table/children/row-container/block.json b/src/editor/blocks/table/children/row-container/block.json new file mode 100644 index 0000000..93e0b96 --- /dev/null +++ b/src/editor/blocks/table/children/row-container/block.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "travelopia/table-row-container", + "title": "Row Container", + "description": "A container for a row (THEAD, TBODY, TFOOT).", + "parent": ["travelopia/table"], + "category": "text", + "textdomain": "tp", + "keywords": ["thead", "tbody", "tfoot", "table"], + "supports": { + "html": false + }, + "providesContext": { + "travelopia/table-row-container-type": "type", + "travelopia/table-row-container-sticky": "isSticky", + "travelopia/table-row-container-id": "blockId" + }, + "attributes": { + "type": { + "type": "string", + "default": "tbody" + }, + "isSticky": { + "type": "boolean", + "default": false + }, + "blockId": { + "type": "string" + } + } +} diff --git a/src/editor/blocks/table-row-container/edit.tsx b/src/editor/blocks/table/children/row-container/edit.tsx similarity index 90% rename from src/editor/blocks/table-row-container/edit.tsx rename to src/editor/blocks/table/children/row-container/edit.tsx index 2491011..fa30764 100644 --- a/src/editor/blocks/table-row-container/edit.tsx +++ b/src/editor/blocks/table/children/row-container/edit.tsx @@ -23,7 +23,7 @@ import classnames from 'classnames'; /** * Internal dependencies. */ -import { name as rowBlockName } from '../table-row'; +import { name as rowBlockName } from '../row'; import { useEffect } from '@wordpress/element'; /** @@ -33,7 +33,7 @@ import { useEffect } from '@wordpress/element'; * * @return {JSX.Element} JSX Component. */ -function TableRowContainerEdit( props: BlockEditProps ): JSX.Element { +export default function Edit( props: BlockEditProps ): JSX.Element { // Block props. const { className, attributes, setAttributes, clientId } = props; @@ -50,7 +50,9 @@ function TableRowContainerEdit( props: BlockEditProps ): JSX.Element { // Determine tag. const Tag: string = attributes.type; + // Set block id. useEffect( () => { + // Set block attributes. setAttributes( { blockId: clientId } ); }, [ clientId, setAttributes ] ); @@ -73,5 +75,3 @@ function TableRowContainerEdit( props: BlockEditProps ): JSX.Element { ); } - -export default TableRowContainerEdit; diff --git a/src/editor/blocks/table/children/row-container/index.php b/src/editor/blocks/table/children/row-container/index.php new file mode 100644 index 0000000..0836aeb --- /dev/null +++ b/src/editor/blocks/table/children/row-container/index.php @@ -0,0 +1,61 @@ + __NAMESPACE__ . '\\render', + ] + ); +} + +/** + * Render this block. + * + * @param mixed[] $attributes The block attributes. + * @param string $content The block default content. + * + * @return string + */ +function render( array $attributes = [], string $content = '' ): string { + // Get block attributes. + $block_attributes = get_block_wrapper_attributes( + [ + 'class' => get_css_classes( + $attributes, + [ + 'travelopia-table__row-container', + ! empty( $attributes['isSticky'] ) ? 'travelopia-table__row-container--sticky' : '', + ] + ), + ] + ); + + $html_tag = 'tbody'; + if ( ! empty( $attributes['type'] ) ) { + $html_tag = $attributes['type']; + } + + return sprintf( + '<%1$s %2$s>%3$s', + $html_tag, + wp_kses_data( $block_attributes ), + $content + ); +} diff --git a/src/editor/blocks/table/children/row-container/index.ts b/src/editor/blocks/table/children/row-container/index.ts new file mode 100644 index 0000000..d6b4977 --- /dev/null +++ b/src/editor/blocks/table/children/row-container/index.ts @@ -0,0 +1,26 @@ +/** + * WordPress dependencies. + */ +import { __ } from '@wordpress/i18n'; +import { BlockConfiguration } from '@wordpress/blocks'; +import { blockTable as icon } from '@wordpress/icons'; + +/** + * Internal dependencies. + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +/** + * Block name. + */ +export const { name }: { name: string } = metadata; + +// @ts-ignore Ignore BlockConfiguration type error for providesContext. +export const settings: BlockConfiguration = { + ...metadata, + icon, + edit, + save, +}; diff --git a/src/editor/blocks/table/children/row-container/save.tsx b/src/editor/blocks/table/children/row-container/save.tsx new file mode 100644 index 0000000..23bf612 --- /dev/null +++ b/src/editor/blocks/table/children/row-container/save.tsx @@ -0,0 +1,12 @@ +/** + * WordPress dependencies. + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +/** + * Save component. + */ +export default function Save() { + // Save inner content. + return ; +} diff --git a/src/editor/blocks/table/children/row/block.json b/src/editor/blocks/table/children/row/block.json new file mode 100644 index 0000000..27e1ee5 --- /dev/null +++ b/src/editor/blocks/table/children/row/block.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "travelopia/table-row", + "title": "Row", + "description": "Individual row of the table.", + "parent": ["travelopia/table-row-container"], + "category": "text", + "textdomain": "tp", + "keywords": ["row", "table"], + "supports": { + "html": true, + "color": { + "text": true, + "background": true + }, + "__experimentalBorder": { + "color": true, + "style": true, + "width": true, + "__experimentalDefaultControls": { + "color": true, + "style": true, + "width": true + } + } + }, + "usesContext": ["travelopia/table-row-container-type"], + "attributes": { + "blockId": { + "type": "string" + } + } +} diff --git a/src/editor/blocks/table-row/edit.tsx b/src/editor/blocks/table/children/row/edit.tsx similarity index 83% rename from src/editor/blocks/table-row/edit.tsx rename to src/editor/blocks/table/children/row/edit.tsx index f6e8f7f..e7c45f8 100644 --- a/src/editor/blocks/table-row/edit.tsx +++ b/src/editor/blocks/table/children/row/edit.tsx @@ -18,7 +18,7 @@ import classnames from 'classnames'; /** * Internal dependencies. */ -import { name as columnBlockName } from '../table-column'; +import { name as columnBlockName } from '../column'; import { useEffect } from '@wordpress/element'; /** @@ -28,7 +28,7 @@ import { useEffect } from '@wordpress/element'; * * @return {JSX.Element} JSX Component. */ -function TableRowEdit( props: BlockEditProps ): JSX.Element { +export default function Edit( props: BlockEditProps ): JSX.Element { // Block props. const { className, clientId, setAttributes } = props; @@ -41,13 +41,14 @@ function TableRowEdit( props: BlockEditProps ): JSX.Element { templateLock: false, } ); + // Set block id. useEffect( () => { + // Set block attributes. setAttributes( { blockId: clientId } ); }, [ clientId, setAttributes ] ); + // Return inner blocks. return ( ); } - -export default TableRowEdit; diff --git a/src/editor/blocks/table/children/row/index.php b/src/editor/blocks/table/children/row/index.php new file mode 100644 index 0000000..7419d3d --- /dev/null +++ b/src/editor/blocks/table/children/row/index.php @@ -0,0 +1,60 @@ + __NAMESPACE__ . '\\render', + ] + ); +} + +/** + * Render this block. + * + * @param mixed[] $attributes The block attributes. + * @param string $content The block default content. + * + * @return string + */ +function render( array $attributes = [], string $content = '' ): string { + $border_styles = get_border_styles( $attributes ); + + // Get block attributes. + $row_attributes = get_block_wrapper_attributes( + [ + 'class' => get_css_classes( + $attributes ?? [], + [ + 'travelopia-table__row ', + $border_styles['css_classes'], + ] + ), + 'style' => get_css_styles( $attributes ?? [] ) . $border_styles['inline_styles'], + ] + ); + + return sprintf( + '%2$s', + wp_kses_data( $row_attributes ), + $content + ); +} diff --git a/src/editor/blocks/table/children/row/index.ts b/src/editor/blocks/table/children/row/index.ts new file mode 100644 index 0000000..590389c --- /dev/null +++ b/src/editor/blocks/table/children/row/index.ts @@ -0,0 +1,28 @@ +/** + * WordPress dependencies. + */ +import { __ } from '@wordpress/i18n'; +import { BlockConfiguration } from '@wordpress/blocks'; +import { blockTable as icon } from '@wordpress/icons'; + +/** + * Internal dependencies. + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +/** + * Block name. + */ +export const { name }: { name: string } = metadata; + +/** + * Block settings. + */ +export const settings: BlockConfiguration = { + ...metadata, + icon, + edit, + save, +}; diff --git a/src/editor/blocks/table/children/row/save.tsx b/src/editor/blocks/table/children/row/save.tsx new file mode 100644 index 0000000..23bf612 --- /dev/null +++ b/src/editor/blocks/table/children/row/save.tsx @@ -0,0 +1,12 @@ +/** + * WordPress dependencies. + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +/** + * Save component. + */ +export default function Save() { + // Save inner content. + return ; +} diff --git a/src/editor/blocks/table/edit.tsx b/src/editor/blocks/table/edit.tsx index 49b9824..fb596bc 100644 --- a/src/editor/blocks/table/edit.tsx +++ b/src/editor/blocks/table/edit.tsx @@ -7,19 +7,10 @@ import { useBlockProps, useInnerBlocksProps, } from '@wordpress/block-editor'; -import { - BlockEditProps, - createBlock, -} from '@wordpress/blocks'; +import { BlockEditProps, createBlock } from '@wordpress/blocks'; import { useEffect } from '@wordpress/element'; -import { - PanelBody, - ToggleControl, -} from '@wordpress/components'; -import { - select, - dispatch, -} from '@wordpress/data'; +import { PanelBody, ToggleControl } from '@wordpress/components'; +import { select, dispatch } from '@wordpress/data'; /** * External dependencies. @@ -30,10 +21,10 @@ import classnames from 'classnames'; * Internal dependencies. */ import { TablePlaceholder } from './placeholder'; -import { name as rowContainerBlockName } from '../table-row-container'; -import { name as rowBlockName } from '../table-row'; -import { name as columnBlockName } from '../table-column'; -import { name as cellBlockName } from '../table-cell'; +import { name as rowContainerBlockName } from './children/row-container'; +import { name as rowBlockName } from './children/row'; +import { name as columnBlockName } from './children/column'; +import { name as cellBlockName } from './children/cell'; /** * Create and insert a row container. @@ -41,10 +32,16 @@ import { name as cellBlockName } from '../table-cell'; * @param {string} type Row container type. * @param {string} tableClientId The table block's client ID. */ -export const createAndInsertRowContainer = ( type: string = 'tbody', tableClientId: string = '' ): void => { +export const createAndInsertRowContainer = ( + type: string = 'tbody', + tableClientId: string = '', +): void => { // Get table block. const tableBlock = select( 'core/block-editor' ).getBlock( tableClientId ); + + // Return if table block is not found. if ( ! tableBlock ) { + // Exit early. return; } @@ -53,6 +50,8 @@ export const createAndInsertRowContainer = ( type: string = 'tbody', tableClient // Determine number of rows to create. let totalRows = tableBlock.attributes.rows; + + // Check if the type is not tbody. if ( 'tbody' !== type ) { totalRows = 1; } @@ -60,25 +59,32 @@ export const createAndInsertRowContainer = ( type: string = 'tbody', tableClient // Add rows and columns to it. for ( let i: number = 0; i < totalRows; i++ ) { const columnBlocks = []; + + // Loop through columns. for ( let j: number = 0; j < tableBlock.attributes.columns; j++ ) { columnBlocks.push( - createBlock( columnBlockName, {}, [ - createBlock( cellBlockName ), - ] ) + createBlock( columnBlockName, {}, [ createBlock( cellBlockName ) ] ), ); } + // Create row block. rowContainerBlock.innerBlocks.push( - createBlock( rowBlockName, {}, columnBlocks ) + createBlock( rowBlockName, {}, columnBlocks ), ); } // Add newly created row and column blocks to the table. if ( 'tbody' === type ) { - dispatch( 'core/block-editor' ).replaceInnerBlocks( tableClientId, [ rowContainerBlock ] ); + dispatch( 'core/block-editor' ).replaceInnerBlocks( tableClientId, [ + rowContainerBlock, + ] ); } else { const position = 'thead' === type ? 0 : tableBlock.innerBlocks.length; - dispatch( 'core/block-editor' ).insertBlock( rowContainerBlock, position, tableClientId ); + dispatch( 'core/block-editor' ).insertBlock( + rowContainerBlock, + position, + tableClientId, + ); } }; @@ -88,15 +94,22 @@ export const createAndInsertRowContainer = ( type: string = 'tbody', tableClient * @param {string} type Row container type. * @param {string} tableClientId The table block's client ID. */ -export const deleteRowContainer = ( type: string = 'thead', tableClientId: string = '' ): void => { +export const deleteRowContainer = ( + type: string = 'thead', + tableClientId: string = '', +): void => { // Get table block. const tableBlock = select( 'core/block-editor' ).getBlock( tableClientId ); + + // Return if table block is not found. if ( ! tableBlock || ! tableBlock.innerBlocks.length ) { + // Exit early. return; } // Find the child block and delete it. tableBlock.innerBlocks.forEach( ( innerBlock ) => { + // Check if the block type matches. if ( innerBlock.attributes?.type === type ) { dispatch( 'core/block-editor' ).removeBlock( innerBlock.clientId ); } @@ -110,18 +123,23 @@ export const deleteRowContainer = ( type: string = 'thead', tableClientId: strin * * @return {JSX.Element} JSX Component. */ -function TableEdit( props: BlockEditProps ): JSX.Element { +export default function Edit( props: BlockEditProps ): JSX.Element { + // Destructure properties. const { className, attributes, clientId, setAttributes } = props; const blockProps = useBlockProps( { className: classnames( className, 'travelopia-table' ), } ); - const innerBlocksProps = useInnerBlocksProps( {}, { - allowedBlocks: [ rowContainerBlockName ], - renderAppender: undefined, - } ); + const innerBlocksProps = useInnerBlocksProps( + {}, + { + allowedBlocks: [ rowContainerBlockName ], + renderAppender: undefined, + }, + ); // Set blockId attribute. useEffect( () => { + // Set blockId attribute. setAttributes( { blockId: clientId } ); }, [ clientId, setAttributes ] ); @@ -131,6 +149,7 @@ function TableEdit( props: BlockEditProps ): JSX.Element { * @param {boolean} hasThead Has THEAD. */ const handleTheadChange = ( hasThead: boolean ): void => { + // Create or delete THEAD row container. if ( hasThead ) { createAndInsertRowContainer( 'thead', clientId ); } else { @@ -145,6 +164,7 @@ function TableEdit( props: BlockEditProps ): JSX.Element { * @param {boolean} hasTfoot Has TFOOT. */ const handleTfootChange = ( hasTfoot: boolean ): void => { + // Create or delete TFOOT row container. if ( hasTfoot ) { createAndInsertRowContainer( 'tfoot', clientId ); } else { @@ -153,6 +173,7 @@ function TableEdit( props: BlockEditProps ): JSX.Element { setAttributes( { hasTfoot } ); }; + // Return the component. return ( <> @@ -174,16 +195,14 @@ function TableEdit( props: BlockEditProps ): JSX.Element {
{ /* Placeholder for initial state. */ - ( 0 === attributes.rows || 0 === attributes.columns ) && + ( 0 === attributes.rows || 0 === attributes.columns ) && ( + ) } - { - ( 0 !== attributes.rows || 0 !== attributes.columns ) && - - } + { ( 0 !== attributes.rows || 0 !== attributes.columns ) && ( +
+ ) } ); } - -export default TableEdit; diff --git a/src/editor/blocks/table/index.php b/src/editor/blocks/table/index.php new file mode 100644 index 0000000..1e4c175 --- /dev/null +++ b/src/editor/blocks/table/index.php @@ -0,0 +1,53 @@ + __NAMESPACE__ . '\\render', + ] + ); +} + +/** + * Render this block. + * + * @param mixed[] $attributes The block attributes. + * @param string $content The block default content. + * + * @return string + */ +function render( array $attributes = [], string $content = '' ): string { + // Enqueue table block styles. + wp_enqueue_style( 'travelopia-table' ); + + $table_attributes = get_block_wrapper_attributes( + [ + 'class' => get_css_classes( $attributes ), + 'style' => get_css_styles( $attributes ), + ] + ); + + return sprintf( + '
%2$s
', + wp_kses_data( $table_attributes ), + $content + ); +} diff --git a/src/editor/blocks/table/index.ts b/src/editor/blocks/table/index.ts new file mode 100644 index 0000000..e615be5 --- /dev/null +++ b/src/editor/blocks/table/index.ts @@ -0,0 +1,54 @@ +/** + * WordPress dependencies. + */ +import { __ } from '@wordpress/i18n'; +import { BlockConfiguration, registerBlockType } from '@wordpress/blocks'; +import { blockTable as icon } from '@wordpress/icons'; + +/** + * Internal dependencies. + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +/** + * Block name. + */ +export const { name }: { name: string } = metadata; + +/** + * Styles. + */ +import '../../../front-end/table/index.scss'; +import './editor.scss'; + +// @ts-ignore Ignore BlockConfiguration type error for providesContext. +export const settings: BlockConfiguration = { + ...metadata, + icon, + edit, + save, +}; + +/** + * Children blocks. + */ +import * as row from './children/row'; +import * as rowContainer from './children/row-container'; +import * as column from './children/column'; +import * as cell from './children/cell'; + +/** + * Initialization. + */ +export const init = (): void => { + // Register block. + registerBlockType( name, settings ); + + // Register children blocks. + registerBlockType( row.name, row.settings ); + registerBlockType( rowContainer.name, rowContainer.settings ); + registerBlockType( column.name, column.settings ); + registerBlockType( cell.name, cell.settings ); +}; diff --git a/src/editor/blocks/table/index.tsx b/src/editor/blocks/table/index.tsx deleted file mode 100644 index 33acb69..0000000 --- a/src/editor/blocks/table/index.tsx +++ /dev/null @@ -1,78 +0,0 @@ -/** - * WordPress dependencies. - */ -import { __ } from '@wordpress/i18n'; -import { BlockConfiguration } from '@wordpress/blocks'; -import { - InnerBlocks, -} from '@wordpress/block-editor'; -import { - blockTable as icon, -} from '@wordpress/icons'; - -/** - * Internal dependencies. - */ -import edit from './edit'; - -/** - * Styles. - */ -import './editor.scss'; - -/** - * Frontend styles. - */ -import '../../../front-end/table/index.scss'; - -/** - * Block data. - */ -export const name: string = 'travelopia/table'; - -export const settings: BlockConfiguration = { - apiVersion: 3, - icon, - title: __( 'Table', 'tp' ), - description: __( 'Create structured content in rows and columns to display information.', 'tp' ), - category: 'text', - keywords: [ __( 'table', 'tp' ) ], - attributes: { - anchor: { - type: 'string', - }, - rows: { - type: 'number', - default: 0, - }, - columns: { - type: 'number', - default: 0, - }, - blockId: { - type: 'string', - }, - hasThead: { - type: 'boolean', - default: false, - }, - hasTfoot: { - type: 'boolean', - default: false, - }, - }, - providesContext: { - 'travelopia/table-id': 'blockId' as never, - 'travelopia/table-total-rows': 'rows' as never, - 'travelopia/table-total-columns': 'columns' as never, - 'travelopia/table-has-thead': 'hasThead' as never, - 'travelopia/table-has-tfoot': 'hasTfoot' as never, - }, - supports: { - anchor: true, - }, - edit, - save() { - return ; - }, -}; diff --git a/src/editor/blocks/table/placeholder.tsx b/src/editor/blocks/table/placeholder.tsx index 4da53f8..bc9e079 100644 --- a/src/editor/blocks/table/placeholder.tsx +++ b/src/editor/blocks/table/placeholder.tsx @@ -27,10 +27,12 @@ import { createAndInsertRowContainer } from './edit'; * @return {JSX.Element} JSX Component. */ export function TablePlaceholder( props: BlockEditProps ): JSX.Element { + // Destructure properties. const { setAttributes, clientId } = props; const [ rows, setRows ] = useState( 2 ); const [ columns, setColumns ] = useState( 2 ); + // Return placeholder. return ( ; +} diff --git a/src/editor/blocks/table-column/toolbar.tsx b/src/editor/blocks/toolbar.tsx similarity index 62% rename from src/editor/blocks/table-column/toolbar.tsx rename to src/editor/blocks/toolbar.tsx index 8a64335..f7d433b 100644 --- a/src/editor/blocks/table-column/toolbar.tsx +++ b/src/editor/blocks/toolbar.tsx @@ -20,19 +20,15 @@ import { tableRowDelete, table, } from '@wordpress/icons'; -import { - useState, - useEffect, - useMemo, -} from '@wordpress/element'; +import { useState, useEffect, useMemo } from '@wordpress/element'; /** * Internal dependencies. */ -import { name as columnBlockName } from './index'; -import { name as rowBlockName } from '../table-row'; -import { name as cellBlockName } from '../table-cell'; -import { name as rowContainerBlockName } from '../table-row-container'; +import { name as columnBlockName } from './table/children/column'; +import { name as rowBlockName } from './table/children/row'; +import { name as cellBlockName } from './table/children/cell'; +import { name as rowContainerBlockName } from './table/children/row-container'; /** * Column block toolbar. @@ -62,28 +58,39 @@ export default function Toolbar( { rowContainerId: string; columnId: string; } ): JSX.Element { + // Get block editor select and dispatch. const { getBlock, canInsertBlockType, getBlockAttributes, - // @ts-ignore - canRemoveBlock, getAdjacentBlockClientId, + + // @ts-ignore - Property 'canRemoveBlock' does not exist on type 'Store'. + canRemoveBlock, } = select( 'core/block-editor' ); + // Get block editor dispatch. const { removeBlock, removeBlocks, insertBlock, updateBlockAttributes, - // @ts-ignore + + // @ts-ignore - Property 'moveBlocksToPosition' does not exist on type 'Store'. moveBlocksToPosition, } = dispatch( 'core/block-editor' ); - const [ maximumColumnsInCurrentRow, setMaximumColumnsInCurrentRow ] = useState( 0 ); - const [ maximumRowsInCurrentColumn, setMaximumRowsInCurrentColumn ] = useState( 0 ); + // State variables. + const [ maximumColumnsInCurrentRow, setMaximumColumnsInCurrentRow ] = + useState( 0 ); + const [ maximumRowsInCurrentColumn, setMaximumRowsInCurrentColumn ] = + useState( 0 ); - const rowContainerBlockType = useMemo( () => getBlock( rowContainerId )?.attributes?.type, [ rowContainerId, getBlock ] ); + // Get row container block type. + const rowContainerBlockType = useMemo( + () => getBlock( rowContainerId )?.attributes?.type, + [ rowContainerId, getBlock ], + ); /** * Set maximum columns in current row. @@ -95,18 +102,28 @@ export default function Toolbar( { // Check if we have a block. if ( ! tableBlock ) { setMaximumColumnsInCurrentRow( 0 ); + + // Exit early. return; } // Traverse table. tableBlock.innerBlocks.some( ( rowContainerBlock ): boolean => { - if ( rowContainerBlock.name !== rowContainerBlockName || ! rowContainerBlock.innerBlocks.length ) { + // Check if the block is a row container. + if ( + rowContainerBlock.name !== rowContainerBlockName || + ! rowContainerBlock.innerBlocks.length + ) { + // Continue loop. return false; } + // Traverse row container. let maxRows = 0; rowContainerBlock.innerBlocks.forEach( ( rowBlock, rowIndex ) => { + // Check if the block is a row. if ( rowBlock.name !== rowBlockName || ! rowBlock.innerBlocks.length ) { + // Continue loop. return; } @@ -115,16 +132,26 @@ export default function Toolbar( { setMaximumColumnsInCurrentRow( rowBlock.innerBlocks.length ); } + // Set maximum rows in current column. rowBlock.innerBlocks.forEach( ( columnBlock, columnIndex ) => { - if ( columnBlock.name !== columnBlockName || columnIndex + 1 !== tableColumn ) { + // Check if the block is a column. + if ( + columnBlock.name !== columnBlockName || + columnIndex + 1 !== tableColumn + ) { + // Continue loop. return; } + // Increment maximum rows. maxRows++; } ); } ); + // Set maximum rows in current column. setMaximumRowsInCurrentColumn( maxRows ); + + // Short-circuit loop. return true; } ); }, [ tableRow, tableColumn, getBlock, tableId ] ); @@ -140,11 +167,13 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } // Check if the row block can be inserted. if ( ! canInsertBlockType( rowBlockName, rowContainerId ) ) { + // Exit early. return; } @@ -179,6 +208,7 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } @@ -187,6 +217,7 @@ export default function Toolbar( { // Check if the row container block exists. if ( ! rowContainerBlock ) { + // Exit early. return; } @@ -198,6 +229,7 @@ export default function Toolbar( { ! currentRowBlock?.clientId || ! canRemoveBlock( currentRowBlock.clientId ) ) { + // Exit early. return; } @@ -221,6 +253,7 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } @@ -229,6 +262,7 @@ export default function Toolbar( { // Check if the row container block exists. if ( ! rowContainerBlock ) { + // Exit early. return; } @@ -236,6 +270,7 @@ export default function Toolbar( { tableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => { // Check the name of the row container block. if ( currentRowContainerBlock.name !== rowContainerBlockName ) { + // Continue loop. return; } @@ -243,11 +278,13 @@ export default function Toolbar( { currentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => { // Check the name of the row block. if ( rowBlock.name !== rowBlockName ) { + // Continue loop. return; } // Check if the column block can be inserted. if ( ! canInsertBlockType( columnBlockName, rowBlock.clientId ) ) { + // Continue loop. return; } @@ -257,7 +294,11 @@ export default function Toolbar( { ] ); // Insert the new column block. - insertBlock( newColumnBlock, tableColumn + insertionIndex, rowBlock.clientId ); + insertBlock( + newColumnBlock, + tableColumn + insertionIndex, + rowBlock.clientId, + ); } ); } ); @@ -276,6 +317,7 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } @@ -286,6 +328,7 @@ export default function Toolbar( { tableBlock.innerBlocks.forEach( ( currentRowContainerBlock ) => { // Check the name of the row container block. if ( currentRowContainerBlock.name !== rowContainerBlockName ) { + // Continue loop. return; } @@ -293,6 +336,7 @@ export default function Toolbar( { currentRowContainerBlock.innerBlocks.forEach( ( rowBlock ) => { // Check the name of the row block. if ( rowBlock.name !== rowBlockName ) { + // Continue loop. return; } @@ -327,21 +371,34 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } + // Get current column block. const currentBlock = getBlock( columnId ); + + // Check if the current column block exists. if ( ! currentBlock ) { + // Exit early. return; } + // Get previous block client ID. const previousBlockClientId = getAdjacentBlockClientId( columnId, -1 ); + + // Check if the previous block client ID exists. if ( ! previousBlockClientId ) { + // Exit early. return; } + // Previous block. const previousBlock = getBlock( previousBlockClientId ); + + // Check if the previous block exists. if ( ! previousBlock ) { + // Exit early. return; } @@ -358,20 +415,34 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } + // Get current column block. const currentBlock = getBlock( columnId ); + + // Check if the current column block exists. if ( ! currentBlock ) { + // Exit early. return; } + + // Get next block client ID. const nextBlockClientId = getAdjacentBlockClientId( columnId, 1 ); + + // Check if the next block client ID exists. if ( ! nextBlockClientId ) { + // Exit early. return; } + // Next block. const nextBlock = getBlock( nextBlockClientId ); + + // Check if the next block exists. if ( ! nextBlock ) { + // Exit early. return; } @@ -388,6 +459,7 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } @@ -396,6 +468,7 @@ export default function Toolbar( { // Check if the row container block exists. if ( ! rowContainerBlock ) { + // Exit early. return; } @@ -405,53 +478,80 @@ export default function Toolbar( { // Traverse rows. tableBlock.innerBlocks.some( ( currentRowContainerBlock ) => { + // Check if the row container block is the current row container block. if ( currentRowContainerBlock.name !== rowContainerBlockName ) { + // Continue loop. return false; } // Avoid merging thead/tfoot row with tbody row. - const currentRowContainerBlockAttributes = getBlockAttributes( currentRowContainerBlock.clientId ); - if ( currentRowContainerBlockAttributes?.type !== rowContainerBlock?.attributes?.type ) { + const currentRowContainerBlockAttributes = getBlockAttributes( + currentRowContainerBlock.clientId, + ); + + // Check if the row container block attributes are the same. + if ( + currentRowContainerBlockAttributes?.type !== + rowContainerBlock?.attributes?.type + ) { + // Continue loop. return false; } - return currentRowContainerBlock.innerBlocks.some( ( rowBlock, rowIndex ): boolean => { - // Get current row. - const rowNumber: number = rowIndex + 1; - if ( rowBlock.name !== rowBlockName || ( rowNumber !== tableRow && rowNumber !== tableRow - 1 ) || ! rowBlock.innerBlocks.length ) { - return false; - } - - // Traverse columns in current row. - rowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => { - // Get column to merge from and into. - const columnNumber: number = columnIndex + 1; - if ( columnNumber === tableColumn && rowNumber === tableRow ) { - columnToMergeFrom = columnBlock; - } else if ( columnNumber === tableColumn && rowNumber === tableRow - 1 ) { - columnToMergeInto = columnBlock; + // Loop through the row container blocks. + return currentRowContainerBlock.innerBlocks.some( + ( rowBlock, rowIndex ): boolean => { + // Get current row. + const rowNumber: number = rowIndex + 1; + + // Check if the row block is the current row block. + if ( + rowBlock.name !== rowBlockName || + ( rowNumber !== tableRow && rowNumber !== tableRow - 1 ) || + ! rowBlock.innerBlocks.length + ) { + // Continue loop. + return false; } - // Short circuit if we found them. - if ( columnToMergeInto && columnToMergeFrom ) { - return true; + // Traverse columns in current row. + rowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => { + // Get column to merge from and into. + const columnNumber: number = columnIndex + 1; + + // Check if the column block is the current column block. + if ( columnNumber === tableColumn && rowNumber === tableRow ) { + columnToMergeFrom = columnBlock; + } else if ( + columnNumber === tableColumn && + rowNumber === tableRow - 1 + ) { + columnToMergeInto = columnBlock; + } + + // Short circuit if we found them. + if ( columnToMergeInto && columnToMergeFrom ) { + // Exit early. + return true; + } + + // We haven't found them, loop some more. + return false; + } ); + + // Check if we have a "to" and "from" column. + if ( ! columnToMergeFrom || ! columnToMergeInto ) { + // Exit early. + return false; } - // We haven't found them, loop some more. - return false; - } ); - - // Check if we have a "to" and "from" column. - if ( ! columnToMergeFrom || ! columnToMergeInto ) { - return false; - } - - // Merge columns. - mergeColumnsVertically( columnToMergeFrom, columnToMergeInto ); + // Merge columns. + mergeColumnsVertically( columnToMergeFrom, columnToMergeInto ); - // Short-circuit loop. - return true; - } ); + // Short-circuit loop. + return true; + }, + ); } ); }; @@ -464,6 +564,7 @@ export default function Toolbar( { // Check if the table block exists. if ( ! tableBlock ) { + // Exit early. return; } @@ -472,6 +573,7 @@ export default function Toolbar( { // Check if the row container block exists. if ( ! rowContainerBlock ) { + // Exit early. return; } @@ -481,53 +583,80 @@ export default function Toolbar( { // Traverse rows. tableBlock.innerBlocks.some( ( currentRowContainerBlock ) => { + // Check if the row container block is the current row container block. if ( currentRowContainerBlock.name !== rowContainerBlockName ) { + // Continue loop. return false; } // Avoid merging thead/tfoot row with tbody row. - const currentRowContainerBlockAttributes = getBlockAttributes( currentRowContainerBlock.clientId ); - if ( currentRowContainerBlockAttributes?.type !== rowContainerBlock?.attributes?.type ) { + const currentRowContainerBlockAttributes = getBlockAttributes( + currentRowContainerBlock.clientId, + ); + + // Check if the row container block attributes are the same. + if ( + currentRowContainerBlockAttributes?.type !== + rowContainerBlock?.attributes?.type + ) { + // Continue loop. return false; } - return currentRowContainerBlock.innerBlocks.some( ( rowBlock, rowIndex ): boolean => { - // Get current row. - const rowNumber: number = rowIndex + 1; - if ( rowBlock.name !== rowBlockName || ( rowNumber !== tableRow && rowNumber !== tableRow + 1 ) || ! rowBlock.innerBlocks.length ) { - return false; - } - - // Traverse columns in current row. - rowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => { - // Get column to merge from and into. - const columnNumber: number = columnIndex + 1; - if ( columnNumber === tableColumn && rowNumber === tableRow ) { - columnToMergeInto = columnBlock; - } else if ( columnNumber === tableColumn && rowNumber === tableRow + 1 ) { - columnToMergeFrom = columnBlock; + // Loop through the row container blocks. + return currentRowContainerBlock.innerBlocks.some( + ( rowBlock, rowIndex ): boolean => { + // Get current row. + const rowNumber: number = rowIndex + 1; + + // Check if the row block is the current row block. + if ( + rowBlock.name !== rowBlockName || + ( rowNumber !== tableRow && rowNumber !== tableRow + 1 ) || + ! rowBlock.innerBlocks.length + ) { + // Continue loop. + return false; } - // Short circuit if we found them. - if ( columnToMergeInto && columnToMergeFrom ) { - return true; + // Traverse columns in current row. + rowBlock.innerBlocks.some( ( columnBlock, columnIndex ): boolean => { + // Get column to merge from and into. + const columnNumber: number = columnIndex + 1; + + // Check if the column block is the current column block. + if ( columnNumber === tableColumn && rowNumber === tableRow ) { + columnToMergeInto = columnBlock; + } else if ( + columnNumber === tableColumn && + rowNumber === tableRow + 1 + ) { + columnToMergeFrom = columnBlock; + } + + // Short circuit if we found them. + if ( columnToMergeInto && columnToMergeFrom ) { + // Exit early. + return true; + } + + // We haven't found them, loop some more. + return false; + } ); + + // Check if we have a "to" and "from" column. + if ( ! columnToMergeFrom || ! columnToMergeInto ) { + // Exit early. + return false; } - // We haven't found them, loop some more. - return false; - } ); - - // Check if we have a "to" and "from" column. - if ( ! columnToMergeFrom || ! columnToMergeInto ) { - return false; - } + // Merge columns. + mergeColumnsVertically( columnToMergeFrom, columnToMergeInto ); - // Merge columns. - mergeColumnsVertically( columnToMergeFrom, columnToMergeInto ); - - // Short-circuit loop. - return true; - } ); + // Short-circuit loop. + return true; + }, + ); } ); }; @@ -537,31 +666,46 @@ export default function Toolbar( { * @param {Object} fromColumn From column block instance. * @param {Object} toColumn To column block instance. */ - const mergeColumnsHorizontally = ( fromColumn: BlockInstance, toColumn: BlockInstance ): void => { + const mergeColumnsHorizontally = ( + fromColumn: BlockInstance, + toColumn: BlockInstance, + ): void => { // Get colspans. const mergeIntoAttributes = getBlockAttributes( toColumn.clientId ); const mergeFromAttributes = getBlockAttributes( fromColumn.clientId ); // Get rowspans. - const mergeIntoRowspan: number = parseInt( mergeIntoAttributes?.rowSpan ?? 1 ); - const mergeFromRowspan: number = parseInt( mergeFromAttributes?.rowSpan ?? 1 ); + const mergeIntoRowspan: number = parseInt( + mergeIntoAttributes?.rowSpan ?? 1, + ); + const mergeFromRowspan: number = parseInt( + mergeFromAttributes?.rowSpan ?? 1, + ); // Invalid merge. if ( mergeIntoRowspan !== mergeFromRowspan ) { + // Exit early. return; } - const mergeIntoColspan: number = parseInt( mergeIntoAttributes?.colSpan ?? 1 ); - const mergeFromColspan: number = parseInt( mergeFromAttributes?.colSpan ?? 1 ); + // Get colspans. + const mergeIntoColspan: number = parseInt( + mergeIntoAttributes?.colSpan ?? 1, + ); + const mergeFromColspan: number = parseInt( + mergeFromAttributes?.colSpan ?? 1, + ); // Update colspan. - updateBlockAttributes( toColumn.clientId, { colSpan: mergeIntoColspan + mergeFromColspan } ); + updateBlockAttributes( toColumn.clientId, { + colSpan: mergeIntoColspan + mergeFromColspan, + } ); // If it is the current column, move children to previous column and delete current column. moveBlocksToPosition( fromColumn.innerBlocks.map( ( block ) => block.clientId ), fromColumn.clientId, - toColumn.clientId + toColumn.clientId, ); // Remove block that is being merged from. @@ -574,31 +718,46 @@ export default function Toolbar( { * @param {Object} fromColumn From column block instance. * @param {Object} toColumn To column block instance. */ - const mergeColumnsVertically = ( fromColumn: BlockInstance, toColumn: BlockInstance ): void => { + const mergeColumnsVertically = ( + fromColumn: BlockInstance, + toColumn: BlockInstance, + ): void => { // Get rowspans. const mergeIntoAttributes = getBlockAttributes( toColumn.clientId ); const mergeFromAttributes = getBlockAttributes( fromColumn.clientId ); // Get colspans. - const mergeIntoColspan: number = parseInt( mergeIntoAttributes?.colSpan ?? 1 ); - const mergeFromColspan: number = parseInt( mergeFromAttributes?.colSpan ?? 1 ); + const mergeIntoColspan: number = parseInt( + mergeIntoAttributes?.colSpan ?? 1, + ); + const mergeFromColspan: number = parseInt( + mergeFromAttributes?.colSpan ?? 1, + ); // Invalid merge. if ( mergeIntoColspan !== mergeFromColspan ) { + // Exit early. return; } - const mergeIntoRowspan: number = parseInt( mergeIntoAttributes?.rowSpan ?? 1 ); - const mergeFromRowspan: number = parseInt( mergeFromAttributes?.rowSpan ?? 1 ); + // Get rowspans. + const mergeIntoRowspan: number = parseInt( + mergeIntoAttributes?.rowSpan ?? 1, + ); + const mergeFromRowspan: number = parseInt( + mergeFromAttributes?.rowSpan ?? 1, + ); // Update rowspan. - updateBlockAttributes( toColumn.clientId, { rowSpan: mergeIntoRowspan + mergeFromRowspan } ); + updateBlockAttributes( toColumn.clientId, { + rowSpan: mergeIntoRowspan + mergeFromRowspan, + } ); // If it is the current column, move children to previous column and delete current column. moveBlocksToPosition( fromColumn.innerBlocks.map( ( block ) => block.clientId ), fromColumn.clientId, - toColumn.clientId + toColumn.clientId, ); // Remove block that is being merged from. @@ -612,19 +771,28 @@ export default function Toolbar( { { icon: tableRowBefore, title: __( 'Insert row before', 'tp' ), - isDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ), + isDisabled: + ! isSelected || + rowContainerBlockType === 'tfoot' || + rowContainerBlockType === 'thead', onClick: () => onInsertRow( -1 ), }, { icon: tableRowAfter, title: __( 'Insert row after', 'tp' ), - isDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ), + isDisabled: + ! isSelected || + rowContainerBlockType === 'tfoot' || + rowContainerBlockType === 'thead', onClick: onInsertRow, }, { icon: tableRowDelete, title: __( 'Delete row', 'tp' ), - isDisabled: ( ! isSelected || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ), + isDisabled: + ! isSelected || + rowContainerBlockType === 'tfoot' || + rowContainerBlockType === 'thead', onClick: onDeleteRow, }, { @@ -660,13 +828,19 @@ export default function Toolbar( { { icon: arrowUp, title: __( 'Merge column up', 'tp' ), - isDisabled: ( tableRow < 2 || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ), + isDisabled: + tableRow < 2 || + rowContainerBlockType === 'tfoot' || + rowContainerBlockType === 'thead', onClick: onMergeColumnUp, }, { icon: arrowDown, title: __( 'Merge column down', 'tp' ), - isDisabled: ( tableRow === maximumRowsInCurrentColumn || rowContainerBlockType === 'tfoot' || rowContainerBlockType === 'thead' ), + isDisabled: + tableRow === maximumRowsInCurrentColumn || + rowContainerBlockType === 'tfoot' || + rowContainerBlockType === 'thead', onClick: onMergeColumnDown, }, ] as DropdownOption[]; diff --git a/tsconfig.json b/tsconfig.json index 46cf6c1..3385296 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "allowJs": true, "moduleResolution": "node", "sourceMap": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, }, "include": ["src/**/*"] } diff --git a/webpack.config.js b/webpack.config.js index e24ceaa..22568db 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,11 +1,13 @@ /** - * Quark Expeditions Webpack Config. + * External dependencies. */ - -// External dependencies. -const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); -const WebpackNotifierPlugin = require( 'webpack-notifier' ); +const path = require( 'path' ); +const fg = require( 'fast-glob' ); +const { exec } = require( 'child_process' ); const TerserPlugin = require( 'terser-webpack-plugin' ); +const WebpackNotifierPlugin = require( 'webpack-notifier' ); +const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); +const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' ); const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' ); // Config. @@ -69,10 +71,59 @@ module.exports = ( env ) => { } ) ], }, plugins: [ + new RemoveEmptyScriptsPlugin(), new MiniCssExtractPlugin( { filename: `./dist/editor/[name].css`, } ), new DependencyExtractionWebpackPlugin( {} ), + { + apply: ( compiler ) => { + /** + * After compile, add PHP files to dependencies. + * @see . + */ + compiler.hooks.afterCompile.tap( 'BlocksManifestPlugin', ( compilation ) => { + // Get PHP files from blocks. + const phpFiles = fg.sync( path.resolve( __dirname, '/src/editor/blocks/**/*.php' ) ); + + // Add PHP files to dependencies. + if ( Array.isArray( compilation.fileDependencies ) ) { + phpFiles.map( ( file ) => compilation.fileDependencies.push( file ) ); + } else { + phpFiles.map( ( file ) => compilation.fileDependencies.add( file ) ); + } + } ); + + // After emit, generate blocks manifest. + compiler.hooks.afterEmit.tap( 'BlocksManifestPlugin', async () => { + // Get PHP script to generate blocks manifest. + const blocksInfoExtractor = path.resolve( __dirname, '.bin/block-manifest-generator.php' ); + + // Run PHP script. + exec( `php ${ blocksInfoExtractor }`, ( error, stdout, stderr ) => { + // If there is an error. + if ( error ) { + // eslint-disable-next-line no-console + console.error( `[BlocksManifestPlugin] \n ${ error }` ); + + // Just return. + return; + } + + // If there is an error. + if ( stderr ) { + // eslint-disable-next-line no-console + console.error( `[BlocksManifestPlugin] \n ${ stderr }` ); + // Just return. + return; + } + + // eslint-disable-next-line no-console + console.log( `[BlocksManifestPlugin] \n ${ stdout }` ); + } ); + } ); + }, + }, ], performance: { hints: false,