Skip to content

Commit

Permalink
Merge pull request #168 from t-hamano/v3.0.1
Browse files Browse the repository at this point in the history
V3.0.1
  • Loading branch information
t-hamano authored Aug 26, 2023
2 parents ae6da7f + 2480506 commit de5b533
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 116 deletions.
2 changes: 1 addition & 1 deletion flexible-table-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Description: Easily create flexible configuration tables.
* Requires at least: 6.1
* Requires PHP: 7.4
* Version: 3.0.0
* Version: 3.0.1
* Author: Aki Hamano
* Author URI: https://github.com/t-hamano
* License: GPL2 or later
Expand Down
7 changes: 6 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tags: gutenberg, block, table
Donate link: https://www.paypal.me/thamanoJP
Requires at least: 6.1
Tested up to: 6.3
Stable tag: 3.0.0
Stable tag: 3.0.1
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -42,6 +42,11 @@ The breakpoints for switching between Desktop and mobile can be changed freely.

== Changelog ==

= 3.0.1 =
* Fix: Keyboard controls don't work within the link control popover
* Fix: Tab key focus doesn't work when cell text contains footnote links
* Enhancement: Release cell selection when the block is unselected

= 3.0.0 =
* Tested to WordPress 6.3
* Fix: Missing top border in the block sidebar
Expand Down
26 changes: 21 additions & 5 deletions src/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Properties } from 'csstype';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { useEffect, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { InspectorControls, BlockControls, useBlockProps } from '@wordpress/block-editor';
import {
Expand Down Expand Up @@ -77,6 +77,14 @@ function TableEdit( props: BlockEditProps< BlockAttributes > ) {
[]
);

// Release cell selection.
useEffect( () => {
if ( ! isSelected ) {
setSelectedCells( undefined );
setSelectedLine( undefined );
}
}, [ isSelected ] );

// Create virtual table object with the cells placed in positions based on how they actually look.
const vTable: VTable = toVirtualTable( attributes );

Expand All @@ -86,7 +94,9 @@ function TableEdit( props: BlockEditProps< BlockAttributes > ) {
};

const onInsertRow = ( offset: number ) => {
if ( ! selectedCells || selectedCells.length !== 1 ) return;
if ( ! selectedCells || selectedCells.length !== 1 ) {
return;
}

const { sectionName, rowIndex, rowSpan } = selectedCells[ 0 ];

Expand All @@ -101,7 +111,9 @@ function TableEdit( props: BlockEditProps< BlockAttributes > ) {
};

const onDeleteRow = () => {
if ( ! selectedCells || selectedCells.length !== 1 ) return;
if ( ! selectedCells || selectedCells.length !== 1 ) {
return;
}

const { sectionName, rowIndex } = selectedCells[ 0 ];

Expand All @@ -123,7 +135,9 @@ function TableEdit( props: BlockEditProps< BlockAttributes > ) {
};

const onInsertColumn = ( offset: number ) => {
if ( ! selectedCells || selectedCells.length !== 1 ) return;
if ( ! selectedCells || selectedCells.length !== 1 ) {
return;
}

const { vColIndex, colSpan } = selectedCells[ 0 ];

Expand All @@ -138,7 +152,9 @@ function TableEdit( props: BlockEditProps< BlockAttributes > ) {
};

const onDeleteColumn = () => {
if ( ! selectedCells || selectedCells.length !== 1 ) return;
if ( ! selectedCells || selectedCells.length !== 1 ) {
return;
}

const { vColIndex } = selectedCells[ 0 ];

Expand Down
4 changes: 3 additions & 1 deletion src/elements/table-placeholder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export default function TablePlaceholder( { setAttributes }: Props ) {
const onCreateTable = ( event: FormEvent ) => {
event.preventDefault();

if ( ! rowCount || ! colCount ) return;
if ( ! rowCount || ! colCount ) {
return;
}

const vTable: VTable = createTable( {
rowCount: Math.min( rowCount, MAX_PREVIEW_TABLE_ROW ),
Expand Down
150 changes: 85 additions & 65 deletions src/elements/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,7 @@ import {
import { convertToObject } from '../utils/style-converter';

import type { SectionName, CellTagValue, BlockAttributes } from '../BlockAttributes';
import type {
VTable,
VCell,
VRow,
VSelectMode,
VSelectedLine,
VSelectedCells,
} from '../utils/table-state';
import type { VTable, VCell, VRow, VSelectedLine, VSelectedCells } from '../utils/table-state';
import type { StoreOptions } from '../store';

function TSection( props: any ) {
Expand Down Expand Up @@ -86,7 +79,7 @@ export default function Table( {

const colorProps = useColorProps( attributes );

const [ selectMode, setSelectMode ] = useState< VSelectMode >( undefined );
const [ isSelectMode, setIsSelectMode ] = useState< boolean >( false );

// Manage rendering status as state since some processing may be performed before rendering components.
const [ isReady, setIdReady ] = useState< boolean >( false );
Expand Down Expand Up @@ -197,7 +190,9 @@ export default function Table( {
const onChangeCellContent = ( content: string, targetCell: VCell ) => {
// If inline highlight is applied to the RichText, this process is performed before rendering the component, causing a warning error.
// Therefore, nothing is performed if the component has not yet been rendered.
if ( ! isReady ) return;
if ( ! isReady ) {
return;
}

const { sectionName, rowIndex: selectedRowIndex, vColIndex: selectedVColIndex } = targetCell;
setSelectedCells( [ { ...targetCell, isFirstSelected: true } ] );
Expand Down Expand Up @@ -229,78 +224,109 @@ export default function Table( {
const onKeyDown = ( event: KeyboardEvent ) => {
const { key } = event;

if ( key === 'Shift' ) {
// range-select mode.
setSelectMode( 'range' );
} else if ( key === 'Control' || key === 'Meta' ) {
// multi-select mode.
setSelectMode( 'multi' );
if ( key === 'Shift' || key === 'Control' || key === 'Meta' ) {
// range-select mode or multi-select mode.
setIsSelectMode( true );
} else if ( key === 'Tab' && options.tab_move && tableRef.current ) {
// Focus on the next cell.
isTabMove = true;

const tableElement: HTMLElement = tableRef.current;
const activeElement = tableElement.querySelector(
'th.is-selected [contenteditable], td.is-selected [contenteditable]'
const { ownerDocument } = tableElement;
const { activeElement } = ownerDocument;

const activeCell = tableElement.querySelector(
'th.is-selected > [contenteditable="true"], td.is-selected > [contenteditable="true"]'
);
const isInsidePopover =
activeElement && activeElement.closest( '.components-popover' ) !== null;
const hasLinkControl = !! ownerDocument.querySelector( '.block-editor-link-control' );

if ( ! activeCell || isInsidePopover || hasLinkControl ) {
return;
}

if ( ! activeElement ) return;
const tabbableNodes = tableElement.querySelectorAll(
'th > [contenteditable="true"], td > [contenteditable="true"]'
);

const tabbableNodes = tableElement.querySelectorAll( '[contenteditable]' );
const tabbableElements = [].slice.call( tabbableNodes );
const activeIndex = tabbableElements.findIndex(
( element: Node ) => element === activeElement
const activeCellIndex = tabbableElements.findIndex(
( element: Node ) => element === activeCell
);

if ( activeIndex === -1 ) return;
if ( activeCellIndex === -1 ) {
return;
}

let nextIndex = event.shiftKey ? activeIndex - 1 : activeIndex + 1;
let nextCellIndex = event.shiftKey ? activeCellIndex - 1 : activeCellIndex + 1;

if ( nextIndex < 0 ) {
nextIndex = tabbableElements.length - 1;
} else if ( nextIndex >= tabbableElements.length ) {
nextIndex = 0;
if ( nextCellIndex < 0 ) {
nextCellIndex = tabbableElements.length - 1;
} else if ( nextCellIndex >= tabbableElements.length ) {
nextCellIndex = 0;
}

const focusbleElement: HTMLElement = tabbableElements[ nextIndex ];
const { ownerDocument } = tableElement;
const focusbleElement: HTMLElement = tabbableElements[ nextCellIndex ];

if ( ! focusbleElement ) {
return;
}

if ( focusbleElement ) {
event.preventDefault();
setSelectMode( undefined );
focusbleElement.focus();
event.preventDefault();
setIsSelectMode( false );
focusbleElement.focus();

// Select all text if the next cell is not empty.
const selection = ownerDocument.getSelection();
const range = ownerDocument.createRange();
// Select all text if the next cell is not empty.
const selection = ownerDocument.getSelection();
const range = ownerDocument.createRange();

if ( selection && focusbleElement.innerText.trim().length ) {
range.selectNodeContents( focusbleElement );
selection.removeAllRanges();
selection.addRange( range );
}
if ( selection && focusbleElement.innerText.trim().length ) {
range.selectNodeContents( focusbleElement );
selection.removeAllRanges();
selection.addRange( range );
}
}
};

const onKeyUp = ( event: KeyboardEvent ) => {
const { key } = event;

if ( key === 'Shift' || key === 'Control' || key === 'Meta' ) {
setSelectMode( undefined );
const targetElement = event.target as HTMLElement;
const isInsideTableBlock =
targetElement.closest( '.wp-block-flexible-table-block-table' ) !== null;

if ( ! isInsideTableBlock ) {
return;
}

setIsSelectMode( false );
}
};

const onClickCell = ( event: MouseEvent, clickedCell: VCell ) => {
const { shiftKey, ctrlKey, metaKey } = event;
const clickedElement = event.target as HTMLElement;
const isInsideTableBlock =
clickedElement.closest( '.wp-block-flexible-table-block-table' ) !== null;

if ( ! isInsideTableBlock ) {
return;
}

const { sectionName, rowIndex, vColIndex } = clickedCell;

if ( event.shiftKey ) {
if ( shiftKey ) {
// Range select.
if ( ! selectedCells ) {
setSelectedCells( [ { ...clickedCell, isFirstSelected: true } ] );
} else {
const fromCell = selectedCells.find( ( { isFirstSelected } ) => isFirstSelected );

if ( ! fromCell ) return;
if ( ! fromCell ) {
return;
}

if ( fromCell.sectionName !== sectionName ) {
// eslint-disable-next-line no-alert, no-undef
Expand All @@ -311,7 +337,7 @@ export default function Table( {
}
setSelectedCells( toRectangledSelectedCells( vTable, { fromCell, toCell: clickedCell } ) );
}
} else if ( event.ctrlKey || event.metaKey ) {
} else if ( ctrlKey || metaKey ) {
// Multple select.
const newSelectedCells = selectedCells ? [ ...selectedCells ] : [];
const existCellIndex = newSelectedCells.findIndex( ( cell ) => {
Expand Down Expand Up @@ -403,25 +429,19 @@ export default function Table( {
// Use only onFocus.
const useOnFocus = !! window?.ftbObj?.useOnFocus;

const focusProp = useOnFocus
? {
onFocus: () => {
if ( ! selectMode || isTabMove ) {
isTabMove = false;
setSelectedLine( undefined );
setSelectedCells( [ { ...cell, isFirstSelected: true } ] );
}
},
}
: {
unstableOnFocus: () => {
if ( ! selectMode || isTabMove ) {
isTabMove = false;
setSelectedLine( undefined );
setSelectedCells( [ { ...cell, isFirstSelected: true } ] );
}
},
};
const focusEvent = () => {
isTabMove = false;
setSelectedLine( undefined );
setSelectedCells( [ { ...cell, isFirstSelected: true } ] );
};

const focusProp =
! isSelectMode || isTabMove
? {
...( useOnFocus && { onFocus: focusEvent } ),
...( ! useOnFocus && { unstableOnFocus: focusEvent } ),
}
: {};

return (
<Cell
Expand Down
8 changes: 6 additions & 2 deletions src/settings/global-settings/setting-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ export default function SettingModal( { options, isAdministrator, setIsSettingMo
} );
}

if ( ! response.block_css ) return;
if ( ! response.block_css ) {
return;
}

// Update inline CSS.
updateInlineCss( response.block_css );
Expand Down Expand Up @@ -171,7 +173,9 @@ export default function SettingModal( { options, isAdministrator, setIsSettingMo
setStoreOptions( response.options );
}

if ( ! response.block_css ) return;
if ( ! response.block_css ) {
return;
}

// Update inline CSS.
updateInlineCss( response.block_css );
Expand Down
3 changes: 0 additions & 3 deletions src/utils/table-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ export type VSelectedLine =
// Virtual table selected cells state
export type VSelectedCells = VCell[] | undefined;

// Determine whether multi-select mode or range select mode
export type VSelectMode = 'range' | 'multi' | undefined;

// Minimum / maximum row / column virtual indexes on virtual table
interface VRangeIndexes {
minRowIndex: number;
Expand Down
19 changes: 19 additions & 0 deletions test/e2e/specs/__snapshots__/table-cell.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Flexible table cell allows cell movement with tab key. 1`] = `
"<!-- wp:flexible-table-block/table -->
<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>Cell 1</td><td>Cell 2</td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></tbody></table></figure>
<!-- /wp:flexible-table-block/table -->"
`;

exports[`Flexible table cell allows keyboard operation within the link popover 1`] = `
"<!-- wp:flexible-table-block/table -->
<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td><a href="#anchor">Link</a></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></tbody></table></figure>
<!-- /wp:flexible-table-block/table -->"
`;

exports[`Flexible table cell allows keyboard operation within the link popover 2`] = `
"<!-- wp:flexible-table-block/table -->
<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td><a href="#anchor-updated" target="_blank" rel="noreferrer noopener">Link-updated</a></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></tbody></table></figure>
<!-- /wp:flexible-table-block/table -->"
`;
6 changes: 0 additions & 6 deletions test/e2e/specs/__snapshots__/table.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,3 @@ exports[`Flexible table should create block with option 1`] = `
<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr></tbody><tfoot><tr><td></td><td></td><td></td><td></td></tr></tfoot></table></figure>
<!-- /wp:flexible-table-block/table -->"
`;

exports[`Flexible table should move cells with the TAB key. 1`] = `
"<!-- wp:flexible-table-block/table -->
<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>Cell 1</td><td>Cell 2</td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></tbody></table></figure>
<!-- /wp:flexible-table-block/table -->"
`;
Loading

0 comments on commit de5b533

Please sign in to comment.