Link react-router-dom causes CSS to be lost - css

I have a react component looks like this:
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<Link to={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</Link>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
</MenuSection>
When I click the Link, the route is correct and it takes me to the correct page. However all the CSS in that following page is not applied. If I reload the page that 'Link' took me to the CSS is applied correctly.
When I change the 'Link' and replace it with an < a > tag, when I click the link everything works the next page has the css applied correctly with out any problems.
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<a href={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</a>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
</MenuSection>
I can't figure out why this is happening, this is the first React project I have done, so maybe I am missing something really obvious?
UPDATE:
When I use import {Nav} from "react-bootstrap"; (Nav.Link) - from react bootstrap, when I click the link the page navigates correctly and the CSS is applied correctly.
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<Nav.Link href={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</Nav.Link>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
So it just seems when I use Link from react-router-dom I get this strange behaviour.
For now I have found a solution by using Nav.Link, but I would really like to know why when I use Link the navigation works but the CSS is not applied untill I reload the page.

Related

react-syntax-highlighter is not working with TailwindCSS

I am displaying sanity block content using [#sanity/block-content-to-react](#sanity/block-content-to-react). The BlockContent component is wrapper by div with class of "prose".
<div className="prose prose-zinc font-display prose-h1:font-normal prose-code:mx-1 prose-code:before:content-none prose-code:after:content-none dark:prose-invert ">
<BlockContent
// Pass in block content straight from Sanity.io
blocks={singleBlog.body}
serializers={serializers}
/>
</div>
In my serializers, I am passing custom <Code/> component.
const serializers = {
types: {
code: (props) => <Code props={props} />,
},
};
In my custom code component, I am using Syntax Highlighter to wrap by code content.
<SyntaxHighlighter style={theme} language={props.node.language}>
{props.node.code}
</SyntaxHighlighter>
But, no matter which theme I choose, it only changes the background colors and font sizes but has no effect in text colors.
I thought 'prose' class on wrapper div was causing the problem. But remove that didn't work either.
{/* <div className="prose prose-zinc font-display prose-h1:font-normal prose-code:mx-1 prose-code:before:content-none prose-code:after:content-none dark:prose-invert "> */}
<BlockContent
// Pass in block content straight from Sanity.io
blocks={singleBlog.body}
serializers={serializers}
/>
{/* </div> */}
Does anyone have any solution ?
I am not sure if you are using a custom theme or if you are using one of the many option. But if you are using the available one that you can find here: https://react-syntax-highlighter.github.io/react-syntax-highlighter/demo/prism.html
Then it may be a problem with your imports.
If I import the theme like that (using the hljs ): import {dark} from "react-syntax-highlighter/dist/esm/styles/hljs"; I only get background color.
If I import the theme like this using the 'prism' option I get the text color too: import {dark} from "react-syntax-highlighter/dist/esm/styles/prism";

How can I remove a CSS class based on condition

Hi I am writing a react code for a button. Here is the code:
<Button
block={true}
className={`sc-pc-action-button ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>
There is a condition in which I dont need this sc-pc-action-button css.
Now this class sc-pc-action-button is hardcoded.
How can I write a CSS which tells me to ignore the contents of sc-pc-action-button and take fresh CSS I am giving.
I need a CSS solution to remove the properties. I don't need JS Solution
<Button
block={true}
className={`${someCondition ? "sc-pc-action-button" : ""} ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>

Using style from a NextJS module CSS stylesheet

I have a stylesheet for a button which is located at styles/Button.module.css and i am trying to use it in my NextJS project but can't seem to get it going.
In my component, i have imported the stylesheet normally, i.e;
import Button from '../styles/Button.module.css';
Then i am trying to add it to the return in a component, like so;
<button onClick={e => login(e)} className={"text-white bg-indigo-600 " + (loading ? "Button.btn-loading" : "")}>
Login
</button>
But the styles don't seem to be pulling through.
Any help would be greatly appreciated
"Button.btn-loading" is invalid. Button is an imported JS object, hence you need to remove the quotes to evaluate the JS object notation.
<button onClick={e => login(e)} className={"text-white bg-indigo-600 " + (loading ? Button['btn-loading'] : "")}>
Login
</button>
That's why CSS Modules recommends using camelCase class names, so that we can use dot notation instead of bracket notation to get the values.
I'd suggest using template literals for more cleaner syntax
<button onClick={e => login(e)} className={`text-white bg-indigo-600 ${loading ? Button['btn-loading']: ""}`}>
Login
</button>

ARIA accessibility issues with <Select>

Background
We are using #axe-core/react to work on ARIA accessibility in react application. By default, on page reload no issues are reported, but on Select click we are facing various issues with accessibility, according to axe-core/react.
Problems
serious: Page must have means to bypass repeated blocks
https://dequeuniversity.com/rules/axe/4.0/bypass?application=axeAPI
moderate: Document must have one main landmark
https://dequeuniversity.com/rules/axe/4.0/landmark-one-main?application=axeAPI
moderate: All page content must be contained by landmarks
https://dequeuniversity.com/rules/axe/4.0/region?application=axeAPI
In addition to problems, there are 2 more:
moderate: Page must contain a level-one heading https://dequeuniversity.com/rules/axe/4.0/page-has-heading-one?application=axeAPI
serious: Elements must have sufficient color contrast https://dequeuniversity.com/rules/axe/4.0/color-contrast?application=axeAPI
Code
import React from "react";
import ReactDOM from "react-dom";
import axe from "#axe-core/react";
import { BrowserRouter, Route, Link } from "react-router-dom";
import { MenuItem, Select, InputLabel } from "#material-ui/core";
const BypassRepeatedBlocks = () => (
<div aria-hidden="true">
<a href="#select-content" style={{ display: "none" }}>
bypass repeated blocks
</a>
</div>
);
const NavigationSample = () => (
// we must have <nav> here in order to put content inside landmark. Otherwise we would get issue.
<nav>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
</ul>
</nav>
);
const HomePage = () => <div></div>;
const App = () => (
// BrowserRouter, Route and <Link> (NavigationSample) are the cause of bypass repeated blocks issue
<BrowserRouter>
{/**but with BypassRepeatedBlocks portion of code, it can be solved */}
<BypassRepeatedBlocks />
<NavigationSample />
<main>
<Route path="/home" component={HomePage} />
{/**without <h1> there is heading issue on page loading */}
<h1>H1</h1>
<InputLabel id="my-input" style={{ color: "black" }}>
Sort
</InputLabel>
<Select
id="select-content"
labelId="my-input"
value="item1"
style={{ width: "200px" }}
>
<MenuItem key="item1" value="item1">
item1
</MenuItem>
<MenuItem key="item2" value="item2">
item2
</MenuItem>
</Select>
</main>
</BrowserRouter>
);
axe(React, ReactDOM, 1000);
ReactDOM.render(<App />, document.getElementById("root"));
Observations
As with shown code, when drop-down menu is shown I can navigate through menuitems (options) with key down and key up from keyboard, and that is what is important, from accessibility point of view, right?
After clicking on Select and inspecting HTML elements of web page, I can see two things: first, that my main content gets hidden <div id="root" aria-hidden="true">, and second that new <div> is generated with role='presentation' which contains this drop-down content. And it is outside of <main> which sort of explains the issue All page content must be contained by landmarks, as well as Document must have one main landmark and Page must contain a level-one heading
In addition to previous observation, I tried to add MenuProps={{ disablePortal: true }} to Select element, and issue All page content must be contained by landmarks was removed but i don't know if and what negative impacts this can have
from what i read on internet on this topic, I find this case (select, drop-down) to be very specific and advance.
Questions
Is there a proper way to handle mentioned issues for Select element? How?
Is this one of the situations to be considered as a trade-off (don't have to / can't get rid of all issues)?
If 2. is true, is then that bug to axe-core/react tool?
Let me know if I can provide more details, or update some content.
Thanks.
EDIT
Github repo for reproduction: https://github.com/StefanZivkovic/aria-accessibility-problems.
When you git clone it from cmd, navigate to cd aria-accessibility-problems, execute npm i, thennpm start and wait for server to start. If you use VS code, from cmd do code . to open the files and check the code if you want.
By the way, i found how to overcome Page must have means to bypass repeated blocks, at least on this simple example. That particular issue was caused by react-router-dom, and its elements, Link, BrowserRouter and Route. Might be useful for some.

Materialize navbar links conditional rendering

I am using React Materialize and React Router Dom. I'm trying to show navlinks to only authenticated users, so I'm using conditional rendering. But if I do it like below, navlinks are rendered vertical, not horizontal as usual. Is there a solution for that? Thanks
<Navbar>
{isAuthenticated && (
<>
<NavLink to="/locations" href="/locations">
Locations
</NavLink>
<NavLink to="/categories" href="/categories">
Categories
</NavLink>
</>
)}
</Navbar>
Looks like the Navbar component is rendering all of its children inside li elements. When you wrap them in a fragment, the component considers this as its only child element and puts all of the NavLink elements in a single li.
I can think of two simple approaches to handle this:
If there are only a few links, you can do conditional rendering for them:
<Navbar>
{isAuthenticated && (<NavLink to="/locations" href="/locations">Locations</NavLink>)}
{isAuthenticated && (<NavLink to="/categories" href="/categories">Categories</NavLink>)}
</Navbar>
However, this solution is not reliable, especially if you have a lot of links.
Store the NavLink elements in some array and conditionally add the auth-dependant items:
// In the component:
const links = [/* some public links */];
const privateLinks = [
// Don't forget keys. The numbers here are only for example.
<NavLink key={1} to="/locations" href="/locations">Locations</NavLink>,
<NavLink key={2} to="/categories" href="/categories">Categories</NavLink>
];
if(isAuthenticated){
links.push(...privateLinks);
}
// In the template:
<Navbar>{links}</Navbar>
The logic with the links arrays is pretty trivial (with setting private links as the last items) only to keep the demo more simple.

Resources