Can't include React UI frameworks (Grommet) - reactjs

I have problems importing UI libraries, I had problem with ant design library so I decided to try different one, now I have problem importing Grommet.
What am I doing wrong? I added dependencies according documentation and added examples included in documentation yet still not working.
I am trying to execute this code from documentation
But it doesn't look the same at all
I work with codesandbox.io, here is link for the code on it
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import Heading from "grommet/components/Heading";
import Box from "grommet/components/Box";
import Header from "grommet/components/Header";
import Title from "grommet/components/Title";
import Search from "grommet/components/Search";
import Menu from "grommet/components/Menu";
import Anchor from "grommet/components/Anchor";
import "grommet-css";
class HelloWorldApp extends React.Component {
render() {
return (
<div>
<Header>
<Title>Sample Title</Title>
<Box flex={true} justify="end" direction="row" responsive={false}>
<Search
inline={true}
fill={true}
size="medium"
placeHolder="Search"
dropAlign={{right: "right"}}
/>
<Menu dropAlign={{right: "right"}}>
<Anchor href="#" className="active">
First
</Anchor>
<Anchor href="#">Second</Anchor>
<Anchor href="#">Third</Anchor>
</Menu>
</Box>
</Header>
<Box>
<Heading>
Hello, I'm a Grommet Component styled with
grommet-css
</Heading>
</Box>
</div>
);
}
}
var element = document.getElementById("root");
ReactDOM.render(<HelloWorldApp />, element);

So according to your code:
<Menu dropAlign={{right: "right"}}>
was missing the icon attribute, without which the Menu component directly renders the Anchor, the menu-items component.
add import for the icon of your choosing, i.e: Actions ( from the example )
import Actions from 'grommet/components/icons/base/Actions';
add the icon attribute to the Menu component:
<Menu
icon={<Actions />}
dropAlign={{ right: 'right' }}
>
<Anchor href="#" className="active">First</Anchor>
<Anchor href="#">Second</Anchor>
<Anchor href="#">Third</Anchor>
</Menu>
here's a codesandbox.io link which fixes your issue:
https://codesandbox.io/s/237xo7y48p

Related

How to conditionally display a material-ui breadcrumb within a component

I'm using mui breadcrumbs within my react app and unsure why I am not seeing the second separator as part of my <MyBreadcrumb /> component.
I am also trying to conditionally display my breadcrumb list but I think now that this could be the issue as it's also placing each breadcrumb item on separate lines.
The main contents looks as follows:
import * as React from 'react';
import Typography from '#mui/material/Typography';
import Breadcrumbs from '#mui/material/Breadcrumbs';
import { Link, useParams } from "react-router-dom";
export default function MyBreadcrumb() {
const { instrument, name } = useParams();
return (
<Breadcrumbs aria-label="breadcrumb">
<Link to={"/"}>
Home
</Link>
{ !instrument ? (
<Typography color="text.primary">{name}</Typography>
) : (
<>
<Link to={-1}>
Musician
</Link>
<Typography color="text.primary">{name} - {instrument}</Typography>
</>
)}
</Breadcrumbs>
)
}
Basically if instrument is undefined then I expect to see the following breadcrumb menu:
Home / Tom
Otherwise if instrument has a value, I then expect to see the following breadcrumb menu:
Home / Musician / Bob - guitar
I believe the issue with the second separator not appearing is because I'm not sure how to conditionally display my breadcrumb menu based on the above rules.
After checking the DOM element, I found something interesting. I have a quick fix for this, but not the best answer I think.
codesandbox: https://codesandbox.io/s/mui-5-forked-fn21v1
import * as React from "react";
import Typography from "#mui/material/Typography";
import Breadcrumbs from "#mui/material/Breadcrumbs";
import { Link } from "react-router-dom";
export default function App() {
const instrument = true ? "guitar" : undefined;
const name = "Tom";
return (
<>
<Breadcrumbs aria-label="breadcrumb">
<Link to={"/"}>Home</Link>
{!instrument && <Typography color="text.primary">{name}</Typography>}
{/* OLD */}
{/* {instrument && (
<>
<Link to={-1}>Musician</Link>
<Typography color="text.primary">
{name} - {instrument}
</Typography>
</>
)} */}
{/* NEW */}
{instrument && <Link to={-1}>Musician</Link>}
{instrument && (
<Typography color="text.primary">
{name} - {instrument}
</Typography>
)}
</Breadcrumbs>
</>
);
}
So the quick fix is to seperate the Musician and {name} - {instrument} element to a different conditional rendering.
DOM screenshot with OLD code:
DOM screenshot with NEW code:
As you can see on OLD code, when we wrap the 2 elements with <>...</>, MUI will convert it into 1 list instead of 2, and meanwhile on the NEW code that we seperate the conditional rendering, MUI generate 2 lists.
I don't know what happen under the hood with MUI, but hope this little quick fix can help.

