I want to add a button to material-table toolbar. it doesnt do anything relevant to the table. it just opens a modal with some information
I want to add a button called "quotations" to the left side of the "add item" button.
Sandbox code: https://codesandbox.io/embed/charming-yalow-4pnk4?fontsize=14&hidenavigation=1&theme=dark
As Will Evers mentioned, it's possible to add whatever is necessary to Toolbar of the MaterialTable component by using Toolbar prop :
Toolbar: (props) => (
<div
style={{
display: "flex",
justifyContent: "flex-end",
alignItems: "center"
}}
>
<Button
style={{ height: "fit-content" }}
color="primary"
variant="contained"
>
Quotations
</Button>
<div style={{ width: "13rem" }}>
<MTableToolbar {...props} />
</div>
</div>
),
Working Demo
Per the docs, it looks like you need to override the Toolbar component of your table and you should be able to add what ever you want above the column headers:
https://material-table.com/#/docs/features/component-overriding
https://i.stack.imgur.com/J0mqf.png
Use this prop in the component tag
renderTopToolbarCustomActions={() => (
<Button
variant="contained"
color="primary"
size="large"
onClick={() => console.log('something')}
>
Quotations
</Button>
)}
Related
Im building a web chat app in next.js and i have a emoji picker button that when its clicked the menu of emojis appear.The thing is that in order to the user sees the menu of the emojis he has to scroll down.I have tried scrollIntoView() but it doesnt seem to work,possibly im doing something wrong.
<EmoticonContainer >
{showEmojis && (<Picker id="picker" style={{width: '100%'}} onSelect={addEmoji}/>)}
</EmoticonContainer>
<InputContainer id="container" >
<IconButton onClick={() => {setShowEmojis(!showEmojis),()=>document.getElementById('picker').scrollIntoView(true)}}>
<EmojiEmotionsIcon style={{ color: 'purple' }} fontSize='inherit' />
</IconButton>
<Input style={{fontFamily:"Roboto",fontSize:"12px"}} onKeyUp={()=>ChangeSendIcon()} onKeyPress={(e) => { e.key === 'Enter' && e.preventDefault(); }} value={input} onChange={e=> setInput(e.target.value)}/>
<div>
<IconButton id="send" onClick={sendMessage} style={{ color: 'purple',display:'none' }} disabled={!input} type="submit">
<SendIcon></SendIcon>
</IconButton>
<IconButton style={{ color: 'purple'}} id="record" onMouseUp={()=>record()}>
<MicIcon ></MicIcon>
</IconButton>
<IconButton style={{ color: 'purple',display:"none" }} onClick={()=>stop()} id="stop" >
<StopIcon></StopIcon>
</IconButton>
</div>
</InputContainer>
You are conditionally rendering the picker Component and the showEmojis state is also being set in the same click listener. State updates may be async and you are calling scrollIntoView on element which doesn't exist.
In order to scroll into view once the picker is opened, you need to call scrollIntoView from useEffect once it is opened.
useEffect(() => {
if(showEmojis) {
document.getElementById('picker').scrollIntoView(true)
}
} , [showEmojis])
Now i have used state hook to hide the Form when the page loads. And upon the click or toggle of the radio I'm able to show the Form, But if i toggle the radio again, the form is not hiding.
This is what i have implemented:
const WelcomeTab = () => {
const [toggle, settoggle] = useState(false);
return (
<React.Fragment>
<Tab.Pane
style={{
borderRadius: '7px',
padding: '30px',
}}
attached={false}
>
<Grid>
<Grid.Row>
<Grid.Column floated="left" width={8}>
<Header
style={{
fontSize: '18px',
fontFamily: 'Nunito-Regular',
color: '#4F4F4F',
}}
>
Welcome Screen
</Header>
</Grid.Column>
<Grid.Column floated="right" width={4}>
<Header
as="h4"
style={{
display: 'flex',
justifyContent: 'space-around',
marginLeft: '30px',
}}
>
Customize
<Radio toggle onChange={() => settoggle({ toggle: !toggle })} />
</Header>
</Grid.Column>
</Grid.Row>
</Grid>
{toggle ? (
<Form style={{ paddingTop: '20px' }}>
<Form.Field>
<label style={lableStyle}>Title</label>
<input style={{ marginBottom: '20px' }} />
<label style={lableStyle}>Message</label>
<TextArea />
</Form.Field>
</Form>
) : null}
</Tab.Pane>
</React.Fragment>
);
};
const lableStyle = {
fontFamily: 'Nunito-Regular',
fontWeight: 400,
color: '#4F4F4F',
fontSize: '15px',
display: 'inline-block',
marginBottom: '10px',
};
export default WelcomeTab;
try to add useEffect hook along with change like below,
you no longer need to {} this is old syntax of setState, using hooks we directly make the changes, hope this helps
useEffect(()=>{},[toggle])
replace this wrong syntax code, i can see its not json its boolean value
<Radio toggle onChange={()=>settoggle({toggle: !toggle})}/>
as this is old syntax not work with hooks, try to implment this instead,
<Radio toggle onChange={()=>settoggle(!toggle)}/>
I am trying to align a button to the most right yet not sucessfull. Here is my attempt.
<Button variant="contained" style={{display: 'flex', justifyContent: 'right'}} color="primary" className="float-right" onClick={this.onSend}>
You need to add display flex to the parent element of your Button.
See sandbox here for example: https://codesandbox.io/s/testproviderconsumer-klcsr
class App extends React.Component {
render() {
return (
<div style={{ display: "flex" }}>
<button
style={{ marginLeft: "auto" }}
>
Click
</button>
</div>
);
}
}
{{display: 'flex', justifyContent: 'flex-end'}} are defined in the parent element to align items in the child element.
We can also use float property to align.
<Button variant="contained" style={{float: 'right'}} color="primary" className="float-right" onClick={this.onSend}>
You have to defined in the parent element to align items in the child element.
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<button>
Click here
</button>
</div>
<Button variant="contained" style={{ marginLeft: "auto" }} color="primary" onClick={this.onSend}>
Click
</Button>
As you can see in the docs, the default positioning for the title in react-native-paper is left-aligned. I've seen multiple questions and answers about how to implement a centered title both for Android Native as well as React Native's StackNavigator, but I am having no luck pulling off the same effect with react-native-paper.
So far I have tried using the style parameter in Appbar.Header to pass in { textAlign: 'center' } or { flexDirection: 'row', justifyContent: 'space-between' }, but nothing seems to work. I'm not very impressed with react-native-paper's lack of documentation on overrides, but I still hope there's a way to do what I'm looking for.
const styles = { header: { textAlign: 'center' }}
<Appbar.Header style={styles.header}>
<Appbar.Action icon="close" onPress={() => this.close()} />
<Appbar.Content title={title} />
<Button mode="text" onPress={() => this.submit()}>
DONE
</Button>
</Appbar.Header>
Considering title accept a node, it can be used to display a react component.
How can I force center the title on all devices?
react-navigation allows passing a component for title instead of a string, so we can do the same thing here:
I wrote an example that accepts a custom title component and can be used wherever we want:
import * as React from 'react';
import { Appbar, Button, Text } from 'react-native-paper';
const ContentTitle = ({ title, style }) => (
<Appbar.Content
title={<Text style={style}> {title} </Text>}
style={{ alignItems: 'center' }}
/>
);
const App = () => (
<Appbar.Header>
<Appbar.Action icon="close" onPress={() => this.close()} />
<ContentTitle title={'Title'} style={{color:'white'}} />
<Button mode="text" onPress={() => this.submit()}>
DONE
</Button>
</Appbar.Header>
);
export default App;
You can check: https://snack.expo.io/r1VyfH1WL
There is 2 approach for this.
First,
The Appbar.Content has marginLeft applied to it. So, you just need to set the marginLeft to 0.
<Appbar.Header>
<Appbar.BackAction />
<Appbar.Content title='Title' style={{ marginLeft: 0 }} titleStyle={{ marginLeft: 0 }} />
// Put empty action here or any action you would like to have
<Appbar.Action/>
</Appbar.Header>
Sadly, this approach only allowed one menu action on the right. (or have an equal amount of actions both left and right, but I think only one menu action will be on the left side, that is back button)
Second, make the Appbar.Content has an absolute position. And yes, keep the marginLeft to 0.
<Appbar.Content title='Title'
style={{ marginLeft: 0, position: 'absolute', left: 0, right: 0, zIndex: -1 }}
titleStyle={{ alignSelf: 'center' }} />
We need to set the zIndex to -1 (or lower) so the button/menu action is clickable. This way, you can have more than one menu actions.
The first way is simple but limited, while the second way is powerful but more code to write.
You have to use titleStyle instead of style to center the text. The below code is working for me.
<Appbar.Header>
<Appbar.Content titleStyle={{textAlign: 'center'}} title="Centered Title" />
</Appbar.Header>
There is also a similar subtitleStyle for styling the subtitle. Check the docs for more info.
For 'react-native-paper', this snippet worked for me:
<Button
style = {{justifyContent: 'center'}}
>
Press
</Button>
This should align both text/node title:
<Appbar.Content
title={<Text>title</Text>}
style={{ alignItems: 'center' }}
/>
See https://snack.expo.io/rJUBIR6lU
<Appbar>
<Appbar.Content titleStyle={{alignSelf: 'center'}} title='something' />
</Appbar>
I have three buttons in a Dialog like so:
The JSX is
<DialogActions classes={{ root: this.props.classes.dialogActionsRoot }} >
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose()} >
Clear
</Button>
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose()} >
Cancel
</Button>
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose(this.state.selectedValue)} >
Select
</Button>
</DialogActions>
The 'buttonRoot' style simply determines the button coloring. How to I left align the 'Clear' button so it sits on the left? It seems the buttons are each in a div with a MuiDialogActions-action class.
Just use divider element with flex: 1 0 0 CSS style:
<DialogActions>
<Button>
Left
</Button>
<Button>
Buttons
</Button>
<div style={{flex: '1 0 0'}} />
<Button>
Right
</Button>
<Button>
Buttons
</Button>
</DialogActions>
No need for complicated answers:
Just set the DialogActions component style to {justifyContent: "space-between"}
<DialogActions style={{ justifyContent: "space-between" }}>
<Button>
Left
</Button>
<Button>
Right
</Button>
</DialogActions>
You can do it with Flexbox:
DialogActions {
display: flex; /* displays flex-items (children) inline */
}
DialogActions > Button:first-child {
margin-right: auto;
}
<DialogActions classes={{ root: this.props.classes.dialogActionsRoot }} >
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose()}>
Clear
</Button>
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose()}>
Cancel
</Button>
<Button classes={{ root: this.props.classes.buttonRoot }} size="small" onClick={() => this.props.handleDialogClose(this.state.selectedValue)}>
Select
</Button>
</DialogActions>
Note: See it in full screen.
Edit: This does not answer the question. It will align all the buttons to the left.
According to the DialogActions API the classes you can override are root and spacing.
After taking a look at the implemantation of the component you can see in root class the rule justifyContent: 'flex-end'.
I simply apllied justifyContent: 'flex-start' with another class:
<DialogActions classes={{ root: classes.leftAlignDialogActions }}>
....
</DialogActions>
Make sure to create the class leftAlignDialogActions with makeStyles
const useStyles = makeStyles(theme => ({
leftAlignDialogActions: {
justifyContent: 'flex-start'
}
}))
I would also disableSpacing and then add the flex attributes and MUI styles overrides I need via the sx prop. In my case I had to modify the spacing (gap) from 8px to 10px.
<DialogActions disableSpacing sx={{gap: '10px'}}>
<Button>Cancel</Button>
<Button>Submit</Button>
</DialogActions>
Maybe in your case another option is to wrap the 2nd and the 3rd buttons in a Box component and on the container to add justifyContent: space-between. In this way in the flex container you will have 2 flex items which will be pushed to the left inner edge and right inner edge of the container. The left item will be the first button and the right item will be the Box which has the 2nd and 3rd buttons as children.
You can use first child selector because first button is clear button in tag DialogActions
DialogActions button:first-child {
float:left;
}
OR
You can try. You need to adjust left and bottom property accordingly.
DialogActions{
position:relative;
width:100%;
}
DialogActions button:first-child {
position:absolute;
left:10px;
bottom:10px;
}
Hope it helps you.