react-bootstrap-table misaligned header columns - css

I have the following:
Node.jsx
import React from 'react';
import {Col, Row, Tab, Tabs} from 'react-bootstrap';
import Alerts from './Alerts';
import Details from './Details';
import Family from './Family';
import Instances from './Instances';
module.exports = React.createClass({
displayName: 'Node',
render () {
return (
<Row>
<Col md={12}>
<Tabs defaultActiveKey={1}>
<Tab eventKey={1} title={'Details'}>
<Details />
</Tab>
<Tab eventKey={2} title={'Alerts'}>
<Alerts />
</Tab>
<Tab eventKey={3} title={'Family'}>
<Family />
</Tab>
<Tab eventKey={4} title={'Instances'}>
<Instances instances={this.props.nodeInstances}/>
</Tab>
</Tabs>
</Col>
</Row>
);
}
});
Instances.jsx
import React from 'react';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
module.exports = React.createClass({
displayName: 'NodeInstances',
getDefaultProps () {
return {
selectRowOpts: {
mode: "radio",
clickToSelect: true,
hideSelectColumn: true,
bgColor: "rgb(238, 193, 213)",
onSelect: (row, isSelected) => { console.log(row, isSelected); }
}
};
},
render () {
var props = this.props;
return (
<BootstrapTable data={props.instances} hover condensed selectRow={props.selectRowOpts}>
<TableHeaderColumn dataField={'interval_value'} dataSort>{'Interval'}</TableHeaderColumn>
<TableHeaderColumn dataField={'status_name'} dataSort>{'Status'}</TableHeaderColumn>
<TableHeaderColumn dataField={'started_ts'} dataSort>{'Started'}</TableHeaderColumn>
<TableHeaderColumn dataField={'completed_ts'} dataSort>{'Completed'}</TableHeaderColumn>
<TableHeaderColumn dataField={'last_runtime'} dataSort>{'RT'}</TableHeaderColumn>
<TableHeaderColumn dataField={'attempts'} dataSort>{'Attempts'}</TableHeaderColumn>
<TableHeaderColumn dataField={'pid'} dataSort>{'PID'}</TableHeaderColumn>
<TableHeaderColumn dataField={'node_instance_id'} dataSort isKey>{'ID'}</TableHeaderColumn>
</BootstrapTable>
);
}
});
Here is what all that looks like:
Why are the header columns for the table misaligned? Further, when I select one of the headers to sort the table, or when I select one of the rows in the table, the columns become properly aligned with the headers. Did I miss something?

I was having the same issue, and I ended up discovering that I was importing the wrong CSS file. Make sure you're using one of the CSS files listed in here.
I also used table-layout: fixed and set a specific width on each TableHeaderColumn component.
Not the most ideal solution, but it's the only thing I've found that works.

I had same issue . This below import in the app.js solved my problem
import 'react-bootstrap-table/dist/react-bootstrap-table.min.css';

