Select Git revision
AbstractMigrationsRepository.php
-
Bartek Jaskulski authoredBartek Jaskulski authored
FlexibleTable.jsx 13.14 KiB
import {__} from '@wordpress/i18n';
import {
RichText,
InspectorControls,
useBlockProps,
} from '@wordpress/block-editor';
import {
PanelBody,
ToggleControl,
} from '@wordpress/components';
import {DragDropContext, Draggable, Droppable} from "react-beautiful-dnd";
import ColorSelector from "../ColorSelector/ColorSelector";
import NumberWithUnit from "../NumberWithUnit/NumberWithUnit";
import AlignButtons from "../AlignButtons/AlignButtons";
import FontStyles from "../FontStyles/FontStyles";
import QuatroInput from "../QuatroInput/QuatroInput";
import BlockPlaceholders from "../BlockPlaceholders/BlockPlaceholders";
export default function FlexibleTable({attributes, setAttributes, placeholders, footer, additionalOptions }) {
const {
headers,
rows,
states,
headerBackground,
headerTextColor,
headerTextAlign,
headerFontWeight,
headerFontStyle,
headerTextDecoration,
headerFontSize,
headerBorderRowWidthTop,
headerBorderRowWidthLeft,
headerBorderRowWidthRight,
headerBorderRowWidthBottom,
headerBorderRowColor,
headerBorderCellWidthTop,
headerBorderCellWidthLeft,
headerBorderCellWidthRight,
headerBorderCellWidthBottom,
headerBorderCellColor,
bodyBackground,
multipleBodyBackground,
bodyBackgroundOdd,
bodyTextColorOdd,
bodyTextColor,
bodyTextAlign,
bodyFontWeight,
bodyFontStyle,
bodyTextDecoration,
bodyFontSize,
bodyBorderRowWidthTop,
bodyBorderRowWidthLeft,
bodyBorderRowWidthRight,
bodyBorderRowWidthBottom,
bodyBorderRowColor,
bodyBorderCellWidthTop,
bodyBorderCellWidthLeft,
bodyBorderCellWidthRight,
bodyBorderCellWidthBottom,
bodyBorderCellColor,
} = 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={header} draggableId={header} 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={__('Border row color', 'flexible-invoices-core')}
value={headerBorderRowColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({headerBorderRowColor: value})}
/>
<QuatroInput
label={__("Border row width", 'flexible-invoices-core')}
values={
{
headerBorderRowWidthTop: headerBorderRowWidthTop,
headerBorderRowWidthLeft: headerBorderRowWidthLeft,
headerBorderRowWidthRight: headerBorderRowWidthRight,
headerBorderRowWidthBottom: headerBorderRowWidthBottom,
}
}
onChange={handleMultipleAttributesChange}
/>
<ColorSelector
label={__('Border cell color', 'flexible-invoices-core')}
value={headerBorderCellColor}
enableAlpha={false}
returnFormat={'hex'}
onChange={(value) => setAttributes({headerBorderCellColor: value})}
/>
<QuatroInput
label={__("Border cell width", 'flexible-invoices-core')}
values={
{
headerBorderCellWidthTop: headerBorderCellWidthTop,
headerBorderCellWidthLeft: headerBorderCellWidthLeft,
headerBorderCellWidthRight: headerBorderCellWidthRight,
headerBorderCellWidthBottom: headerBorderCellWidthBottom,
}
}
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={__('Duo color table', 'flexible-invoices-core')}
checked={multipleBodyBackground}
onChange={(newValue) => setAttributes({multipleBodyBackground: newValue})}
/>
{multipleBodyBackground ?
<>
<ColorSelector
label={__('Background color (odd rows)', 'flexible-invoices-core')}
value={bodyBackgroundOdd}
onChange={(value) => setAttributes({bodyBackgroundOdd: value})}
/>
<ColorSelector
label={__('Text color (odd rows)', 'flexible-invoices-core')}
value={bodyTextColorOdd}
enableAlpha={false}
onChange={(value) => setAttributes({bodyTextColorOdd: 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}
onChange={(value) => setAttributes({bodyBorderRowColor: value})}
/>
<QuatroInput
label={__("Border row width", 'flexible-invoices-core')}
values={
{
bodyBorderRowWidthTop: bodyBorderRowWidthTop,
bodyBorderRowWidthLeft: bodyBorderRowWidthLeft,
bodyBorderRowWidthRight: bodyBorderRowWidthRight,
bodyBorderRowWidthBottom: bodyBorderRowWidthBottom,
}
}
onChange={handleMultipleAttributesChange}
/>
<ColorSelector
label={__('Border cell color', 'flexible-invoices-core')}
value={bodyBorderCellColor}
enableAlpha={false}
onChange={(value) => setAttributes({bodyBorderCellColor: value})}
/>
<QuatroInput
label={__("Border cell width", 'flexible-invoices-core')}
values={
{
bodyBorderCellWidthTop: bodyBorderCellWidthTop,
bodyBorderCellWidthLeft: bodyBorderCellWidthLeft,
bodyBorderCellWidthRight: bodyBorderCellWidthRight,
bodyBorderCellWidthBottom: bodyBorderCellWidthBottom,
}
}
onChange={handleMultipleAttributesChange}
/>
</PanelBody>
{additionalOptions}
{placeholders && <BlockPlaceholders
placeholders={placeholders}
/>}
</InspectorControls>
<div {...blockProps}>
<table className="fitb-item-table has-background" style={{
borderCollapse: 'collapse'
}}>
<thead className={"fitb-item-table-header"} style={{
borderStyle: "solid",
borderColor: headerBorderRowColor,
borderTopWidth: headerBorderRowWidthTop,
borderLeftWidth: headerBorderRowWidthLeft,
borderRightWidth: headerBorderRowWidthRight,
borderBottomWidth: headerBorderRowWidthBottom,
}}>
<tr className={"fitb-item-table-header-row"} style={{
background: headerBackground,
}}>
{headers.map((header, index) => (
states[index] ?
<th className={"fitb-item-table-header-cell"} key={index}
style={{
borderStyle: "solid",
borderColor: headerBorderCellColor,
borderTopWidth: headerBorderCellWidthTop,
borderLeftWidth: headerBorderCellWidthLeft,
borderRightWidth: headerBorderCellWidthRight,
borderBottomWidth: headerBorderCellWidthBottom,
}}>
<RichText
tagName="div"
key={index}
value={header}
style={{
color: headerTextColor,
textAlign: headerTextAlign,
fontStyle: headerFontStyle,
textDecoration: headerTextDecoration,
fontSize: headerFontSize,
fontWeight: headerFontWeight,
}}
onChange={(value) => updateHeader(index, value)}
/>
</th> : ''
))}
</tr>
</thead>
<tbody className={"fitb-item-table-body"}>
{Array.from({length: 2}).map((_, index) => (
<tr className={"fitb-item-table-row"} style={{
background: (multipleBodyBackground && index === 1) ? bodyBackgroundOdd : bodyBackground,
borderStyle: "solid",
borderColor: bodyBorderRowColor,
borderTopWidth: bodyBorderRowWidthTop,
borderLeftWidth: bodyBorderRowWidthLeft,
borderRightWidth: bodyBorderRowWidthRight,
borderBottomWidth: bodyBorderRowWidthBottom,
}}>
{rows.map((row, index) => (
states[index] ?
<td className={"fitb-item-table-cell"} key={index}
style={{
borderStyle: "solid",
borderColor: bodyBorderCellColor,
borderTopWidth: bodyBorderCellWidthTop,
borderLeftWidth: bodyBorderCellWidthLeft,
borderRightWidth: bodyBorderCellWidthRight,
borderBottomWidth: bodyBorderCellWidthBottom,
}}>
<RichText
tagName="div"
key={index}
value={row}
style={{
color: (multipleBodyBackground && index === 1) ? bodyTextColorOdd : bodyTextColor,
textAlign: bodyTextAlign,
fontStyle: bodyFontStyle,
fontSize: bodyFontSize,
textDecoration: bodyTextDecoration,
fontWeight: bodyFontWeight,
}}
onChange={(value) =>
updateCell(index, value)
}
/>
</td> : ''
))}
</tr>
))}
</tbody>
{footer &&
<tfoot>
{footer}
</tfoot>
}
</table>
</div>
</>
);
}