How to style (add css) to material-table (React)? - css

I've been searching for a few days now and can't find anything. I'm using material-table in React but can't figure how to add css in headers (columns of the table) and the content [like changing font size, width and making table rows of striped background].
Can anyone tell me how I can do it?
For reference, here's the current Material table I have and I want to make the rows striped and change the look of headers (column names)
<MaterialTable
title="Title"
columns={this.state.columns}
data={newDataTable}
options={{
selection: true
}}
options={{
search: false,
sorting: true
}}
actions={[
{
icon: () => <Checkbox />,
tooltip: 'checkbox'
},
{
icon: () => <InfoIcon />,
tooltip: 'info',
onClick: (event, item) => {
this.setState({
isOpen: true,
selectedItem: item
});
}
}
]}
/>
</div>
Edit: Also, can't figure out how to change the content of the rows. Like for example I want to add an icon in front of every item corresponding to its data. Currently, I'm just using a js array to display the static data but I can't edit it.

Just define the styles within the columns property:
this.setState({
columns: {[
{
title: 'Name', field: 'name',
cellStyle: {
backgroundColor: '#039be5',
color: '#FFF'
},
headerStyle: {
backgroundColor: '#039be5',
}
},
// Other columns
]}
});
See https://material-table.com/#/docs/features/styling

if you want to add an icon inside your data( rows/cells), you can use built-in render callback in columns definition like this :
const handleTableColumns = (cols) => {
return cols.map((col) => ({
...col,
render: (rowData) => {
return (
<span style = {{display: 'flex'}} >
<KeyboardArrowRightIcon />
{ rowData[col.id]}
</span>
);
};
}))
};
this will insert the icon <KeyboardArrowRightIcon /> in front of every cell of each row, so in materialTable component you have to use handleTableColumns as columns :
<MaterialTable
style={{ padding: '0 8px' }}
columns={this.handleTableColumns(this.state.columns)}
data={data}
...
...
/>

Options can be passed with a key rowstyle. Where you can configure the background colour.
< MaterialTable title = "Title"
columns = {
this.state.columns
}
data = {
newDataTable
}
options = {
{
selection: true,
rowStyle: (row) => {
const rowStyling = {
fontSize: "14px",
fontFamily: "latoregular"
};
if (row.sl % 2) {
rowStyling.backgroundColor = "#f2f2f2";
}
return rowStyling;
},
}
}
options = {
{
search: false,
sorting: true,
}
}
actions = {
[{
icon: () =>
<
Checkbox / > ,
tooltip: "checkbox",
}, {
icon: () =>
<
InfoIcon / > ,
tooltip: "info",
onClick: (event, item) => {
this.setState({
isOpen: true,
selectedItem: item,
});
},
}, ]
}
/>;

Related

How would I go about changing the css of the currently selected value

import { HTMLSelect } from '#blueprintjs/core';
let value = '';
const dropdownPanelSelector = () => {
const options = [
{ label: 'Map', value: '' },
{ label: 'Camera', value: 'Camera' },
];
const onChange = (e) => {
console.log(e, e.target.value);
value = e.target.value;
};
return (
<HTMLSelect
className={css.dropdownPanel}
options={options}
selected={value}
onChange={onChange}
/>
);
};
I would like to change the selected box's text and none of the others.
.dropdown select (unsure here){
font-size:2em:
}

How can I update a Block Templates with dynamic data in WordPress Custom Blocks?

