I'm trying to implement the dynamic Row's properties and found justify and align are not updated when the props are updated. Not sure why, maybe something is wrong with the code?
import React, { useState } from "react";
import "./index.css";
import { Col, Row, Button, Select } from "antd";
const App = () => {
const [justify, setjustify] = useState("end");
return (
<>
{justify}
<Select
value={justify}
options={[
{ value: "start", label: "start" },
{ value: "end", label: "end" }
]}
onChange={(val) => {
setjustify(val);
}}
/>
<Row justify={justify} style={{ height: "150px" }} align="bottom">
<Button type="primary">button1</Button>
<Button type="primary">button</Button>
</Row>
</>
);
};
export default App;
The justify property is changed only on the load, not dynamically. I mean the row is not updated on the property's change.
The code to play with is here: https://codesandbox.io/s/grid-sort-antd-5-0-7-forked-85qlli?file=/demo.js:0-662
There are two questions already on Stackoverflow:
Create Horizontal Timeline With
React How to create responsive horizontal timeline
None of them have any accepted answer. And also my question is specifically related to react-horizontal-timeline.
I'm creating my personal portfolio and I wish to show my education/college journey.
The author has given the code:
const VALUES = [ /* The date strings go here */ ];
export default class App extends React.Component {
state = { value: 0, previous: 0 };
render() {
return (
<div>
{/* Bounding box for the Timeline */}
<div style={{ width: '60%', height: '100px', margin: '0 auto' }}>
<HorizontalTimeline
index={this.state.value}
indexClick={(index) => {
this.setState({ value: index, previous: this.state.value });
}}
values={ VALUES } />
</div>
<div className='text-center'>
{/* any arbitrary component can go here */}
{this.state.value}
</div>
</div>
);
}
}
Since I'm coming from Angular and MVC frameworks, I didn't understand what this HorizontalTimeline is doing there. Is there anything I need to import? I'm asking this because the code is giving this error:
Line 13:22: 'HorizontalTimeline' is not defined react/jsx-no-undef
Looks like the compiler is not able to recognize HorizontalTimeline.
And also I would like to have it as a separate component for example <MyTimeline> or so. Why would I clutter my App.js. Hope I was able to explain. Please pitch in.
You need to import the component.
Unfortunately the vendor's documentation doesn't include the import statement. Further unfortunately still, the vendor's demo imports it directly from their source code. Which is fine if you're using their source code, but useless if you're installing their npm package.
Unless the IDE can find the import for you (VS Code should be able to, but anything could be preventing that) then best guesses would be:
import HorizontalTimeline from 'react-horizontal-timeline';
or:
import { HorizontalTimeline } from 'react-horizontal-timeline';
Check out this timeline component if you are interested. I think it's better for your need and also has much more clear documentation and a better horizontal mode.
react-chrono
Here is an example of a responsive timeline using the react-chrono component. I have also added some code that will automatically change to the vertical mode which is better for mobile view.
import React from "react";
import { Chrono } from "react-chrono";
class EducationTimeline extends React.Component {
constructor(props) {
super(props);
this.state = { matches: window.matchMedia("(min-width: 768px)").matches };
}
componentDidMount() {
const handler = (e) => this.setState({ matches: e.matches });
window.matchMedia("(min-width: 768px)").addEventListener("change", handler);
}
render() {
const items = [
{
title: "example",
cardTitle: "example",
cardSubtitle: "example",
cardDetailedText: "example",
}
];
return (
<div style={{ width: "500px", height: "400px" }}>
<Chrono
items={items}
mode={this.state.matches ? "HORIZONTAL" : "VERTICAL"}
slideShow={false}
itemWidth={"250"}
hideControls={true}
cardHeight={100}
borderLessCards={true}
theme={{
primary: "#01bf71",
secondary: "#010606",
cardBgColor: "#f7f8fa",
cardForeColor: "#010606",
titleColor: "#fff",
}}
></Chrono>
</div>
);
}
}
export default EducationTimeline;
In this code, I am trying to insert a code block using react-quilljs
import React, { useState } from 'react';
import hljs from 'highlight.js';
import { useQuill } from 'react-quilljs';
import 'quill/dist/quill.snow.css'; // Add css for snow theme
export default () => {
hljs.configure({
languages: ['javascript', 'ruby', 'python', 'rust'],
});
const theme = 'snow';
const modules = {
toolbar: [['code-block']],
syntax: {
highlight: (text) => hljs.highlightAuto(text).value,
},
};
const placeholder = 'Compose an epic...';
const formats = ['code-block'];
const { quill, quillRef } = useQuill({
theme,
modules,
formats,
placeholder,
});
const [content, setContent] = useState('');
React.useEffect(() => {
if (quill) {
quill.on('text-change', () => {
setContent(quill.root.innerHTML);
});
}
}, [quill]);
const submitHandler = (e) => {};
return (
<div style={{ width: 500, height: 300 }}>
<div ref={quillRef} />
<form onSubmit={submitHandler}>
<button type='submit'>Submit</button>
</form>
{quill && (
<div
className='ql-editor'
dangerouslySetInnerHTML={{ __html: content }}
/>
)}
</div>
);
};
Using the above code, I get the following preview of the editor's content
There are two problems with this:
There is no code syntax highlighting, as I want to achieve this using the highlihgt.js package, inside the code block inside the editor, and
The code block is not displayed (with the black background and highlighting syntax when it's working) in the previewing div outside the editor.
How can I fix these two issues?
Your code is getting marked up by highlight.js with CSS classes:
<span class="hljs-keyword">const</span>
You are not seeing the impact of those CSS classes because you don't have a stylesheet loaded to handle them. You need to choose the theme that you want from the available styles and import the corresponding stylesheet.
import 'highlight.js/styles/darcula.css';
Look at the css in the editor mode. It depends on two class names ql-snow and ql-editor.
You can fix this issue by wrapping it around one more div with className ql-snow.
<div className='ql-snow'>
<div className='ql-editor' dangerouslySetInnerHTML={{ __html: content }}>
<div/>
</div>
This should work.
I got the same issue and when I used hjls what happened was that I got syntax highlighting in the editor but not in the value.
If you noticed the syntax gets highlighted some seconds after you write the code block, this means that the value gets set before the syntax gets highlighted.
So, I just set the value after 2 seconds using setTimeout and this solved my problem
Like this:
<ReactQuill
theme="snow"
value={value}
onChange={(content) => {
setTimeout(() => {
setValue(content)
}, 2000)
}}
modules={modules}
formats={formats}
bounds="#editor"
placeholder="Write something..."
className="text-black dark:text-white"
/>
I recently implemented this logic into my project. I used React Quill for the text editor, implemented syntax highlighting to it using highlight.js, and I also used React Markdown to display the formatted content on my website. React Markdown by default works with markdown, so you need a plugin (rehype-raw) to get it to parse HTML. This is my code, from my project. Just remove some of the unnecessary stuff from here that is specific to my project and use what you need.
// PLUGINS IMPORTS //
import { Typography } from "#mui/material";
import { useEffect, useState } from "react";
import hljs from "highlight.js";
import "react-quill/dist/quill.core.css";
import "react-quill/dist/quill.snow.css";
import "highlight.js/styles/atom-one-dark.css";
import ReactQuill from "react-quill";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
// COMPONENTS IMPORTS //
import { CreateButton } from "components/atoms";
// EXTRA IMPORTS //
import styles from "./create-post.module.css";
import { ETheme } from "types/theme";
/////////////////////////////////////////////////////////////////////////////
type CreatePostProps = {};
hljs.configure({
// optionally configure hljs
languages: ["javascript", "python", "c", "c++", "java", "HTML", "css", "matlab"],
});
const toolbarOptions = [
["bold", "italic", "underline", "strike"],
["blockquote", "code-block"],
[{ list: "ordered" }, { list: "bullet" }],
["link"],
[{ indent: "-1" }, { indent: "+1" }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ align: [] }],
];
const modules = {
syntax: {
highlight: function (text: string) {
return hljs.highlightAuto(text).value;
},
},
toolbar: toolbarOptions,
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
};
const formats = [
"header",
"font",
"size",
"bold",
"italic",
"underline",
"strike",
"blockquote",
"code-block",
"list",
"bullet",
"indent",
"link",
"align",
];
const placeholder = "Description";
const CreatePost = (props: CreatePostProps) => {
const [markdownText, setMarkdownText] = useState("");
useEffect(() => {
console.log({ markdownText });
}, [markdownText]);
return (
<main className={`${styles["create-post-wrapper"]}`}>
<header className={`${styles["create-post-header"]}`}>
<Typography variant="h6">Create a post</Typography>
</header>
{/* making the border a seperate div makes it easier to apply margin */}
<div className={`${styles["border"]} ${styles["top"]}`}></div>
<div>Choose a community</div>
<article className={`${styles["create-post"]}`}>
<section className={`${styles["inner-create-post"]}`}>
<section>Title</section>
<ReactQuill
value={markdownText}
onChange={value => setMarkdownText(value)}
theme="snow"
modules={modules}
formats={formats}
placeholder={placeholder}
/>
<div className="ql-snow">
<div className="ql-editor">
<ReactMarkdown children={markdownText} rehypePlugins={[rehypeRaw]} />
</div>
</div>
<div className={`${styles["border"]} ${styles["bottom"]}`}></div>
<section className={`${styles["post-button"]}`}>
<CreateButton
theme={ETheme.LIGHT}
buttonText="Post"
buttonProps={{
fullWidth: false,
}}
/>
</section>
</section>
</article>
</main>
);
};
export default CreatePost;
You can always add more options to toolbarOptions, but don't forget to also add them to formats if you do. Also, if you want to keep formatting anywhere else in your website, you need the two divs with these 2 classes around your markdown.
React Quill bacially saves everything into a string with HTML and classes, you import styles for those classes and it works like magic.
I'm using material ui for a react app. I'm also using material table. My nav bar just uses the default styling that material ui provides. This has been working fine. However when I add material table to the page, the nav bar goes from blue to white! I'm not sure how to resolve this. The code is below:
class ProfilePage extends React.Component {
render() {
const rows = [
{ title: "Time", field: "time" },
{ title: "Type", field: "type" },
{ title: "Feature", field: "feature" },
{ title: "Weight", field: "weight" }
];
const {Profile, error, match } = this.props;
const features = Profile;
const userId = `ID: ${match.params.userId}`;
if (error || Object.entries(tasteProfile).length === 0) {
toastr.error(error);
featureTable = <h2>Couldn't find profiles for that id</h2>;
}
return (
<div>
<NavBar />
<Typography id="userId" variant="h6" color="inherit">
{userId}
</Typography>
<Paper>
<div>
<MaterialTable
title="Profiles"
columns={rows}
data={features["features"]}
>
</MaterialTable>
</div>
</Paper>
</div>
);
}
}
Grateful for any help!
Try using the same versions of material-ui/core and material-ui/icons that material-table uses as seen in the package-lock.json file. I was able to fix my AppBar CSS style issue by downgrading these to the same version.
npm uninstall #material-ui/core
npm uninstall #material-ui/icons
npm install #material-ui/core#4.0.1
npm install #material-ui/icons#4.0.1
Have you tried including the Material table stylesheet before the Material UI kit one?
I have an app using Material UI Beta where I try to style a simple component as follows:
import { MuiThemeProvider } from 'material-ui/styles';
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: 200,
marginRight: theme.spacing.unit,
width: 200,
},
menu: {
width: 200,
},
});
export const CreateJob = (props) => {
const { classes } = props;
let confirmDelete = () => {
const r = window.confirm("Confirm deletion of job");
return r === true;
};
return (
<MuiThemeProvider>
<div>
<form onSubmit={props.isEditting ? props.handleEdit : props.handleSubmit} noValidate autoComplete="off">
<h2>Update job details</h2>
<TextField
error={props.jobIdError !== ''}
helperText={props.jobIdError || "Example: ES10"}
autoFocus
margin="dense"
id="jobId"
label="Job ID"
name="jobid"
fullWidth
onChange={props.handleInputChange('jobId')}
value={props.jobId} />
</form>
</div>
</MultiThemeProvider>
I then use this in my parent component as follows:
<CreateJob open={this.state.open} />
However, this yields the following error:
TypeError: Cannot read property 'classes' of undefined
this.state is not defined in your code. In the example, state is defined as
state = {
name: 'Cat in the Hat',
age: '',
multiline: 'Controlled',
currency: 'EUR',
};
Sorry I'm kinda late with an answer, but I just found this question while searching for another solution.
I'm going to assume you also imported withStyles.
Firstly, you don't need to export both the simple component and the enhanced one:
export const CreateJob = props => {...} // lose the 'export'
export default withStyles(styles)(CreateJob); // only export here
Secondly, a real problem: <MuiThemeProvider> should be placed around your highest component(usually the <App> component that you render in your entry point file), so you can customize the default theme to your liking for the whole app; see their example here. I'm not sure, but this might even solve your problem, since that should have thrown another error like in this issue.
I just hope this helps someone, but I cannot be sure about what your exact problem is without the complete component file.