import {__} from '@wordpress/i18n'; import {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"; 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={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' }}> {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> </> ); }