In the following code, I am trying to dynamically update a template with attribute data that is not available until the first useEffect call. In the code below, the first render of course has emoty attributes and displays defaults. I can trace the code and see the template get updated, but after the useInnerBlocksProps is called with the revised template, the data is still not rendered. what am I missing?
export default function Edit(props) {
const { PanelBody, PanelRow } = wp.components;
const { attributes, setAttributes } = props;
useEffect(() => {
setAttributes({'name': 'Edward Alan Thompson'});
setAttributes({'birth_date': '1 jan 1900'});
setAttributes({'death_date': '31 Dec 1990'});
setAttributes({'imageUrl': 'http://wordpressdevel.local/wp-content/uploads/2022/07/1.png'});
}, []);
const blockProps = useBlockProps( {
style:{minHeight: 40, width: '100%', border: "1px dotted red"}
});
const innerBlocksProps = useInnerBlocksProps(
{orientation: "horizontal"},
{template: [
[ 'core/columns', { columns: 2 }, [
[ 'core/column', {width: "20%"}, [
[ 'core/image', { url: attributes.imageUrl??''} ]
] ],
[ 'core/column', {}, [
[ 'core/heading', { content: attributes.name??''} ],
[ 'core/paragraph', { content: 'b. ' + attributes.birth_date??''} ],
[ 'core/paragraph', { content: 'd. ' + attributes.death_date??''} ]
] ],
]
]
]}
);
return (
<div >
<InspectorControls>
<PanelBody title="General" initialOpen={true}>
<PanelRow>
</PanelRow>
</PanelBody>
</InspectorControls>
<div {...blockProps}>
<div {...innerBlocksProps}></div></div>
</div>
);
}
I verified that the last render call does have the proper template definition, its just not what is displayed on the screen.
Looking at your code, the issue seems to be with how useInnerBlocksProps() is called: the first parameter expects blockProps followed by the innerBlocks content, eg:
edit.js
import { useEffect } from '#wordpress/element';
import { useInnerBlocksProps, useBlockProps } from '#wordpress/block-editor';
export default function Edit({ attributes, setAttributes }) {
// Nb. Removed code not related to issue for clarity
useEffect(() => {
// Call setAttributes once
setAttributes({
name: "Edward Alan Thompson",
birth_date: "1 jan 1900",
death_date: "31 Dec 1990",
image_url: "http://wordpressdevel.local/wp-content/uploads/2022/07/1.png",
});
}, []);
const blockProps = useBlockProps({
style: { minHeight: 40, width: '100%', border: "1px dotted red" }
});
const TEMPLATE = [
['core/columns', {}, [ // Number of columns not needed
['core/column', { width: '20%' }, [
['core/image', { url: attributes.image_url ?? '' }]],
],
['core/column', {}, [
['core/heading', { content: attributes.name ?? '' }],
['core/paragraph', { content: 'b. ' + attributes.birth_date ?? '' }],
['core/paragraph', { content: 'd. ' + attributes.death_date ?? '' }]
]]
]]]
const { children, ...innerBlocksProps } = useInnerBlocksProps(blockProps,
{
orientation: "horizontal",
template: TEMPLATE
}
);
return (
<div {...innerBlocksProps}>
{children}
</div>
);
}
Ref: Inner Blocks: Using a react hook
I came to this conclusion after testing your template definition by itself using <InnerBlocks .../> then checked what useInnerBlocksProps() expected.

Gutenberg Block not saving select option

