Skip to content
Snippets Groups Projects
Select Git revision
  • f6cb44b4a64e4081c033e57e962ccf4e06c5aa25
  • main default protected
  • just_for_review
  • 1.0.0
4 results

FlexibleTable.jsx

Blame
  • 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>
    		</>
    	);
    }