Typography element in material ui version 5 - material-ui

Hi I get this error when trying to use Typography element with material-ui-5:
export 'default' (imported as 'typography') was not found in '#mui/material/typography'
here is my code:
import React from 'react';
import Typography from '#mui/material';
export default function Create() {
return (
<div>
<Typography>
Create Page
</Typography>
</div>
)
}

use this :
import {Typography} from '#mui/material';
or
import Typography from '#mui/material/Typography';

Related

Unable to use Makestyles from Material Ui

So, I am using react with MUI (latest version), but the custom CSS is not working as in console. It is showing that.
makestyles is no longer exported from #mui/material/styles ,instead try this #mui/styles
But after using it, it's raising an error which is.
Failed to resolve import "#mui/styles" from "src\component\leaderboard.jsx". Does the file exist?
Here is my code.
import React from 'react'
import Container from '#mui/material/Container'
import Button from '#mui/material/Button'
import {Grid} from '#mui/material'
import {Typography} from '#mui/material'
import {makeStyles} from '#mui/material/styles'
const useStyles = makeStyles({
btnLeader: {
margin: '1rem',
},
})
const Leaderboard = () => {
const classes = useStyles()
return (
<Container align='center'>
<Typography
variant='h4'
align='center'
fontFamily='revert-layer'
color='black'
gutterBottom>
Leaderboard
</Typography>
<Grid
container
spacing='5m'
justifyContent='center'>
<Grid item>
<Button
variant='contained'
className={classes.btnLeader}
align='center'>
Register
</Button>
<Button
variant='outlined'
align='center'>
Top Gainers
</Button>
</Grid>
</Grid>
</Container>
)
}
export default Leaderboard
It looks like you are using an outdated version of Material-UI. The makeStyles API has been moved to a new package #material-ui/styles in the latest version. Try installing and importing like that:
npm install #material-ui/styles
import { makeStyles } from '#material-ui/styles';
Also, make sure that the #material-ui/styles package is installed in your project and the import path is correct.
If you are still encountering an error, make sure that you have installed the latest version of #mui/styles in your project. First try to run that.
With NPM
npm install #mui/styles
Or, with yarn
yarn add #mui/styles
Then try to use that.
import { makeStyles } from '#mui/styles';
Here is the official documentation:- MUI Material. Please read this first for better understanding.
The things are that #mui/styles is not compatible with React.StrictMode or React 18. And #mui/styles is the legacy styling solution for MUI. It depends on JSS as a styling solution, which is not used in the #mui/material any more, deprecated in v5.
makeStyle is deprecated in MUI v5. Instead you can use styled, or the very easy to use sx-prop.
styled
import { styled } from "#mui/material/styles";
import { Button } from "#mui/material";
const StyledButton = styled(Button)({
margin: "1rem",
});
export default function Test() {
return <StyledButton variant="contained">styled button</StyledButton>;
}
sx-prop
import { Button } from "#mui/material";
const classes = {
btnLeader: {
margin: "1rem",
},
};
export default function Leaderboard() {
return (
<Button variant="contained" sx={classes.btnLeader}>
sx prop button
</Button>
);
}

How to import Lottie component?

