Select Git revision
SimpleLoggerFactory.php
-
Grzegorz Rola authoredGrzegorz Rola authored
FlexibleTable.jsx 12.30 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 {DuoInput, NumberWithUnit, ColorSelector, FontStyles, AlignButtons, BlockPlaceholders} from "../../index";
export default function FlexibleTable({attributes, setAttributes, placeholders, footer, additionalOptions }) {
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={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={__('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={__("Border row 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={__("Border cell 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={__('Duo color table', '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={__("Border row width", 'flexible-invoices-core')}
values={
{
bodyBorderRowWidthTop,
bodyBorderRowWidthBottom,
}
}
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'}
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'
}}>
<thead className={"fitb-item-table-header"} style={{
borderStyle: "solid",
borderColor: headerBorderRowColor,
borderTopWidth: headerBorderRowWidthTop,
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: headerBorderColumnColor,
borderLeftWidth: headerBorderColumnWidthLeft,
borderRightWidth: headerBorderColumnWidthRight,
}}>
<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((_, trIndex) => (
<tr className={"fitb-item-table-row"} style={{
background: (multipleBodyBackground && trIndex === 1) ? bodyBackgroundEven : bodyBackground,
borderStyle: "solid",
borderColor: bodyBorderRowColor,
borderTopWidth: bodyBorderRowWidthTop,
borderBottomWidth: bodyBorderRowWidthBottom,
}}>
{rows.map((row, index) => (
states[index] ?
<td className={"fitb-item-table-cell"} key={index}
style={{
borderStyle: "solid",
borderColor: bodyBorderColumnColor,
borderLeftWidth: bodyBorderColumnWidthLeft,
borderRightWidth: bodyBorderColumnWidthRight,
}}>
<RichText
tagName="div"
key={index}
value={row}
style={{
color: (multipleBodyBackground && trIndex === 1) ? bodyTextColorEven : 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>
</>
);
}