Styling with dynamically used class names and attributes in JS(React)? - javascript

I wonder if there is a feasible way to implement something like that.
Say, I want to specify padding but I don't want to use inline styling and want to use classes instead. But I also don't want to specify all possible values in CSS.
Like I write:
<Container className="p25 m10" />
what can be rendered to the self-generated classes p25 and m10
<div class="p25 m10"/> /* Classes p25 and m10 are self-generated and have padding and margin */
or even
<Container p=25, m=10 />
rendered into the same or at least to
<div style="padding: 25px; margin: 10px"/>

I don't see that there is a way to auto-generate a css class. But,
this your first option, are classes that represent some kind of pure css style, what you can do is create a class like this:
.p25 {
padding: 25px;
}
<Container className="p25"/>
Your second option, are props that inside the functional component, through some logic, you will carry out the implementation, for example:
export default function Container({p, m}) {
return (
<div style={{padding: `${p}px`}, margin: `${m}px`}></div>
)
}

install tailwind and config manual stuff into config file.
module.exports = {
theme: {
extend: {
spacing: {
'25': '25px',
}
}
}
}
then use it this way
<div class="p-[25]">
<!-- ... -->
</div>

Related

The correct styling is applied despite the targeting are different in JSX and CSS files

Currently I have the following code:
FormInput.jsx:
import './FormInput.scss';
const FormInput = ({ label, ...otherProps} ) => {
const { value } = otherProps;
return (
<div className="group">
<input className="formInput" {...otherProps} />
{label && (
<label
className={`${value.length ? 'shrink' : ''} formInput-label`}
>{label}</label>
)}
</div>
)
};
export default FormInput;
In FormInput.scss:
.formInput-label {
transition: 300ms ease all;
position: absolute;
font-size: 18px;
left: 5px;
top: 10px;
&.shrink {
top: -14px;
}
}
What I'm confused about is that the targeted class of the label in FormInput.jsx should compile to:
.shrink .formInput-label
But the one in the SASS file will compile to:
.formInput-label.shrink
My question is how does the correct styling still get applied if the class targeting in the JSX and SASS files aren't the same? The JSX has the classes in reverse order and a space in between.
The class attribute (or className in JSX) defines a list of classes. The syntax for classes is different in HTML and in CSS, but the order of classes on the same element does not matter in either.
JSX renders to HTML, so it renders as class="shrink formInput-label", which defines the list of classes ["shrink", "formInput-label"] and is compatible with the CSS selector .shrink.formInput-label.
Also, a CSS selector such as .shrink would match the element as well (just with a lower specifity rating), because it matches one of the classes in the list.

How to display some value with styled-components?