I am working on creating a Gutenberg block that will have a dropdown of posts and the user will pick one.
It saves the selection, but if I refresh the page the selection is not there anymore, switches back to 'ALL'.
It also displays fine in the front end, however, if I try to edit the page, the selections are gone and the dropdown switch back to all.
Any ideas on this one?
const { RichText, InspectorControls, ColorPalette, MediaUpload } = wp.blockEditor;
const { PanelBody, IconButton, RangeControl, TextControl, SelectControl } = wp.components;
wp.data.select('core').getEntityRecords('postType', 'beers');
registerBlockType('tg/product-block', {
title: 'TG Product Block',
description: 'Showcasing Products in a block',
parent: ['tg/products-block'],
atrributes: {
beerName: {
type:'string'
},
beerId: {
type:'string'
}
},
edit: ({attributes, setAttributes}) => {
const {
beerName,
beerId,
} = attributes;
function getBeers() {
let options = [{ value: 0, label: 'All' }];
let beers = wp.data.select('core').getEntityRecords('postType', 'beers');
beers.forEach((beer) => {
options.push({ value: beer.id, label: beer.title.rendered });
});
return options;
}
function onDropdownChangeOne (newBeerId) {
console.log('newBeerId', newBeerId)
setAttributes({ beerId: newBeerId })
fetch(window.location.protocol + '//' + window.location.hostname + ':10016/wp-json/wp/v2/beers/' + newBeerId)
.then(response => response.json())
.then(data => {
console.log(data)
setAttributes({beerName: data.title.rendered})
})
}
return([
<InspectorControls style={{ marginBottom: '40px' }}>
<PanelBody title={'Choose Category For The First Box'}>
</PanelBody>
</InspectorControls>,
<div className="col-md-4">
<SelectControl
value={beerId}
label={'Select a Post'}
options={getBeers()}
onChange={onDropdownChangeOne}
/>
<RichText.Content tagName="h2"
value={beerName}
/>
</div>
])
},
save: ({attributes}) => {
const {
beerName,
beerId,
} = attributes;
return(
<div className="col-md-4">
<RichText.Content tagName="h2"
value={beerName}
/>
</div>
)
}
})```

How can I fix this Wordpress Custom Gutenburg block problem with rendering once loading after it successfully saves?

As the title states I am teaching myself how to create a custom Gutenburg Block for wordpress development and I have written the following code. It functions correctly when you save, but when you reload the saved page you get console errors and it shows
This block contains unexpected or invalid content.
When you click resolve it shows the following:
// Import CSS.
import './editor.scss';
import './style.scss';
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { RichText } = wp.blockEditor
const { withColors } = wp.blockEditor
const { PanelColorSettings} = wp.blockEditor;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
registerBlockType( 'cgb/block-my-block', {
title: __( 'my-block - CGB Block' ),
icon: 'shield',
category: 'common',
keywords: [
__( 'my-block — CGB Block' ),
__( 'CGB Example' ),
__( 'create-guten-block' ),
],
attributes: {
align: {
type: 'string',
default: 'full',
},
link_text: {
selector: 'a',
source: 'children',
},
link_url: {
selector: 'a',
source: 'attribute',
attribute: 'href',
},
txtColor: {
type: 'string'
},
bgcolor: {
type: 'string'
},
},
supports: {
align:true,
//align: ['wide','full'], // limit only to these
},
getEditWrapperProps() {
return {
'data-align': 'full',
};
},
edit: ( props ) => {
let link_text = props.attributes.link_text
let link_url = props.attributes.link_url
let txtColor = props.attributes.txtColor
let bgColor = props.attributes.bgColor
function onChangeContentURL ( content ) {
props.setAttributes({link_url: content})
}
function onChangeContentName ( content ) {
props.setAttributes({link_text: content})
}
function onChangeBGColor ( content ) {
props.setAttributes({bgColor: content})
}
function onChangeColor ( content ) {
props.setAttributes({txtColor: content})
}
return (
<div className={ props.className } style={{ backgroundColor:bgColor, color: txtColor }}>
<InspectorControls key= { 'inspector' } >
<PanelBody>
<PanelColorSettings
title={ __('Title Color', 'tar') }
colorSettings= { [
{
value: txtColor,
onChange: (colorValue) => onChangeColor ( colorValue ),
label: __('Color', 'tar'),
},
] }
/>
<PanelColorSettings
title={ __('Background Color', 'tar') }
colorSettings= { [
{
value: bgColor,
onChange: (colorValue) => onChangeBGColor ( colorValue ),
label: __('Color', 'tar'),
},
] }
/>
</PanelBody>
</InspectorControls>
<p>Sample Link Block</p>
<label>Name:</label>
<RichText
className={props.className} // Automatic class: gutenberg-blocks-sample-block-editable
onChange={onChangeContentName} // onChange event callback
value={link_text} // Binding
placeholder="Name of the link"
/>
<label>URL:</label>
<RichText
format="string" // Default is 'element'. Wouldn't work for a tag attribute
className={props.className} // Automatic class: gutenberg-blocks-sample-block-editable
onChange={onChangeContentURL} // onChange event callback
value={link_url} // Binding
placeholder="URL of the link"
/>
<p>— Hello from the backend.!!</p>
</div>
);
},
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by Gutenberg into post_content.
*
* The "save" property must be specified and must be a valid function.
*
* #link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* #param {Object} props Props.
* #returns {Mixed} JSX Frontend HTML.
*/
save: ( props ) => {
let txtColor = props.attributes.txtColor
let bgColor = props.attributes.bgColor
return (
<div className={ props.className } style={{ backgroundColor:bgColor, color:txtColor }} >
<p>— Hello from the frontend.</p>
<a href={props.attributes.link_url}>{props.attributes.link_text}</a>
</div>
);
},
} );
The console error looks like the POST and the SAVE data are different causing the error.
The message is:
Block validation: Block validation failed for `cgb/block-my-block` ({name: "cgb/block-my-block", icon: {…}, attributes: {…}, keywords: Array(3), save: ƒ, …}).
Content generated by `save` function:
<div class="wp-block-cgb-block-my-block alignfull" style="color:#000000"><p>— Hello from the frontend.</p><a></a></div>
Content retrieved from post body:
<div class="wp-block-cgb-block-my-block alignfull" style="background-color:#cd2653;color:#000000"><p>— Hello from the frontend.</p><a></a></div>
So it looks to me as if the problem is with the Save function style tag's on the root element.
<div className={ props.className } style={{ backgroundColor:bgColor, color:txtColor }} >
I have removed one style only leaving the other and it works. Putting the other back in and it breaks. Have I included this multiple style wrong? If so what is the convention for adding multiple styles that save on the root element? Also I am new and I am learning from tutorials and reading the Gutenburg github docs. If there is something rudimentary I am doing wrong please let me know.
The block validation issue is caused by a small typo where your attribute bgcolor (case sensitive) is called as bgColor in edit() and save().
Your code shows you are on the right path with creating your own custom Gutenberg block, so I'd like to share a suggestion to use array destructuring with props to make your code much easier to read and maintain. Your custom onChange functions which just call setAttributes()can also be removed in favor of calling setAttributes directly, this reduces how much code you need to write and reduces the chance of typos too..
Eg:
// Import CSS.
import './editor.scss';
import './style.scss';
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { RichText } = wp.blockEditor
const { withColors } = wp.blockEditor
const { PanelColorSettings } = wp.blockEditor;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
registerBlockType('cgb/block-my-block', {
title: __('my-block - CGB Block'),
icon: 'shield',
category: 'common',
keywords: [
__('my-block — CGB Block'),
__('CGB Example'),
__('create-guten-block'),
],
attributes: {
align: {
type: 'string',
default: 'full',
},
link_text: {
selector: 'a',
source: 'children',
},
link_url: {
selector: 'a',
source: 'attribute',
attribute: 'href',
},
txtColor: {
type: 'string',
},
bgColor: {
type: 'string',
},
},
supports: {
align: true,
//align: ['wide','full'], // limit only to these
},
getEditWrapperProps() {
return {
'data-align': 'full',
};
},
// Use array destructuring of props
edit: ({ attributes, className, setAttributes } = props) => {
// Use array destructuring of the attributes
const { link_text, link_url, txtColor, bgColor } = attributes;
// Removed custom onChange functions that just call setAttributes
return (
<div className={className} style={{ backgroundColor: bgColor, color: txtColor }}>
<InspectorControls key={'inspector'} >
<PanelBody>
<PanelColorSettings
title={__('Title Color', 'tar')}
colorSettings={[
{
value: txtColor,
onChange: (colorValue) => setAttributes({ txtColor: colorValue }),
label: __('Color', 'tar'),
},
]}
/>
<PanelColorSettings
title={__('Background Color', 'tar')}
colorSettings={[
{
value: bgColor,
onChange: (colorValue) => setAttributes({ bgColor: colorValue }),
label: __('Color', 'tar'),
},
]}
/>
</PanelBody>
</InspectorControls>
<p>Sample Link Block</p>
<label>Name:</label>
<RichText
className={className} // Automatic class: gutenberg-blocks-sample-block-editable
onChange={(content) => setAttributes({ link_text: content })} // onChange event callback
value={link_text} // Binding
placeholder="Name of the link"
/>
<label>URL:</label>
<RichText
format="string" // Default is 'element'. Wouldn't work for a tag attribute
className={className} // Automatic class: gutenberg-blocks-sample-block-editable
onChange={(content) => setAttributes({ link_url: content })} // onChange event callback
value={link_url} // Binding
placeholder="URL of the link"
/>
<p>— Hello from the backend.!!</p>
</div>
);
},
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by Gutenberg into post_content.
*
* The "save" property must be specified and must be a valid function.
*
* #link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
*
* #param {Object} props Props.
* #returns {Mixed} JSX Frontend HTML.
*/
// Use array destructuring of props
save: ({ attributes, className } = props) => {
// Use array destructuring of the attributes
const { txtColor, bgColor, link_url, link_text } = attributes;
return (
<div className={className} style={{ backgroundColor: bgColor, color: txtColor }}>
<p>— Hello from the frontend.</p>
<a href={link_url}>{link_text}</a>
</div >
);
},
});

How can I set the z-index for this select?

Hello I would like to set the z-index of the following component :
import React from 'react';
import chroma from 'chroma-js';
import { colourOptions } from './docs/data';
import Select from 'react-select';
const colourStyles = {
control: styles => ({ ...styles, backgroundColor: 'white' }),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
const color = chroma(data.color);
return {
...styles,
backgroundColor: isDisabled
? null
: isSelected
? data.color
: isFocused
? color.alpha(0.1).css()
: null,
color: isDisabled
? '#ccc'
: isSelected
? chroma.contrast(color, 'white') > 2
? 'white'
: 'black'
: data.color,
cursor: isDisabled ? 'not-allowed' : 'default',
':active': {
...styles[':active'],
backgroundColor: !isDisabled && (isSelected ? data.color : color.alpha(0.3).css()),
},
};
},
multiValue: (styles, { data }) => {
const color = chroma(data.color);
return {
...styles,
backgroundColor: color.alpha(0.1).css(),
};
},
multiValueLabel: (styles, { data }) => ({
...styles,
color: data.color,
}),
multiValueRemove: (styles, { data }) => ({
...styles,
color: data.color,
':hover': {
backgroundColor: data.color,
color: 'white',
},
}),
};
export default () => (
<Select
closeMenuOnSelect={false}
defaultValue={[colourOptions[0], colourOptions[1]]}
isMulti
options={colourOptions}
styles={colourStyles}
/>
);
I found this solution :
styles={{menu: provided => ({ ...provided, zIndex: 9999, colourStyles })}}
instead of
styles={colourStyles}
But I lose all the colors...
Could you help me please ?
Here is the code :
https://codesandbox.io/s/condescending-noether-1ee0v?file=/example.js:0-1531
Thank you very much !
Note that if you used styles={{colourStyles}} instead of styles={colourStyles}, then the app would also lose the colors. This is because it is not expanded as it should. However, styles={{...colourStyles}} would work. Read more in this post.
So this bit of code should fix your problem:
example.js
export default () => (
<Select
[your other props],
styles={{
...colourStyles,
...{control: styles => ({ ...styles, zIndex: 9999})},
}}
/>
);
where the two objects colourStyles and {zIndex: 9999} were merged (in ES6 compatible syntax, see this post for different ways to do this). Alternatively you can just append zIndex: 9999 right behind backgroundColor: 'white' within the colourStyles constant.
Upon inspection you can see it works:

Resources