how to use react routing to switch between pages

i am currently building a shopping website . i finished the homepage and i have to make routing for other pages
i have 3 main files: App.js, Menuitem.js (which is to execute props), and Homepage.js (which also is used to apply executing props from sections array which includes titles and background images and sections paths)
this is the App js
import React from "react";
import Homepage from './Homepage'
import "./styles.css";
import './Homepage.css'
import {Route, Switch} from "react-router-dom";
const Hatspage=function() {
return(
<div>
<h1>
Hats page
</h1>
</div>
)
}
function App() {
return (
<div>
<Switch>
<Route exact path='/'component={Homepage}/>
<Route path='/hats'component={Hatspage}/>
</Switch>
</div>
);
}
export default App
Menuitem.js
import React from 'react'
import {WithRouter} from 'react'
const Menuitem= function(props){
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})` }} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
export default Menuitem
Homepage.js
import React from "react";
import sections from './directory-components';
import Menuitem from "./menu-item-components";
const arrayOne=[sections.slice(0,3)]
const arrayTwo=[sections.slice(3,)]
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl}/>
)
}
function Homepage(){
return(
<div className='directory-menu'>
<div className='content'>
{sections.slice(0,3).map(extract) }
</div>
<div className='second'>
{sections.slice(3,).map(extract) }
</div>
</div>
)
}
export default Homepage
so i need for example when i click on hats picture i switch to hats page . how to do that
image attached
Thanks in advance
reactjs routing
You can do two different approaches. Both of them will require an extra prop that will be the actual url you want to access when clicking the menu item.
Assuming you modify your section array to look like this:
[{title: 'Your title', imageUrl: 'your-image.jpg', linkUrl: '/hats'}]
And you modify your extract function to add the url value as a prop in the MenuItem component:
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl} linkUrl={item.linkUrl} />
)
}
You can do this
First one: Using a Link component from react router:
import React from "react";
import { Link } from "react-router-dom";
const Menuitem= function(props){
return(
<Link to={props.linkUrl}>
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
</Link>
)
}
Now you will have to add extra styling because that will add a regular a tag, but I like this approach because for example you can open the link in a new tab since it is a regular link.
Using the history prop.
import React from "react";
import { useHistory } from "react-router-dom";
const Menuitem= function(props){
const history = useHistory()
const goToPage = () => history.push(props.linkUrl)
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} onClick={goToPage} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
This approach is a basic on click so if you press the component it will go to the selected page, this will work but keep in mind that event bubbling will be harder if you add more on clicks inside the menu item, so please be aware of that.
You should fire an event inside your MenuItem in order to redirect the user
import { useHistory } from 'react-router-dom'
const history = useHistory()
<img onClick={() => history.push('/hats')} />

React FontAwesome Icon disappears when I add <a> tag

I am trying to add links to my font-awesome react component.
<div>
<FontAwesomeIcon icon={faHome} size="2x" />
<div>
The component above renders the faHome icon.
But when I add anchor tag around it, it does not render. I can still see that the component in inspector tools with <svg> tag also loaded the same way when I didn't have anchor tag in the first example.
<div>
<a href="https://www.youtube.com/c/jamesqquick">
<FontAwesomeIcon icon={faHome} size="2x" />
</a>
</div>
it is working perfectly. Please check the below code:
import React from "react";
import "./styles.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faHome } from "#fortawesome/free-solid-svg-icons";
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div>
<a href="https://www.youtube.com/">
<FontAwesomeIcon icon={faHome} size="2x" />
</a>
</div>
</div>
);
}
Here is the Code Sandbox
Here is output

Problem with showing a component which is in another file onclick

I am currently building an website in React with a navigation bar which I use Material-UI for.
My problem is that when I for example click "About" in my navigation bar, I want to show the content/component in About, and when I click Home I want the component Home to be shown and others hidden.
The problem is I am still a beginner in React and want to practice my React skills and now I have the navbar, Home, About in seperate files and not sure on how to pass through state, props and so in this case.
I will show a screen shot on the website and code-snippets to show my code so far.
My website:
File structure of my program:
Here is Code:
App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import NavBar from './Components/Navigationbar'
import Home from './Components/Home'
import About from './Components/About'
class App extends Component {
constructor(props){
super(props);
this.state = {showAbout: true};
this.handleAbout = this.handleAbout.bind(this);
}
handleAbout(){
this.setState({showAbout: true})
}
render() {
return (
<div className="App">
<div className="App-header">
</div>
<NavBar></NavBar>
<p className="App-intro">
<Home></Home>
</p>
{this.state.showAbout ? <About /> : null}
</div>
);
}
}
export default App;
Home.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
Home
</Typography>
<Typography component="p">
Welcome Home
</Typography>
</Paper>
</div>
);
}
About.jsx:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
padding: theme.spacing(3, 2),
backgroundColor: 'mistyrose'
},
}));
export default function PaperSheet() {
const classes = useStyles();
return (
<div>
<Paper className={classes.root}>
<Typography variant="h5" component="h3">
About
</Typography>
<Typography component="p">
About
</Typography>
</Paper>
</div>
);
}
And finally the navigation bar which is from Material UI:
Navigationbar.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import Button from '#material-ui/core/Button';
import App from '../App';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import About from './About';
const useStyles = makeStyles({
root: {
flexGrow: 1,
},
});
function handleAbout(props){
alert('About');
}
const navBar = (props) => {
return (
<Paper >
<Tabs
//value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
centered
>
<Tab label="Home" />
<Tab label="About" onClick={() => handleAbout(props)} />
<Tab label="Contact" />
</Tabs>
</Paper>
);
}
//ReactDOM.render(<navBar />, document.querySelector('#app'));
export default navBar;
My problem is I want to when I click "About" in the navbar, I want to show the About component(the content in About.jsx) on my website but not sure on how to handle state and props in the case when they are in seperate files.
Would appreciate if someone could help me.
Thanks a lot.
You can use react-router for navigation. How to install and use it is quite nicely shown on the page: https://reacttraining.com/react-router/web/guides/quick-start
Oh boy, this is a big one...
In the simplest case, you pass state though props like this:
<ChildComponent showAbout={this.state.showAbout}/>, and access it in ChildComponent by props.showAbout (or this.props.showAbout if it's a class component).
But things can get complicated as your application scales. Values can only be passed through props downwards inside the component tree; in other words, a component can only see a state that's somewhere above it. You can't use state from a sibling component or a component below it.
And that's the whole reason state management libraries exist. They provide a 'global' state that is available anywhere in the app. Redux is one of them.
You should sit down and learn Redux, as you can't really make a big app without a state management tool.
Another thing you should learn is react-router, for client-side routing.
Those things combined will provide a powerful tool for making useful apps.

how to change the menu depending on the width of the screen?

I apologize for my English using a translator.
I use React.js.
I have a component "header" that accepts two other components - and .
import React, { Component } from 'react';
import styles from './Header.module.css';
import MainLogo from '../MainLogo/MainLogo';
import NavMenu from '../NavMenu/NavMenu';
import BurgerButton from '../BurgerMenu/BurgerButton';
import BurgerMenu from '../BurgerMenu/BurgerMenu';class Header extends Component {
render() {
return (
<header className={styles.header}>
<nav className={styles.navBar}>
<MainLogo />
<NavMenu />
</nav>
</header>
);
}
}
export default Header;
I also created a separate component .
I want to get this markup option: if the screen size is <= 420px, the component should be rendered in the header. With a screen width >420px, the component should be displayed.
I understand that the question is very banal, but I have not yet found an elegant solution.
Thank you in advance!
P.S. using an external library is not suitable.
You can use react-media to render components conditionally based on the screen's size.
In your case, it would look something like this (adapt for your specific markup)
<header className={styles.header}>
<nav className={styles.navBar}>
<MainLogo />
<NavMenu />
<Media query={{ maxWidth: 420 }}>
{matches => <MyComponent /> // Component is in the header}
</Media>
</nav>
</header>
<Media query={{ minWidth: 421 }}>
{matches => <MyComponent /> // Component is outside of the header}
</Media>

Resources