How to use SyntaxHighlighter for inline code - css

I am using Syntax Highlighter for my website.But how can I use it for inline code? I mean when I use it for inline code it still shows the line number 1 and I want to remove it as it makes no sense to show line number for inline code
i.e
I want
"This is a java print code System.out.println("Hello");"
instead of
"This is a java print code 1 |System.out.println("Hello");"
(notice the line number in second case)
I searched it on google but no success.

There is a configuration for turning line number on/off:
setting gutter attribute allows you to turn gutter with line numbers on and off.
Here is reference , Here is DEMO

You will have to use a custom code block and style it yourself to achieve it:
Algo:
If Inline Display Custom Block
Else Allow SyntaxHighlighter to do its magic.
I have used the below code:
CodeHighlighter.js
import {Prism as SyntaxHighlighter} from "react-syntax-highlighter";
import {dracula} from "react-syntax-highlighter/dist/esm/styles/prism";
import './CodeHighlighter.css'
import {Card} from "#mui/material";
function cleanChildren(children){
for (var i = 0; i < children.length; i++){
children[i] = children[i].trim()
}
return children
}
export default function CodeHighlight({node, inline, className, children, ...props}) {
var lang = "";
try {
lang = className.replace("language-", "");
} catch {
lang = "";
}
return (
<div className='highlightRoot'>
{inline ?
(
<Card className='inlineCode' variant='outlined'>
<code >{children}</code>
</Card>
)
: (
<div>
<SyntaxHighlighter
language={lang}
style={dracula}
showLineNumbers={!inline}
startingLineNumber={1}
children={cleanChildren(children)}
/>
<p>{lang}</p>
</div>
)
}
</div>
);
}
CodeHighlighter.css
.highlightRoot{
display: inline;
}
.inlineCode{
display: inline;
padding: 0 4px;
background-color: #4b4b59;
color: white;
}
I have been using this in conjunction with ReactMarkdown library.
What I was able to achieve:

Related

Importing React State into CSS file

I am currently working on a NextJS based project, in which I need to use React State to determine the width of a div. Currently this is being calculated inside a .tsx file using consts and incremented when a button is clicked. The resultant width is then passed down as a prop to the component.
Right now, I'm using inline styling to set the width of the div, but I wanted to know if it was possible to pass the prop directly into the .module.css file I'm using as it will be tidier and much easier for media queries later on. Is that possible?
Also, is it possible to import variables from the media queries back into the .tsx file?
Main file:
const [width, setWidth] = React.useState(0)
const increment: number = maxWidthTop / totalRounds
export default function Labeller() {
function clicked() {
setWidth(width + increment)
}
return (
<Progress
width={width} />
)}
Component file:
import styles from '../../styles/Progress.module.css'
type ProgressProps = {
width: number;
}
export default function ProgressBar(props: ProgressProps) {
return (
<div className={styles.main}>
<div className={styles.bar}>
<div className={styles.base}></div>
<div style={{width: `${props.width}em`}} className={styles.top}></div>
</div>
</div>
)
}
You can't modify the css module dynamically at runtime as the css files are downloaded and parsed by the browser separately from the js. Supplying your width value using inline is styles a good way to go but you are right that it doesn't make media queries easy.
One alternative option would be to write a function that formats a css string with your width variable, and renders the output inside a style element:
import "./styles.css";
const divWidthStyles = (width: number) => `
.${styles.top} {
width: ${width}px;
}
#media only screen and (min-width: 600px) {
.${styles.top} {
width: ${2 * width}px;
}
}
`;
...
export default function ProgressBar(props: ProgressProps) {
return (
<div className={styles.main}>
/* Use style element */
<style>{divWidthStyles(props.width)}</style>
<div className={styles.bar}>
<div className={styles.base}></div>
<div className={styles.top}></div>
</div>
</div>
);
}
Another option would be to set a css variable using javascript, whenever width changes, by making use of useEffect(). Like so:
function ProgressBar(props: ProgressProps) {
const { width } = props;
const divRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (divRef.current) {
divRef.current.style.setProperty("--width", `${width}px`);
}
}, [width]);
return (
...
<div
className={"dynamic_width"}
ref={(ref) => (divRef.current = ref)}
></div>
...
);
}
And then making use of the variable in your css.module file like this:
.dynamic_width {
height: 200px;
background: red;
width: var(--width);
}
#media only screen and (min-width: 600px) {
.dynamic_width {
width: calc(2 * var(--width));
}
}
Side note; there's a library called styled-components that allows you to supply values to the styles of components easily. I find it helps to keep things very tidy and could be a more elegant solution to your problem.

