Custom button in toolbar draftjs editor - reactjs

How can I add a button with a custom function behind it to the draftjs editor? I have the feeling this should be pretty straightforward but I can't find examples or documentation.
I have an Editor with only bold italic and list buttons and I want to add a button that shows a popup where I can select 1 of 3 options and then "inject" this in the editor.
Can someone point me in the right direction (or documentation)?

here how i tried this, purely react hooks way to achieving things,
App.js file
import MyEditor from './Component/MyEditor';
function App() {
<MyEditor />
}
MyEditor.js file export MyEditor component used and imported in App.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState, RichUtils} from 'draft-js';
import 'draft-js/dist/Draft.css';
import './MyEditor.css'
export default function MyEditor() {
const [editorState, setEditorState] = React.useState(
() => EditorState.createEmpty(),
);
const _onBoldClick = () => {
setEditorState(RichUtils.toggleInlineStyle(editorState, 'BOLD'))
}
return(
<div>
<button onClick={_onBoldClick}>BOLD</button>
<div
>
<Editor
textAlignment="left" placeholder="Enter something here"
editorState={editorState} onChange={setEditorState} />
</div>
</div>
)
}
//ReactDOM.render(<MyEditor />, document.getElementById('container'));
css file for styling
div.DraftEditor-root {
border: 1px solid black;
height: 200px;
width: 200px;
margin-left: 20%;
overflow-y: auto;
}
div.DraftEditor-editorContainer, div.public-DraftEditor-content {
height: 100%;
}

Related

Ant design Menu.Item custom style in react

Hi everyone i learning ant design with React + typescript. i need to override some default styles in Menu.Item components. but i have a problem with remove border-right style when user click that Menu.Item using styleComponent. i don't know the exact way but i inspect that component and i picked the className from inspection and made border-right: 3px solid transparent
but still it didn't work for me Here is the code i attach below
import { Layout, Menu } from "antd";
import React from "react";
import styled from "styled-components";
import { Flex } from "../styleComponents/commonUtilsStyles";
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from "#ant-design/icons";
import SubMenu from "antd/lib/menu/SubMenu";
const MenuItem = styled(Menu.Item)`
.ant-menu-vertical .ant-menu-item::after,
.ant-menu-vertical-left .ant-menu-item::after,
.ant-menu-vertical-right .ant-menu-item::after,
.ant-menu-inline .ant-menu-item::after {
border-right: 3px solid transparent !important;
}
`;
const { Header, Sider, Content } = Layout;
const FlexContainer = styled(Flex)`
background-color: white;
box-shadow: 6px 6px 32px #cccccc, -6px -6px 32px #f4f4f4;
`;
const HeaderContainer: React.FC = () => {
return (
<>
<Layout>
<Sider>
<Menu mode="inline">
<SubMenu key="submenu" title="number">
<MenuItem className="no-border" key="1">
one
</MenuItem>
<MenuItem className="no-border" key="2">
two
</MenuItem>
<MenuItem className="no-border" key="3">
three
</MenuItem>
</SubMenu>
<MenuItem className="no-border" key="11">
one 1
</MenuItem>
<MenuItem className="no-border" key="21">
two 1
</MenuItem>
<MenuItem className="no-border" key="31">
three 1
</MenuItem>
</Menu>
</Sider>
</Layout>
<h1>hello</h1>
</>
);
};
export default HeaderContainer;
output
but i need to remove that border line style when user click that menu it
Create a css file and set the border-right property to 0px for following classes to remove the right border.
index.css
.ant-menu-vertical .ant-menu-item::after,
.ant-menu-vertical-left .ant-menu-item::after,
.ant-menu-vertical-right .ant-menu-item::after,
.ant-menu-inline .ant-menu-item::after {
border-right: 0px;
}
Screenshot:
I found the best way is using Emotion React
import styled from "#emotion/styled";
import { Menu } from "antd";
and then overwrite the style (you need to inspect to know the antd css class)
/**
* ant-menu-item:hover::after
* ant-menu-item-selected
* ant-menu-item-selected:after
*/
const CustomMenu = styled(AntMenu)`
&& .ant-menu-item:hover::after {
border-bottom: 0px solid transparent;
}
&& .ant-menu-item-selected {
background-color: #EEF6F7;
border-top: 4px solid #B80012;
border-radius: 0px;
color: #B80012;
}
&& .ant-menu-item-selected:after {
border-bottom-width: 0px;
border-bottom-color: transparent;
}
`;
Finally, use it as a component
return (
<ConfigProvider theme={theme}>
<CustomMenu
onClick={onClick}
selectedKeys={[current]}
mode="horizontal"
items={menuItems}
{...props}
/>
</ConfigProvider>
);
This is how I test in Storybook
Custom AntDesign Horizontal menu
EXPLAINATION
Why can we do this?
Firstly, Emotion styled component' styled can style any component as long as it accepts a className prop. https://emotion.sh/docs/styled
Secondly, let's check Ant Design source code, go to Menu component, we will see index.tsx import InternalMenu in this line import InternalMenu from './menu';
Then, we go to menu.tsx, which export InternalMenu component and see its props here const InternalMenu = forwardRef<RcMenuRef, InternalMenuProps>((props, ref) => {...}
And scroll down, in the destructuring part it has const { prefixCls: customizePrefixCls, className,...restProps} = props;
=> Here you can see it accepts className props, which means you can apply what styled component approach which EmotionJS offers.
Have fun!
Binh Truong :)

Is there a way to override style from Semantic-UI with style from Styled-Components in ReactJS?