I had same issues, I tried adding fixed width to all rows but it is not a perfect solution. So finally I have created a dynamic width for each row's based on its text string length.
So my suggestion to make the width of every row dynamically(based on string length and also restricted that to 24).
In my below program I have done for loop to get the length of a string in that array and assigning max value as the width of that column(in your case its row)
for (let i = 0; i < (totalElementsinArray); i++) {
if(((obj[i]["Title"]).length)> ((obj[i]["1_Content"]).length) & ((obj[i]["Title"]).length) > 24 ){
heightlength=((obj[i]["Title"]).length)-5
} else {
if(((obj[i]["1_Content"]).length) > 24){
heightlength=((obj[i]["1_Content"]).length)-5
} else {
heightlength=24;
}
}

I've created a javascript function to get the widths of the real table headers and set them to the fixed table headers (wich actually is in another table) :
function fixTableCols(table) {
var _length = [];
var $table = $(table);
$table.find('th').each(function (index, headerCol) {
_length[index] = $(headerCol).width();
});
$table.parent().parent().find('.fixed-table-header').find('th').each(function (index, headerCol) {
$(headerCol).find('.th-inner ').css('width', _length[index]);
});
}
So, you can call this function after applying the bootstrapTable(), like this:
var $table = $('table');
$table.bootstrapTable();
fixTableCols($table);

Related

Creating a custom slider block from InnerBlocks using React Slick

I'm trying to create a somewhat basic custom block that creates a slider based off of the element's inner/nested blocks. Using React Slick, I've ran into an issue where ALL of the inner blocks are being wrapped in a single tag inside of the initialized slick slider element. This means, no matter how many inner blocks I add, there's only a single slide inside of the slick slider element.
Here's a screenshot of what's happening:
I've highlighted the to show you how the inner blocks elements (two basic paragraph blocks) are being combined as one singular slide.
Here's my edit.js:
import { __ } from '#wordpress/i18n';
import React from "react";
import Slider from "react-slick";
import {
InnerBlocks,
useBlockProps,
useInnerBlocksProps,
InspectorControls
} from '#wordpress/block-editor';
import {
PanelBody,
PanelRow,
} from '#wordpress/components';
import './editor.scss';
import classnames from 'classnames';
export default function Edit(props) {
const blockProps = useBlockProps( {
className: classnames( {
'slider': true
} )
} );
var settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
const { children, ...innerBlocksProps } = useInnerBlocksProps( blockProps, {
templateInsertUpdatesSelection: true
} );
return (
<>
<InspectorControls key="1">
<PanelBody title={ __( 'Slides' ) }>
<PanelRow>
<fieldset>
Test
</fieldset>
</PanelRow>
</PanelBody>
</InspectorControls>
<div { ...innerBlocksProps }>
<Slider { ...settings }>
{ children }
</Slider>
</div>
</>
);
}
My gut is telling me this could have something to do with the timing of how the inner blocks get rendered, but I am a bit of a newbie when it comes to building custom blocks. Can anyone steer me in the right direction? I'd really really appreciate it. Thanks!

Add value to existing WP Block Editor setting

I would like to add a 33% to the Wordpress Block "Button". So far it has 25%,50%,75% and 100%. Is it possible to insert my new value into the existing width selector?
I'm guessing Block Filters are the way to go.
I think I also found the way to get the settings object which might then help me to find out what I need to overwrite. However simply adding this code to my admin.js does not produce any output. Where would I need to load this?
const filterBlocks = (settings) => {
if (settings.name !== 'core/buttons') {
return settings
}
console.log(settings);
return settings;
}
Quick solution: Add a custom CSS class in the Buttons' block properties under "Advanced > Additional CSS class(es)" then define the custom width in your theme style.css
Detailed solution:
By using wp.hooks.addFilter() you can add a new control to the Button block with as many extra custom width options as you need. The Button blocks preset widths are defined within the function WidthPanel() of the blocks edit.js function:
function WidthPanel( { selectedWidth, setAttributes } ) {
...
return (
...
<ButtonGroup aria-label={ __( 'Button width' ) }>
{ [ 25, 50, 75, 100 ].map( ( widthValue ) => {
...
}
}
To add a new width value of 33% to the block, we need to add our own new button control to the InspectorControls and then use wp.hooks.addFilter() to add this to the existing core Button block, eg:
index.js
import { createHigherOrderComponent } from '#wordpress/compose';
import { Fragment } from '#wordpress/element';
import { InspectorControls } from '#wordpress/block-editor';
import { PanelBody, Button } from '#wordpress/components';
const withInspectorControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { setAttributes } = props;
let widthValue = 33; // must be a number
return (
<Fragment>
<BlockEdit {...props} />
<InspectorControls>
<PanelBody title="Custom Width">
<Button
key={widthValue}
isSmall
variant={widthValue}
onClick={() => setAttributes({ width: widthValue })}
>
{widthValue}%
</Button>
</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withInspectorControl');
wp.hooks.addFilter(
'editor.BlockEdit',
'core/button',
withInspectorControls
);
Next, a new additional css style needs to be added that (matches the existing width presets structure) for the new custom width, eg:
style.scss
$blocks-block__margin: 0.5em;
&.wp-block-button__width-33 {
width: calc(33.33% - #{ $blocks-block__margin });
}
And there you have it..
The easiest way to put all the code above together/working is to create your own Gutenberg block (and that in itself can be challenging if you aren't familiar with the process or ReactJS). I too have come across similiar challenges with Gutenberg, so I wanted to provide a detailed solution for this kind of issue that works.

Trouble styling TablePagination to-from on material-table

I am attempting to style the from-to of x rows number on a Material-Table, via
import MaterialTable from 'material-table'
import { TablePagination, withStyles } from '#material-ui/core'
const StyledPagination = withStyles({
caption: {
'&.MuiTypography-caption': {
fontSize: '1.5rem !important'
},
fontSize: '1.5rem !important'
}
})(TablePagination)
<MaterialTable
**Other Props Here**
components={{
Pagination: props => (
<StyledPagination
{...props}
labelRowsPerPage={<div>{props.labelRowsPerPage}</div>}
labelDisplayedRows={row => (
<div>{props.labelDisplayedRows(row)}</div>
)}
/>
)
}}
/>
I feel like those two css selectors should be redundant, but neither is working. I feel like material-table is overriding them as the computed font size is 0.75rem .MuiTypography-caption. Have also attempted styling via the root rather than caption with no difference there either.
I have been able to style the dropdown selector for number of rows to display, which seems like the same should apply to this. Originally started with this approach, which also did not work.
Ended up solving this with MuiThemeProvider, I dont think the normal ThemeProvider is working with Material-table
import { createMuiTheme, MuiThemeProvider } from '#material-ui/core/styles'
const theme = createMuiTheme({
overrides: {
MuiTypography: {
caption: {
fontSize: '1.5rem'
}
}
})
then,
<MuiThemeProvider theme={theme}>
<MaterialTable />
</MuiThemeProvider>
Although, this will style anything with class MuiTypography-caption

Add CSS for html selector based on React state?

I'd like to set overflow-y: hidden for the html selector (not an element) based on whether a React class component state variable is true. Is that possible?
If you mean you want to apply the overflow-y to the actual HTML tag then putting this code in the render worked for me
...
render() {
let html = document.querySelector('html');
this.state.test === "test" ? html.style.overflowY = "hidden" : html.style.overflowY = "visible";
return (
....
)
};
You can do
function MyComponent() {
// Set your state somehow
const [something, setSomething] = useState(initialState)
// Use it in your className`
return <div className={!!something && 'class-name'} />
}
If you have multiple class names to work with, a popular package is (aptly named) classnames. You might use it like so:
import cx from 'classnames'
function MyComponent() {
const [something, setSomething] = useState(initialState)
return <div className={cx({
'some-class' : something // if this is truthy, 'some-class' gets applie
})} />
}
Yes, It's possible. You can do this.
function App() {
const [visible, setVisible] = useState(false);
useEffect(() => {
const htmlSelector = document.querySelector("html");
htmlSelector.style.overflowY = visible ? "unset" : "hidden";
}, [visible]);
return (
<button onClick={() => setVisible(prevState => !prevState)}>
Toggle overflow
</button>
);
}
See the full example on CodeSandbox
You can use the style property to set inline CSS:
<div style={{ overflowY: hide ? 'hidden' : 'auto' }}>

How to dynamically adjust textarea height with React?

I want to adjust my textarea height dynamically with Refs and pass it to the state but it don't work correctly.
I created a codesandbox to help you to understand what exactly I want.
https://codesandbox.io/s/ol5277rr25
You can solve this by using useRef and useLayoutEffect built-in hooks of react. This approach updates the height of the textarea before any rendering in the browser and therefor avoids any "visual update"/flickering/jumping of the textarea.
import React from "react";
const MIN_TEXTAREA_HEIGHT = 32;
export default function App() {
const textareaRef = React.useRef(null);
const [value, setValue] = React.useState("");
const onChange = (event) => setValue(event.target.value);
React.useLayoutEffect(() => {
// Reset height - important to shrink on delete
textareaRef.current.style.height = "inherit";
// Set height
textareaRef.current.style.height = `${Math.max(
textareaRef.current.scrollHeight,
MIN_TEXTAREA_HEIGHT
)}px`;
}, [value]);
return (
<textarea
onChange={onChange}
ref={textareaRef}
style={{
minHeight: MIN_TEXTAREA_HEIGHT,
resize: "none"
}}
value={value}
/>
);
}
https://codesandbox.io/s/react-textarea-auto-height-s96b2
Here's a simple solution that doesn't involve refs. The textarea is dynamically adusted using some CSS and the rows attribute. I used this myself, recently (example: https://codesandbox.io/embed/q8174ky809).
In your component, grab the textarea, calculate the current number of rows, and add 1:
const textArea = document.querySelector('textarea')
const textRowCount = textArea ? textArea.value.split("\n").length : 0
const rows = textRowCount + 1
return (
<div>
<textarea
rows={rows}
placeholder="Enter text here."
onKeyPress={/* do something that results in rendering */}
... />
</div>
)
And in your CSS:
textarea {
min-height: 26vh; // adjust this as you see fit
height: unset; // so the height of the textarea isn't overruled by something else
}
You can check the repo. Or you can add the package to your project.
https://github.com/andreypopp/react-textarea-autosize
Also if you really willing to learn how the logic working exactly;
https://github.com/andreypopp/react-textarea-autosize/blob/master/src/calculateNodeHeight.js
There is a source code with all calculations together.

Resources