Remix is prone to the following error when using import on top-level components TypeError: Cannot read properties of undefined (reading 'root').
So I've done as they recommend and have the following imports.server.tsx file.
export * from "lottie-react";
Then my component app.tsx looks exactly like this lottie example.
import React from "react";
import * as Lottie from "../imports.server";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
export default function App() {
return (
<>
<h1>lottie-react - Component</h1>
<Lottie animationData={groovyWalkAnimation} />;
</>
);
}
but I get the following error
JSX element type 'Lottie' does not have any construct or call
signatures.ts(2604)
Edit 1:
The following seems to have worked for imports:
imports.server.tsx
import Lottie from "lottie-react";
export default Lottie;
AppTry.tsx
import React from "react";
import Lottie from "../imports.server";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
export default function AppTry() {
// console.log(LottieModule);
return (
<>
<h1>lottie-react - Component</h1>
<Lottie animationData={groovyWalkAnimation}></Lottie>
</>
);
}
Now the various paramaters like "animationData" and "autoPlay" pop up on the Lottie component which I assume means the import is working? However I am now getting this error when rendering AppTry.tsx?
react.development.js:220 Warning: React.createElement: type is invalid
-- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to
export your component from the file it's defined in, or you might have
mixed up default and named imports.
Check the render method of AppTry.
Edit 2:
import { useLottie } from "lottie-react";
import Lottie from "lottie-react";
import groovyWalkAnimation from "../../public/assets/102875-cinema-clap.json";
const Example = () => {
const options = {
animationData: groovyWalkAnimation,
loop: true,
autoplay: true,
};
const { View } = useLottie(options);
return View;
};
const Example1 = () => {
return <Lottie animationData={groovyWalkAnimation} />;
};
export const TopicOverview = () => {
return (
<div className="space-y-20">
<Example1></Example1>
<Example></Example>
</div>
);
};
Looks like it has to do with your way of importing Lottie.
Shouldn't you import Lottie like this?:
import Lottie from "lottie-react";
I also struggled to get this working in Remix.
You can do the lazy load import somewhere higher up in the tree too.
import type { LottiePlayer } from "#lottiefiles/lottie-player";
import { useEffect } from "react";
interface LottieCompProps {
src: LottiePlayer["src"];
style?: Partial<LottiePlayer["style"]>;
}
function LottieComp({ src, style = {} }: LottieCompProps): JSX.Element | null {
// NB: otherwise, will cause app to crash. see https://remix.run/docs/en/v1/guides/constraints#third-party-module-side-effects
useEffect(() => {
import("#lottiefiles/lottie-player");
},[]);
if (typeof document === "undefined") return null;
return (
//#ts-expect-error dynamic import
<lottie-player
autoplay
loop
mode="normal"
src={typeof src === "string" ? src : JSON.stringify(src)}
style={{
...{
width: "100%",
backgroundColor: "transparent",
},
...style,
}}
/>
);
}
export default LottieComp;
The issue was in my root.tsx, an ErrorBoundary() function that called an <UnexpectedErrors/> component.
This same component was being called in various slug.tsx files. For some reason remix did not like this.
Having two different <UnexpectedErrors/> and <UnexpectedErrors2/> components - one for the slug.tsx files and one for the index.tsx files fixed this.

How to fix 'missing form label' error in Material UI Select using chrome WAVE tool

I am using material UI Select and we are using chrome WAVE tool to fix ADA issues. An error of 'Missing form label' is coming on material UI Select like in the below screenshot. Can anyone help me to solve this issue. Thanks in advance.
wave tool: https://chrome.google.com/webstore/detail/wave-evaluation-tool/jbbplnpkjmmeebjpijfedlgcdilocofh
code:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import InputLabel from '#material-ui/core/InputLabel';
import MenuItem from '#material-ui/core/MenuItem';
import FormHelperText from '#material-ui/core/FormHelperText';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
const useStyles = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
export default function SimpleSelect() {
const classes = useStyles();
const [age, setAge] = React.useState('');
const handleChange = (event) => {
setAge(event.target.value);
};
return (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
onChange={handleChange}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
);
}
screenshot:
I have found one solution for it. Just add htmlFor="demo-simple-select-placeholder-label" in InputLabel tag to rmove the 'missing form label' error.
The error says that the input element, which by the way is aria-hidden="true", has no label.
I think it's a problem similar to the one reported about TablePagination answered here, and to the one about TextareaAutosize discussed here. The element is always hidden to screen readers and the select behavior is implemented with javascript.
WAVE plugin is reporting the error because they prefer report more than less, in case the hidden element is shown at some point like they explain here.
I was able to get the warning to go away by adding htmlFor={'input-id'} to the InputLabel, and adding inputProps={{id: 'input-id'}} to the Select.