I'm building a small project in ReactJS and I would like to use Semantic-UI (as a main theme of my website) and override some parts of it with Styled Components (like if it was some custom CSS).
When I'm trying to import them on the same component, I've noticed that Styled-Components will use some of the style I wrote but not all of it (like text-size or some margin).
EDIT
Here's the way I've tried to implement them in my component:
import "semantic-ui-css/semantic.min.css";
import { Grid, Form, Segment, Button, Header, Message, Icon } from 'semantic-ui-react';
import { StyledRegister } from '../styles/StyledRegister';
class Register extends React.Component {
...
render() {
return (
<StyledRegister>
<Grid textAlign="center" verticalAlign="middle">
<Grid.Column style={{ maxWidth: 450 }}>
// Here's continue the long code of my register page including form ect...
</Grid.Column>
</Grid>
</StyledRegister>
Do any of you have an idea if it's possible, and if so, is there proper way to do it ?
An example with the custom adapted statistics component of semantic ui:
import "semantic-ui-css/semantic.min.css";
import { StyledStatistic } from "./styledStatistic";
function App() {
return (
<div className="App">
<StyledStatistic>
<StyledStatistic.Value>5,550</StyledStatistic.Value>
<StyledStatistic.Label>Downloads</StyledStatistic.Label>
</StyledStatistic>
</div>
);
}
import styled from "styled-components";
import { Statistic } from "semantic-ui-react";
export const StyledStatistic = styled(Statistic)`
padding: 2rem;
display: flex !important;
justify-content: center;
&&& > .value {
color: red;
}
&&& > .label {
color: green;
}
`;
See: https://codesandbox.io/s/goofy-mestorf-go410

React styled-components how styled declared component

I will try explain one more time my problem for better undestanding .
I need styled component whose I wish he was simultaneously method when i can inject props .
I created easier code for this example :
import React from "react";
import styled from "styled-components";
import "./App.css";
const styledInput = styled.input`
width: 300px;
height: 300px;
border: 2px solid black;
`;
const Input = props => {
return <styledInput type="text" />;
};
const App = props => {
return (
<div>
Text : <Input val={1} />
</div>
);
};
export default App;

How do you pass an image to a styled component?

I'm using styled-components in ReactJS and I'm trying to create a component that can take in the background-image as a prop. After some research, I've tried this:
import SpeechBubble1 from '../images/home_images/Speech 1.png';
...
const SpeechBubble = styled.div`
background-image: url(${props => props.background});
`;
...
<SpeechBubble background={SpeechBubble1} />
But it doesn't work. Checking in the browser element window, I can see I'm getting an Invalid property value for background-image.
What am I doing wrong?
Edit:
I also tried doing this, which hasn't worked:
<SpeechBubble style={{background: `url(${SpeechBubble1})`}} />
Make sure you are including a height for the styled component, otherwise, it won't display anything (unless it has children that define its dimensions).
Working example:
components/Container
import styled from "styled-components";
const Container = styled.div`
height: 100vh;
background-image: url(${({ background }) => background});
background-repeat: no-repeat;
background-size: cover;
`;
export default Container;
index.js
import React, { Fragment } from "react";
import { render } from "react-dom";
import reactbg from "./images/reactbg.png";
import Container from "./components/Container";
import GlobalStyles from "./components/GlobalStyles";
import Title from "./components/Title";
const App = () => (
<Fragment>
<GlobalStyles />
<Container background={reactbg}>
<Title>Hello World</Title>
</Container>
</Fragment>
);
render(<App />, document.getElementById("root"));
Index.js
import React from 'react'
import {ProfilePic} from './NavigationElements'
import profileimg from '../../images/profileimg.jpg'
const Navigation = () => {
return (
<NavigationWrapper>
<ProfilePic src={profileimg} alt="" />
</NavigationWrapper>
)
}
export default Navigation
NavigationElements.js
import styled from "styled-components";
export const NavigationWrapper = styled.div`
color: #fff;
`
export const ProfilePic = styled.img`
width: 5vh;
height: 3vh;
margin: 55px;
`
You can use inline styling:
<SpeechBubble style={{background: `url(${SpeechBubble1})`}} />

How to use styled-components in React?

Please forgive my confusion and newbiness. I'm trying to export a styled Button. Totally dazed and confused. Please help. I don't really want to export 2 buttons, as shown, but a single Button with the styles from the props, and the given styles as the default, I think :(
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import styled, { css } from 'styled-components'
export default class Button extends React.Component {
btn: Btn = (props) => {
styled.button`
border-radius: 3px;
padding: 0.25em 1em;
margin: 0 1em;
background: transparent;
color: palevioletred;
border: 2px solid palevioletred;
${props => props.primary && css`
background: palevioletred;
color: white;
`}
`
}
render(
<Btn>Normal Button</Btn>
<Btn primary>Primary Button</Btn>
)
}
And my App element in case it's relevant
import React, { Component } from 'react'
import 'containers/App.css'
import Button from 'components/Button'
export default class App extends Component {
render() {
return (
<div>
<p>
<Button primary="primary" label="Button Help" />
</p>
</div>
)
}
}
Define your Styled Button as follows
import React from 'react';
import styled, {css} from 'react-emotion';
const StyledButton = styled('button')`
border-radius: 3px;
padding: 0.25em 1em;
margin: 0 1em;
background: transparent;
color: palevioletred;
border: 2px solid palevioletred;
`;
const primary = css`
background: black;
color: white;
`;
export default class Button extends React.Component {
render() {
return (
<div>
<StyledButton className={this.props.primary && `${primary}`}>
{this.props.label}
</StyledButton>
</div>
);
}
}
and in app element use buttton as follows
import React, { Component } from 'react'
import 'containers/App.css'
import Button from 'components/Button'
export default class App extends Component {
render() {
return (
<div>
<p>
<Button label="Button Help" /> // for normal Styled Button
<Button primary label="Button Primary" /> // for Primary Styled Button
</p>
</div>
)
}
}

Resources