Apply CSS styling to Draft.js formatted text content

I'm implementing a rich text editor to my React web app using Draft.js.
The only options I've kept in the toolbar are inline-styling (bold, italic, underline) and numbered/bulleted lists.
Before implementing the text editor, the texts in my database were simple strings that I could retrieve, display in a styled component and apply CSS to, so the first letter in the text looked like this:
This was my React styled component :
export const Text = styled.p`
&:first-letter {
float: left;
font-family: 'Centaur';
font-size: 3.5rem;
line-height: 0.65;
margin: 0.1em 0.1em 0.1em 0;
}
`
Now that I'm using Draft's text editor, my text is being displayed in a div that has a dangerouslySetInnerHTML property applied to it, so I can't apply CSS to it to edit the style of the first letter.
How can I get my head around this? I know that I can retrieve the editor's plain text with: editorState.getCurrentContent().getPlainText('\u0001')
I was thinking about storing the first letter of the text in the database to wrap it with a CSS class when displaying it, but then I would need to remove that letter from the rest of the text content saved so that the first letter doesn't appear twice, and I don't know how to alter Draft.js text content while retaining the styling.
This is my Draft.js Editor component with a Preview component underneath that displays the formated text:
import { EditorState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import { convertToHTML } from 'draft-convert';
export default function MyComponent() {
const [editorState, setEditorState] = useState( () => EditorState.createEmpty() );
const [convertedContent, setConvertedContent] = useState('');
const handleChange = () => {
let currentContentAsHTML = convertToHTML(editorState.getCurrentContent());
setConvertedContent(currentContentAsHTML);
}
const createMarkup = (html) => {
return {
__html: html
}
}
return (
<>
<Editor
editorState={editorState}
onEditorStateChange={setEditorState}
toolbar={{options: ['inline', 'list', 'link', 'emoji', 'remove', 'history']}}
onContentStateChange={handleChange}
/>
<Preview dangerouslySetInnerHTML={createMarkup(convertedContent)}></Preview>
</>
)
}
Do you have any suggestion?
Thank you!

How should I write Jest Test cases for styled component and spy on css to verify if the styles?

I have a component in React-redux, which has a PagedGrid component (basically a table which renders data row-wise).
<UsersContainer>
<Title>{t('users')}</Title>
<PagedGrid
data-auto-container="user:table"
pageData={user.data}
columns={this.column}
/>
</UsersContainer>
I have created a function for the custom styled component which applies css to the rows of the table inside PagedGrid
const UsersContainer = styled.div`
> table > tbody {
${props => customcss(props)};
}
`;
function customcss({ data = [] }) {
let styles = '';
if (data.length > 0) {
data.forEach((value, index) => {
if (value.mycondition) {
const rowStyle = `& > tr:nth-child(${index + 1}) {
background-color: ${LIGHT_BLUE}
}`;
}
});
}
return css` ${rowStyle} `;
}
Now I want to create a test case using jest to spy on the css of this table and check if the styles are getting applied or not. Can anyone help me on creating a test case for this.
Assuming that you use the #testing-library/react library, you could test your component's style by getting it directly from the html document, and see precisely what style is used for your specific element.
In your example, you can do something like below (assuming that the ${LIGHT_BLUE} value is blue):
import React from 'react';
import { render } from '#testing-library/react';
import UsersContainer from '../UsersContainer';
it('should have the background color set to blue', () => {
const { container, getAllByTestId } = render(
<UsersContainer />
);
// Replace <YOUR_CSS_SELECTOR> by your component's css selector (that can be found in the inspector panel)
let contentDiv = document.querySelector('<YOUR_CSS_SELECTOR>');
let style = window.getComputedStyle(contentDiv[0]);
expect(style.color).toBe('blue');
}
Here, to get the style of your element, I am using the element's CSS Selector. However, it could also work with the element's className, or id directly if it has one, respectively using the methods document.getElementByClassName('YOUR_DIV_CLASS_NAME'), document.getElementId('YOUR_DIV_ID') instead of document.querySelector('<YOUR_CSS_SELECTOR>'). Note that the given name here should be unique, either with the id technique, or the className.

In React,How to make a page that contains two dynamic size components

If data in container A collapses(minimised), Component B should increase vertically in size and appear on full page. Similarly if Component B is collapsed,component A should increase.By default,both the components have equal screen space.
there are tons of ways to do this, you can check how flexbox in CSS works. it should not bee very react specific, All you need to do from react is to know which component is collapsed and which is to expanded.
In the parent component, you'll want to track which component is maximised. Then, pass a maximised prop to component A and component B, and let them set their CSS classes based on it. You could hide most of the content if you just want a mini version of the component.
Assuming you're using function components with hooks, it would look somewhat like this:
const Container = () => {
// Either "A", "B" or null (equal sizes)
const [componentMaximised, setComponentMaximised] = useState(null);
return (
<div className="container">
<A maximised={componentMaximised === "A"}/>
<B maximised={componentMaximised === "B"}/>
</div>
);
};
const A = props => {
return (
<div className={props.maximised ? "component component-maximised" : "component"}>
// ...
</div>
);
};
const B = props => {
return (
<div className={props.maximised ? "component component-maximised" : "component"}>
// ...
</div>
);
};
You'll also want to pass the setComponentMaximised function to each component as a prop if you want them to be able to have a button to maximise and minimise themselves.
For your CSS, use display: flex in combination with flex-grow to set how the items share the space:
.container {
height: 100vh; /* approx full height */
display: flex;
flex-flow: column nowrap;
}
.component {
flex-grow: 1;
overflow: hidden; /* prevent contents from spilling out of component */
}
.component-maximised {
flex-grow: 3;
}
Quick demo of this technique (try changing the classes manually in HTML)
https://codepen.io/gh102003/pen/MWKOQqE
You can use flex-grow: 0 if you just want the component to take up the space it needs.

How to make a block appear in reactjs?

Hi and thanks for the great work here. I'm pretty new in reactjs and I'm struggling to make it work with sandbox like jsfiddle.
I have a div called "app-content" tht is supposed to appear in the middle of the document just like the following :
For some reasons , I cant make the following thing on my sandbox , and I get the following : https://jsfiddle.net/w7sf1er6/8/
JS here
export default class App extends React.Component {
render() {
return (
<div className="app-content">
</div>
);
}
};
ReactDOM.render (
<App />,
document.getElementById('root')
);
and CSS here
html {
background-color: #e3e3e3;
font-family: regular, arial, sans-serif; }
body {
margin: 0 !important;
padding: 0 !important; }
a {
text-decoration: none; }
.app-content {
width: 1200px;
height: 500px;
margin-left: auto;
margin-right: auto;
background-color: white; }
What am I mising ? I need to make it work on JSfiddle so I can share it with others developers. I wuld appreciate some help from our community.
Thanks.
You must install react-blocks via npm first if you haven't already.
Like so, npm install react-blocks
Once you have done this, you will need to import/require react-blocks within your react code.
// using an ES6 transpiler
import Block from 'react-blocks';
// not using an ES6 transpiler
var Block = require('react-blocks');
Next, the layout:
// Normal Flex layout
const App = () => {
return (
<Block layout>
<div>Alpha</div>
<div>Beta</div>
</Block>
);
};
// Reverse Flex layout
const Reverse = () => {
let { reverse } = styles;
return (
<Block style={reverse.block} layout vertical reverse>
<div>Alpha</div>
<div flex>Beta</div>
</Block>
);
};
Feel free to read more on the process here.
Hope this helps!
Your React component is not rendering to the div. You can see errors in the console log and doing "view frame source" on the HTML output pane will show you that the "div" element hasn't been replaced.
As Chris suggested, just start from a JSFiddle example that sets up React correctly.
The example above mainly differs from your code in that it imports React definitions.
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js" />

Resources