mui5 - TypeError: Cannot read properties of undefined (reading '__emotion_styles') - material-ui

I copied this code from official example:https://mui.com/material-ui/react-stepper/
import { styled } from '#mui/material/styles';
import { StepConnector, stepConnectorClasses } from '#mui/material/StepConnector';
const QontoConnector = styled(StepConnector)(({ theme }) => ({
[`&.${stepConnectorClasses.alternativeLabel}`]: {
top: 10,
left: 'calc(-50% + 16px)',
right: 'calc(50% + 16px)',
},
but I get the error
TypeError: Cannot read properties of undefined (reading '__emotion_styles')

The problem lies in your second line.
Change it to this:
import StepConnector, { stepConnectorClasses } from '#mui/material/StepConnector';

Related

Module "punycode" has been externalized for browser compatability

I am trying to use the '#ensdomains/eth-ens-namehash' package to hash an input.
I am using it in combination with 'pinia'.
I call on this method in Nuxt3.
This is the code:
import { defineStore } from "pinia"
import namehash from "#ensdomains/eth-ens-namehash"
import { Buffer } from 'buffer'
export const exampleMethod = defineStore('example', {
state: () => {
return{
hash: String
}
},
actions: {
method(input) {
globalThis.Buffer = Buffer
this.hash = namehash.hash(input).toString()
}
}
}
When trying to call 'method' I get the following error:
Uncaught (in promise) Error: Module "punycode" has been externalized
for browser compatibility. Cannot access "punycode.ucs2" in client
code.

Unable to pass props to makeStyles when using material UI with next.js

I am using Next.js with material UI.
I have created a Icon and when clicked it calls the setOpenFn() and sets the open variable to be true. This variable is then passed as props to the useStyles(). Now I display the search bar if open is true. But I get the below error
webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:67 Warning: Prop `className` did not match. Server: "makeStyles-search-3 makeStyles-search-8" Client: "makeStyles-search-3 makeStyles-search-9"
When the search Icon is clicked display: flex property is also not working.
I tried to create .babelrc file and added this
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
but still nothing works.
const useStyles = makeStyles((theme) => ({
search: {
[theme.breakpoints.down('sm')]: {
display: (props) => (props.open ? 'flex' : 'none'),
width: '70%',
},
}
}))
const Navbar = () => {
const [open, setOpen] = useState(false);
const setOpenFn = () => {
setOpen(true);
};
const classes = useStyles({ open });
return(
<Search
className={classes.searchButton}
onClick={() => {
setOpenFn();
}}
/>
)
}
I am assuming you are using mui version 5+
According to this migration guide! you need to wrap your JSX with the following component.
<StyledEngineProvider injectFirst>
</StyledEngineProvider>

How to await an auth object with hooks? (MongoDB Stitch in React Native)

I am using React Native to build an app that relies on MongoDB Stitch for authentication. More often than not, the app crashes because the client object has not yet loaded when I use it in the following line of code. The error I get is the infamous TypeError: undefined is not an object followed by evaluating 'client.auth.user'.
import React from 'react';
import { View, Text } from 'react-native';
import { Stitch } from 'mongodb-stitch-react-native-sdk';
const APP_ID = '<my app ID>';
const client = Stitch.hasAppClient(APP_ID)
? Stitch.getAppClient(APP_ID)
: Stitch.initializeDefaultAppClient(APP_ID);
const { user } = client.auth;
const Home = () => {
return (
<View style={styles.home}>
<Text>HOME</Text>
<Text>Hi {user.profile.data.email}</Text>
</View>
);
};
export default Home;
const styles = {
home: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
};
The example provided with the MongoDB Stitch NPM package uses componentDidMount (see here), but I am trying to make this work using Hooks. I have tried useEffect, a bunch of if statements, async/await, placing the object in state with useState; No luck.
So yeah, you can use useEffect hook to instantiate the client and get the user info.
useEffect(() => {
_loadClient();
}, []);
const [client,setClient] = useState({});
const [user,setUser] = useState({});
_loadClient() {
Stitch.initializeDefaultAppClient('<your-client-app-id>').then(client => {
setClient(client);
if(client.auth.isLoggedIn) {
setUser( client.auth.user)
}
});
}
That should do it.

trying to generate a PDF and view or email it with React Native

I spent the last few days playing with react-native-html-to-pdf (https://github.com/christopherdro/react-native-html-to-pdf ), react-native-mail (by chirag04) and react-native-view-pdf (by cnjon)
There is another version of react-native-mail by parkerdan that I have yet to try, but the chrirag04's version basically corrupted all my projects and was a pain to uninstall.
react-native-html-to-pdf doesn't seem to generate any error, and I can't seem have access to the pdf generated. here a snippet of the code I am running:
import RNHTMLtoPDF from 'react-native-html-to-pdf';
import PDFView from 'react-native-pdf-view';
...
createPDF() {
var options = {
html: '<h1>PDF TEST</h1>', // HTML String
// ****************** OPTIONS BELOW WILL NOT WORK ON ANDROID **************
fileName: 'test', /* Optional: Custom Filename excluded extention
Default: Randomly generated
*/
directory: 'docs', /* Optional: 'docs' will save the file in the `Documents`
Default: Temp directory
*/
height: 800, /* Optional: 800 sets the height of the DOCUMENT that will be produced
Default: 612
*/
width: 1056, /* Optional: 1056 sets the width of the DOCUMENT that will produced
Default: 792
*/
padding: 24, /* Optional: 24 is the # of pixels between the outer paper edge and
corresponding content edge. Example: width of 1056 - 2*padding
=> content width of 1008
Default: 10
*/
};
RNHTMLtoPDF.convert(options).then((filePath) => {
AlertIOS.alert(
'creat pdf',
'filePath=' + filePath
);
return (
<PDFView ref={(pdf)=>{this.pdfView = pdf;}}
src={filePath}
onLoadComplete = {(pageCount)=>{
this.pdfView.setNativeProps({
zoom: 1.5
});
}}
/>
)
});
};
and later in the code I call it with:
<TouchableHighlight onPress={this.createPDF} style={styles.button}>
<Text>create pdf </Text>
</TouchableHighlight>
I get the AlertIOS, with something that looks like a valid filepath (any hint to check the path is correct, let me know)
But that's it, I don't seem to find the test.pdf document anywhere.
Can anyone tell what I am doing wrong?
Many Thanks,
Cheufte
I think the file path is document directory you can go through the file path by first clicking the windows option in xcode after that find devices option upon clicking device option all the information of your device will appear then select the application and see it's container and you will find your pdf file.
var localpath= RNFS.DocumentDirectoryPath + filePath
<PDFView ref={(pdf)=>{this.pdfView = pdf;}}
path={localpath}
onLoadComplete = {(pageCount)=>{
this.pdfView.setNativeProps({
zoom: 1.5
});
}}
/>
write path in place of src because it is deprecated.
import React, { Component } from 'react';
import {
AlertIOS,
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
View
} from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
export default class testApp extends Component {
createPDF() {
var options2 = {
html: '<h1>PDF TEST</h1>', // HTML String
// ****************** OPTIONS BELOW WILL NOT WORK ON ANDROID **************
fileName: 'test2', /* Optional: Custom Filename excluded extension
Default: Randomly generated
*/
directory: 'docs', /* Optional: 'docs' will save the file in the `Documents`
Default: Temp directory */
base64: true ,
height: 800,
width: 1056, /* Optional: 1056 sets the width of the DOCUMENT that will produced
Default: 792
*/
padding: 24, /* Optional: 24 is the # of pixels between the outer paper edge and
corresponding content edge. Example: width of 1056 - 2*padding
=> content width of 1008
Default: 10
*/
};
RNHTMLtoPDF.convert(options2).then((data2) => {
console.log(data2.filePath);
console.log(data2.base64);
AlertIOS.alert(
'options2 filename' + options2.fileName,
'data2 filePath=' + data2.filePath
);
});
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to testApp
</Text>
<TouchableHighlight onPress={this.createPDF}>
<Text>Create PDF</Text>
</TouchableHighlight>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('testApp', () => testApp);

How to pass context down to the Enzyme mount method to test component which includes Material UI component?

I am trying to use mount from Enzyme to test my component in which a several Material UI component are nested. I get this error when running the test:
TypeError: Cannot read property 'prepareStyles' of undefined
After some digging, I did found that a theme needs to be passed down in a context. I am doing that in the test but still get this error.
My test:
import expect from 'expect';
import React, {PropTypes} from 'react';
import {mount} from 'enzyme';
import SearchBar from './SearchBar';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
function setup() {
const muiTheme = getMuiTheme();
const props = {
closeSearchBar: () => {},
fetchSearchData: () => {},
data: [],
searching: false
};
return mount(<SearchBar {...props} />, {context: {muiTheme}});
}
describe('SearchBar Component', ()=> {
it('Renders search toolbar properly', () => {
const wrapper = setup();
expect(wrapper.find('.toolbar').length).toBe(1);
expect(wrapper.find('button').length).toBe(1);
});
});
My searchbar component is a stateless component, so I am not pulling in any context. But even when I am, I still get the same error.
What am I doing wrong?
Try adding childContextTypes in the mount options:
return mount(
<SearchBar {...props} />, {
context: {muiTheme},
childContextTypes: {muiTheme: React.PropTypes.object}
}
);
By doing it you set the Enzyme wrapper to make the muiTheme available to it's children through the context.
this is my handy method to test Material UI with shallow and mount
...
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme';
const muiTheme = getMuiTheme();
const shallowWithContext = (node) => shallow(node, {context: {muiTheme}, childContextTypes: {muiTheme: PropTypes.object}});
const mountWithContext = (node) => mount(
node, {context: {muiTheme}, childContextTypes: {muiTheme: PropTypes.object}}
);
// now you can do
const wrapper = shallowWithContext(<Login auth={auth} onChange={() => 'test'} />);