I'm new to styled-components and I'm bit confused.
Can we display something or add functionality to styled-compoentns.
OR styled-components is component that we can apply css only
styled-components is primarily intended to apply css.
So typically you would use wrapper components that provide the content and use the components obtained from styled-components for decoration.
Once in a while, I have found it useful to use the .attrs constructor to pass children when
the content is very specific to the component.
const ResourceMissingError= styled.div.attrs({
children: 'This resource could not be found'
})`color: red`;
render(<ResourceMissingError />);
Can we display something or add functionality to styled-components?
Yes, styled components are usable as any native component would be. So just as HTML's <button> can be used to display something, you can use a styled button to do so. See below.
Similarly, you can add functionality as you would in a native component, by listening to click events, for instance. The demo below "adds" functionality to the ColorfulButton by handling its click event.
See also how the color is passed as a prop to the ColorfulButton via mycolor="green":
const ColorfulButton = styled.button`
display: inline-block;
color: ${props => props.mycolor || "blue"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
display: block;
`;
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.state = { text: "Learn JavaScript (click me)", done: true }
}
handleClick = e => {
this.setState({...this.state, done: !this.state.done});
}
render() {
return (
<div>
<ColorfulButton onClick={this.handleClick} mycolor="green">{this.state.text}</ColorfulButton>
<br />
{this.state.done ? 'Yes' : 'No'}
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="app"></div>
You can make a CSS file and import it in your different components like making class in CSS and use that class in your component as className="". Also, you can refer inline CSS like this way style={{}} make sure the properties name like font-size will be written in fontSize in React inline CSS. Every CSS property that have a dash in the middle of the property name, the dash will be removed and the next letter after dash will be capitalized and also the property value will be in double or single quotation.

Can i use react-native flex similiar to bootstrap row/column system?

Is this good idea to use flex in react native like this?creating your own components which retrive flex values?I were using bootstrap grid system before and now im trying to learn react native.
Is there any way to show this example using react-native bootstrap on the stack?
let FlexContainer = ({direction,children}) =>{
console.log(direction)
var style = {
flexDirection:direction || 'row',
display:'flex',
width:'100%',
height:'100%'
}
return(<div style={style}>{children}</div>)
}
let FlexBox = ({val, color, children}) => {
return (
<div style={{backgroundColor:color, flex:val}}>{children}</div>
)
}
class LayoutExample extends React.Component {
constructor(props){
super(props)
}
render(){
return(
<div className='screen'>
<FlexContainer>
<FlexBox val={1} />
<FlexBox color="blue" val={1} />
<FlexBox color="red" val={1} />
</FlexContainer>
</div>
)
}
}
ReactDOM.render(<LayoutExample />,document.getElementById('example'))
.screen {
width:400px;
height:300px;
border:2px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="example"></div>
Is this approach valid or not?
It is valid, though in my opinion it's better to separate style considerations from logic as much as possible.
I used to work with bootstrap as well, but since I moved to react native I didn't use any grid system and I didn't feel like I missed something, each screen I style according to what I need from that screen, and of curse trying to reuse components as much as possible.

How to set default font family and size in draft.js

I am learning draft.js editor and can't find how to configure default font-family and font size.
I tried this way:
let editorState = EditorState.createEmpty();
let newState = RichUtils.toggleBlockType(
editorState,
'aligncenter'
);
newState = RichUtils.toggleInlineStyle(
newState,
'FONT_SIZE_36'
);
newState = RichUtils.toggleInlineStyle(
newState,
'TIMES_NEW_ROMAN'
);
What is weird, aligncenter style works fine, but font size and family disappears when component gets focus.
Can you please suggest correct way how to do it?
Using RichUtils.toggleInlineStyle() is for modifying the currently selected range of text (or setting the inline style for text that will be entered at the current cursor position). There is not a way to use this to set the default inline styles for the entire document (nor is this recommended).
To get default styles, you should use CSS and set the styles you want for the entire editor. Then you should override those styles for specific text ranges using toggleInlineStyle when the user wants a non-default style (for instance selecting font-size from a dropdown).
Here's the catch. Currently you can pre-define these inline styles using styleMap but you can't really create them on-the-fly as a user chooses an arbitrary font-family (or size or color).
I have been struggling with this also while trying to implement a color-picker for react-rte.org.
(Technically, you can add styles on the fly, but it won't trigger a re-render, so that's not really usable.)
There is an open issue for this here:
https://github.com/facebook/draft-js/issues/52
I expect this will be resolved within a week or so and I can edit this answer with example code to accomplish what you're after.
if your trying to set the default font size in draft.js Editor just set up your component like this below
notice the div that is wrapped around the Editor, EmojiSuggestions, and mentionSuggestion components. Just set the className for the editor to your font size. in my case it is fs-1. Note I have added an editorStyles.editor class that is coming from an attached scss file. This contains some scss for the editor.
Here is what the scss looks like, no need to add this though if you are just trying to edit the default font style
Just showing this, but not needed to set default font size. That is done in div wrapper
.editor {
box-sizing: border-box;
border: 1px solid #ddd;
cursor: text;
padding: 16px;
border-radius: 2px;
margin-bottom: 9px;
box-shadow: inset 0px 1px 8px -3px #ABABAB;
background: #fefefe;
}
.editor :global(.public-DraftEditor-content) {
min-height: 140px;
}
.mention {
color: #2c7be5
}
<div
style={{minHeight: "7em", maxHeight: "10em", overflow: "auto"}}
className={`border border-2x border-300 bg-light rounded-soft fs-1 ${editorStyles.editor}` }
onClick={() => { messageFieldRef.current.focus(); }}
>
<Editor
editorKey={'editor'}
currentContent={ContentState}
editorState={tempEditorState ? tempEditorState : editorState}
onChange={setEditorState}
plugins={plugins}
ref={messageFieldRef}
/>
<EmojiSuggestions />
<MentionSuggestions
open={open}
onOpenChange={onOpenChange}
suggestions={suggestions}
onSearchChange={onSearchChange}
onAddMention={(e) => {// get the mention object selected
}}
entryComponent={Entry}
/>
</div>
<div>
<EmojiSelect closeOnEmojiSelect />
<span color="light" className="px-3 py-1 bg-soft-info rounded-capsule shadow-none fs--1 ml-3" >
<FontAwesomeIcon icon="tags" transform="left-3"/>
Press <strong>#</strong> while typing to insert custom fields
</span>
</div>

tooltip div with ReactJS

objective
I have a div that I want to make act like a tooltip with reactjs.
HTML
<div>on hover here we will show the tooltip</div>
<div>
<div class="tooltip_custom">this is the tooltip!!</div>
</div>
I am used to angularjs using the ng-show with a condition on the <div> , I was wondering if there is such binding in reactjs , or else how can I do this functionality ?
Thanks
You can make your component to return the following markup
return (
<div>
<div onMouseOver={this.handleMouseIn.bind(this)} onMouseOut={this.handleMouseOut.bind(this)}>on hover here we will show the tooltip</div>
<div>
<div style={tooltipStyle}>this is the tooltip!!</div>
</div>
</div>
);
Where tooltipStyle is assigned like this:
const tooltipStyle = {
display: this.state.hover ? 'block' : 'none'
}
So tooltip depends on component state, now in handleMouseIn and handleMouseOut you need to change component state to make tooltip visible.
handleMouseIn() {
this.setState({ hover: true })
}
handleMouseOut() {
this.setState({ hover: false })
}
Here is working example.
You can start diving in React with this article: Thinking in React.
One option is just to do it in CSS. It's not quite as flexible, but with markup like:
<div className="tooltip-on-hover">Hover here</div>
<div className="tooltip">This is the tooltip</div>
You could do:
.tooltip {
...
visibility: hidden; /* Or display: none, depending on how you want it to behave */
}
.tooltip-on-hover:hover + .tooltip { /* Uses the adjacent sibling selector */
visibility: visible; /* Or display: block */
}
Example:
.tooltip { display: none; }
.tooltip-on-hover:hover + .tooltip { display: block; }
<div class="tooltip-on-hover">Hover here</div>
<div class="tooltip">This is the tooltip</div>
You could also nest the tooltip inside the element so you could use a normal descendant selector like .tooltip-on-hover:hover .tooltip. You could even use a ::before or ::after pseudo-element, there are guides around on how to do this.
I think whatever you want to show as tooltip, just add that to the "title" of the div where you want to show it.
Eg:
<div title="I am the tooltip text">I am the div where you should hover</div>
But if its a custom designed div then go as the answers given before.
Install npm package:
npm install react-tooltip
Usage:
import ReactTooltip from "react-tooltip";
<div data-tip="msg to show" data-for='toolTip1' data-place='top'>Tooltip</div>
<ReactTooltip id="toolTip1" />
You can also use React Mapple ToolTip which is easy to use and customize and also comes with predefined themes.
Disclaimer: I am the author of this library
reactjs-mappletooltip
You can use react-tooltip package. Super easy to use and handy also.
Installation: npm i react-tootip.
Example:
1. import it :
import ReactTooltip from "react-tooltip"
Include it in your component:
<div className="createContent">
**<ReactTooltip />**
<div className="contentPlaceholder">
add tool tip to your button/div or any element: data-tip="add tooltip message"
<button className="addSection" data-tip="add tooltip message" onClick={() => this.onAddChild()}>+</button>
package url: https://www.npmjs.com/package/react-tooltip
import Tooltip from "#material-ui/core/Tooltip";
const HtmlTooltip = withStyles((theme) => ({
tooltip: {
backgroundColor: 'rgba(255,250,228)',
color: 'rgba(0, 0, 0, 0.87)',
maxWidth: 400,
fontSize: theme.typography.pxToRem(12),
border: '1px solid #dadde9',
},
}))(Tooltip);
headerName: 'FEEDBACK',
field: "remarks",
flex: 0.30,
renderCell: (params: GridCellParams) => (
<Grid>
<HtmlTooltip title={params.value} placement="bottom">
<Typography style={{ color: "inherit", cursor: "pointer" }}>{params.value}</Typography>
</HtmlTooltip>
</Grid>
)
In case, if you are using react-bootstrap in your project, then use https://react-bootstrap.github.io/components/overlays/ Overlay with the tooltip.
MouseEnter and MoverLeave need to be used though.
<OverlayTrigger
placement="right"
delay={{ show: 250, hide: 400 }}
overlay={renderTooltip}>
<div>on hover here we will show the tooltip</div>
</OverlayTrigger>

Categories