Ionic-React: Not able to customize single IonSelectOption with CSS class

I'm trying to customize a single IonSelectOption with a custom CSS class to change the color of one IonSelectOption. I am copy-pasting the code from Ionic's documentation but it still isn't working. The CSS className that I provide to the IonSelectOption does not seem to get passed along to whatever interface that it selected. Hope someone can help me out!
Link to Documentation. This is the code I'm using:
import React from 'react';
import { IonContent, IonItem, IonLabel, IonSelect, IonSelectOption, IonPage } from '#ionic/react';
const options = {
cssClass: 'my-custom-interface'
};
export const SelectOptionExample: React.FC = () => {
return (
<IonPage>
<IonContent>
<IonItem>
<IonLabel>Select</IonLabel>
<IonSelect interface="popover" interfaceOptions={options}>
<IonSelectOption value="brown" class="brown-option">Brown</IonSelectOption>
<IonSelectOption value="blonde">Blonde</IonSelectOption>
<IonSelectOption value="black">Black</IonSelectOption>
<IonSelectOption value="red">Red</IonSelectOption>
</IonSelect>
</IonItem>
</IonContent>
</IonPage>
);
};
and the CSS:
/* Popover Interface: set color for the popover using Item's CSS variables */
.my-custom-interface .brown-option {
--color: #5e3e2c;
--color-hover: #362419;
}
in react, it is className, not class

How to disable the SaveButton when the SimpleForm is invalid in a react-admin app?

In a react-admin SimpleForm component validation is working fine when I click the save button. The field that is required is highlighted and marked red when I click the save button.
I'd like to add a className to the SaveButton as long as the form is invalid. This way I can make it clear to the user that he's not done with the form yet and prevent the user from clicking it.
This is a simplified version of such a SimpleForm.
import {
required,
//...
} from 'react-admin';
const UserCreateToolbar = props =>
<Toolbar {...props}>
<SaveButton
label="user.action.save_and_show"
redirect="show"
submitOnEnter={true}
/>
</Toolbar>;
export const UserCreate = props =>
<Create {...props}>
<SimpleForm
toolbar={<UserCreateToolbar />}
>
<TextInput source="name" validate={[required()]} />
</SimpleForm>
</Create>;
You can create your own SaveButton component, connected to redux, which will get the validation status from the state (check the redux-form documentation) for the form which is always named record-form in react-admin.
Then, you can apply the disabled prop on the button and eventually tweak its styles
Here's my own SaveButton component I came up with. It's working for me. Thanks #Gildas for pointing me in the right direction.
import React from 'react';
import PropTypes from 'prop-types';
import { reduxForm } from 'redux-form';
import { SaveButton } from 'react-admin';
const SaveButtonAware = ({ invalid, ...rest }) => (
<SaveButton disabled={invalid} {...rest} />
);
SaveButtonAware.propTypes = {
invalid: PropTypes.bool,
};
export default reduxForm({
form: 'record-form',
})(SaveButtonAware);
Update. Apparently, this is working too. Not sure why.
import React from 'react';
import PropTypes from 'prop-types';
import { SaveButton } from 'react-admin';
const SaveButtonAware = ({ invalid, ...rest }) => (
<SaveButton disabled={invalid} {...rest} />
);
SaveButtonAware.propTypes = {
invalid: PropTypes.bool,
};
export default SaveButtonAware;
You should first create a customized toolbar and set Save button's disabled element to Toolbars invalid state, as shown below. ( Toolbar always have the state of form)
import * as React from "react";
import {
Toolbar,
SaveButton
} from 'react-admin';
const CustomToolbar = (props) => (
<Toolbar {...props}>
<SaveButton disabled={props.invalid}/>
</Toolbar>
);
export default CustomToolbar;
Then use this customized toolbar in your form like shown below:
<SimpleForm redirect="list" toolbar={<CustomToolbar/>}>
{your form elements}
</SimpleForm>