Select Git revision
FlexibleTable.jsx
FlexibleTable.jsx 11.61 KiB
import {__} from '@wordpress/i18n';
import {InspectorControls, useBlockProps,} from '@wordpress/block-editor';
import {PanelBody, ToggleControl} from '@wordpress/components';
import {DragDropContext, Draggable, Droppable} from "@hello-pangea/dnd";
import {DuoInput, NumberWithUnit, ColorSelector, FontStyles, AlignButtons, BlockPlaceholders} from "../../index";
import TableBody from "./TableBody";
import TableHead from "./TableHead";
export default function FlexibleTable({
attributes,
setAttributes,
placeholders,
additionalOptions,
tableHeader,
tableBody,
tableFooter,
}) {
const {
headers,
rows,
states,
headerBackground,
headerTextColor,
headerTextAlign,
headerFontWeight,
headerFontStyle,
headerTextDecoration,
headerFontSize,
tableBorderColor,
tableBorderWidth,
bodyBorderColumnColor,
bodyBorderColumnWidthLeft,
bodyBorderColumnWidthRight,
bodyBorderRowColor,
bodyBorderRowWidthTop,
bodyBorderRowWidthBottom,
headerBorderColumnColor,
headerBorderColumnWidthLeft,
headerBorderColumnWidthRight,
headerBorderRowColor,
headerBorderRowWidthTop,
headerBorderRowWidthBottom,
bodyBackground,
multipleBodyBackground,
bodyBackgroundEven,
bodyTextColorEven,
bodyTextColor,
bodyTextAlign,
bodyFontWeight,
bodyFontStyle,
bodyTextDecoration,
bodyFontSize,
} = attributes;
const blockProps = useBlockProps();
const handleMultipleAttributesChange = (newValues) => {
setAttributes({...attributes, ...newValues});
}
const updateHeader = (index, value) => {
const newHeaders = [...headers];
newHeaders[index] = value;
setAttributes({headers: newHeaders});
};
const updateCell = (index, value) => {
const newRows = [...rows];
newRows[index] = value;
setAttributes({rows: newRows});
};
const toggleColumn = (index, value) => {
const newStates = [...states];
newStates[index] = value;
setAttributes({states: newStates});
};
const handleDragEnd = (result) => {
if (!result.destination) {
return;
}
const {source, destination} = result;
const newHeaders = [...headers];
const newStates = [...states];
const newRows = [...rows];
const [movedHeader] = newHeaders.splice(source.index, 1);
newHeaders.splice(destination.index, 0, movedHeader);
const [movedState] = newStates.splice(source.index, 1);
newStates.splice(destination.index, 0, movedState);
const [movedRow] = newRows.splice(source.index, 1);
newRows.splice(destination.index, 0, movedRow);
setAttributes({
headers: newHeaders,
states: newStates,
rows: newRows
});
};
return (
<>
<InspectorControls>
<PanelBody title={__("Table columns", "flexible-invoices-core")}>
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId="table-columns">
{(provided) => (
<ul
{...provided.droppableProps}
ref={provided.innerRef}
style={{padding: 0, listStyle: "none"}}
>
{headers.map((header, index) => (
<Draggable key={`draggable-${header}-${index}`} draggableId={`draggable-${header}-${index}`} index={index}>
{(provided) => (
<li
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className="fi-settings-toggle"
style={{
...provided.draggableProps.style,
}}
>
<div className="fi-settings-toggle-header">
<span className="dashicons dashicons-ellipsis"></span>
<span>{header}</span>
</div>
<ToggleControl
checked={states[index]}
onChange={(newValue) => toggleColumn(index, newValue)}
/>
</li>
)}
</Draggable>
))}
{provided.placeholder}
</ul>
)}
</Droppable>
</DragDropContext>
</PanelBody>
<PanelBody title={__('Header appearance', 'flexible-invoices-core')}>
<ColorSelector
label={__('Text Color', 'flexible-invoices-core')}
value={headerTextColor}
enableAlpha={false}
onChange={(value) => setAttributes({headerTextColor: value})}
/>
<ColorSelector
label={__('Background Color', 'flexible-invoices-core')}
value={headerBackground}
onChange={(value) => setAttributes({headerBackground: value})}
/>
<NumberWithUnit
label={__('Font Size', 'flexible-invoices-core')}
value={headerFontSize}
onChange={(value) => setAttributes({headerFontSize: value})}
/>
<AlignButtons
label={__('Text Align', 'flexible-invoices-core')}
onChange={(value) => setAttributes({headerTextAlign: value})}
/>
<FontStyles
label={__('Font style', 'flexible-invoices-core')}
onChange={(newFontStyles) => setAttributes({
...attributes,
headerFontStyle: newFontStyles.fontStyle,
headerFontWeight: newFontStyles.fontWeight,
headerTextDecoration: newFontStyles.textDecoration
})}
values={
{
fontStyle: headerFontStyle,
fontWeight: headerFontWeight,
textDecoration: headerTextDecoration
}
}
/>
<ColorSelector
label={__('Table border color', 'flexible-invoices-core')}
value={tableBorderColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({tableBorderColor: value})}
/>
<NumberWithUnit
label={__('Table border width', 'flexible-invoices-core')}
value={tableBorderWidth}
onChange={(value) => setAttributes({tableBorderWidth: value})}
/>
<ColorSelector
label={__('Border row color', 'flexible-invoices-core')}
value={headerBorderRowColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({headerBorderRowColor: value})}
/>
<DuoInput
label={__("Row top/bottom border width", 'flexible-invoices-core')}
values={
{
headerBorderRowWidthTop,
headerBorderRowWidthBottom,
}
}
onChange={handleMultipleAttributesChange}
/>
<ColorSelector
label={__('Border cell color', 'flexible-invoices-core')}
value={headerBorderColumnColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({headerBorderColumnColor: value})}
/>
<DuoInput
label={__("Column left/right border width", 'flexible-invoices-core')}
values={
{
headerBorderColumnWidthLeft,
headerBorderColumnWidthRight,
}
}
layout={'row'}
onChange={handleMultipleAttributesChange}
/>
</PanelBody>
<PanelBody title={__('Body appearance', 'flexible-invoices-core')}>
<ColorSelector
label={__('Text color', 'flexible-invoices-core')}
value={bodyTextColor}
enableAlpha={false}
onChange={(value) => setAttributes({bodyTextColor: value})}
/>
<ColorSelector
label={__('Background color', 'flexible-invoices-core')}
value={bodyBackground}
enableAlpha={false}
onChange={(value) => setAttributes({bodyBackground: value})}
/>
<ToggleControl
label={__('Alternating row colors', 'flexible-invoices-core')}
checked={multipleBodyBackground}
onChange={(newValue) => setAttributes({multipleBodyBackground: newValue})}
/>
{multipleBodyBackground ?
<>
<ColorSelector
label={__('Background color (even rows)', 'flexible-invoices-core')}
value={bodyBackgroundEven}
onChange={(value) => setAttributes({bodyBackgroundEven: value})}
/>
<ColorSelector
label={__('Text color (even rows)', 'flexible-invoices-core')}
value={bodyTextColorEven}
enableAlpha={false}
onChange={(value) => setAttributes({bodyTextColorEven: value})}
/>
</>
: ''
}
<NumberWithUnit
label={__('Font size', 'flexible-invoices-core')}
value={bodyFontSize}
onChange={(value) => setAttributes({bodyFontSize: value})}
/>
<AlignButtons
label={__('Text align', 'flexible-invoices-core')}
onChange={(value) => setAttributes({bodyTextAlign: value})}
/>
<FontStyles
label={__('Font style', 'flexible-invoices-core')}
onChange={(newFontStyles) => setAttributes({
...attributes,
bodyFontStyle: newFontStyles.fontStyle,
bodyFontWeight: newFontStyles.fontWeight,
bodyTextDecoration: newFontStyles.textDecoration
})}
values={
{
fontStyle: bodyFontStyle,
fontWeight: bodyFontWeight,
textDecoration: bodyTextDecoration
}
}
/>
<ColorSelector
label={__('Border row color', 'flexible-invoices-core')}
value={bodyBorderRowColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({bodyBorderRowColor: value})}
/>
<DuoInput
label={__("Row top/bottom border width", 'flexible-invoices-core')}
values={
{
bodyBorderRowWidthTop,
bodyBorderRowWidthBottom,
}
}
units={ [
{ label: 'px', value: 'px' },
{ label: 'em', value: 'em' },
{ label: 'pt', value: 'pt' }
] }
onChange={handleMultipleAttributesChange}
/>
<ColorSelector
label={__('Border cell color', 'flexible-invoices-core')}
value={bodyBorderColumnColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({bodyBorderColumnColor: value})}
/>
<DuoInput
label={__("Border cell width", 'flexible-invoices-core')}
values={
{
bodyBorderColumnWidthRight,
bodyBorderColumnWidthLeft,
}
}
layout={'row'}
units={ [
{ label: 'px', value: 'px' },
{ label: 'em', value: 'em' },
{ label: 'pt', value: 'pt' }
] }
onChange={handleMultipleAttributesChange}
/>
</PanelBody>
{additionalOptions}
{placeholders && <BlockPlaceholders
placeholders={placeholders}
/>}
</InspectorControls>
<div {...blockProps}>
<table className="fitb-item-table has-background" style={{
borderStyle: "solid",
borderColor: tableBorderColor,
borderWidth: tableBorderWidth,
borderCollapse: 'collapse'
}}>
{tableHeader ? tableHeader :
<TableHead
headers={headers}
updateHeader={updateHeader}
tableStyles={{
headerBackground,
headerTextColor,
headerTextAlign,
headerFontStyle,
headerTextDecoration,
headerFontSize,
headerFontWeight,
headerBorderColumnColor,
headerBorderColumnWidthLeft,
headerBorderColumnWidthRight,
headerBorderRowColor,
headerBorderRowWidthTop,
headerBorderRowWidthBottom
}}
states={states}
/>
}
{
tableBody ? tableBody :
<TableBody
rows={rows}
states={states}
updateCell={updateCell}
tableStyles={
{
bodyBackground,
bodyBackgroundEven,
bodyTextColor,
bodyTextColorEven,
bodyTextDecoration,
bodyTextAlign,
bodyFontStyle,
bodyFontSize,
bodyFontWeight,
bodyBorderColumnColor,
bodyBorderColumnWidthLeft,
bodyBorderColumnWidthRight,
bodyBorderRowColor,
bodyBorderRowWidthTop,
bodyBorderRowWidthBottom,
multipleBodyBackground
}
}
/>
}
{tableFooter &&
<tfoot>
{tableFooter}
</tfoot>
}
</table>
</div>
</>
);
}