stories .mdx doesn't load properly in react storybook project - reactjs

I am working on a storybook project and here is a story of a sample component (sample.stories.mdx):
import Sample from './index';
import { ComponentStory, ComponentMeta } from '#storybook/react';
import { Canvas, Meta, Story, ArgsTable } from '#storybook/addon-docs';
<Meta title='Molecules/Sample' component={Sample} />
export const Template = (props) => <Sample {...props} />;
export const props = {
label: 'Sample',
children: 'Click me'
};
<Canvas>
<Story name='Default' args={props}>
{Template.bind({})}
</Story>
</Canvas>
<ArgsTable story='Default' />
But every time I start the project, it shows the following error:
./components/molecules/Sample/Sample.stories.mdx: Module parse failed: Unexpected token (5:64)
You may need an appropriate loader to handle this file type, currently no loaders are
configured to process this file
Can anyone help? Is this mdx file correct?
Thanks in advance.

Related

Import markdown files dynamically with Vite

I'm looking for a solution that lets me render markdown dynamically, based on the query string. At the moment I render markdown like this, in React + Vite:
import some other stuff...
import { useParams } from 'react-router-dom';
import { ReactComponent } from '../content/blog1.md';
const BlogPost = () => {
const params = useParams();
return (
<Base>
<PageTitle title={`title of blog ${params.blogId}`} />
<ReactComponent />
</Base>
);
};
export default BlogPost;
What I would like is to pass the blogId to the import path like:
import { ReactComponent } from `../content/blog${params.blogId}.md`
Such that the correct file is imported on each /blog/* route. I tried this by lazy loading the markdown like:
const path = `../content/blog${params.blogId}.md`;
const Markdown = React.lazy(() => import(path));
But this raises errors and when I log Markdown I see
{$$typeof: Symbol(react.lazy), _payload: {…}, _init: ƒ}
$$typeof: Symbol(react.lazy)
_init: ƒ lazyInitializer(payload)
_payload: {_status: -1, _result: ƒ}
Which appears to be empty. What would be a solution to accomplish this?
I had also issue when importing assets. In my case .md import failed.
import Article from './assets/article.md';
Failed to parse source for import analysis because the content
contains invalid JS syntax. You may need to install appropriate
plugins to handle the .md file format, or if it's an asset, add
"**/*.md" to assetsInclude in your configuration
So I solved it adding assetsInclude: ['**/*.md'] setting to vite.config.js (for my .md files)
export default defineConfig({
...
plugins: [react()],
assetsInclude: ['**/*.md']
...
})
Eventually this started to work:
import("./assets/article.md").then(res => {
fetch(res.default)
.then(response => response.text())
.then(text => console.log(text))
})
Docs are here:https://vitejs.dev/guide/assets.html
Hope it helps.
Cheers.

Gatsby language localization Mdx files with gatsby-plugin-intl

I am trying to localize pages with gatsby-plugin-intl. No problem for .js files as I described below but how should I make it for .mdx files?
import React from "react"
import { FormattedMessage, injectIntl, navigate } from "gatsby-plugin-intl"
const MyPage = ( {intl} ) => (
<Layout>
<h2><FormattedMessage id="TITLE"/></h2>
</Layout>
)
export default injectIntl(MyPage)
I am trying to make the similar logic here:
---
name: Settings
route: /documentation/settings
---
import { Playground, Props } from 'docz'
import { useIntl, Link, FormattedMessage } from "gatsby-plugin-intl"
const intl = useIntl()
## Settings
intl.formatMessage({ id: "TITLE"})
every think look right but you have an error on the mdx file
const intl = useIntl()
use the FormattedMessage components instead message
example
<FormattedMessage id="TITLE" />
or your components
<Yourcomponents title={useIntl().formatMessage({ id: "TITLE" })} />
don't use const

How to make a stories.mdx file in Storybook?

I would like to add documentation alongside my components in Storybook thanks to markdown syntax. I've followed Storybook's guidelines, but when launching the app, I receive the following error in my terminal:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory. (...) Command failed with signal "SIGABRT".
Here is my storybook config:
// main.ts
module.exports = {
stories: ["../**/stories.tsx", "../**/stories.mdx"],
addons: [
{
name: "#storybook/addon-essentials",
options: { backgrounds: false, docs: false, viewport: false },
},
"storybook-addons-abstract/register",
],
};
// webpack.config.js
module: {
rules: [
{ test: /\.mdx?$/, use: ["babel-loader", "#mdx-js/loader"]}
//... + all necessary loaders such as ts-loader, etc.)
]
}
My component:
import React from "react";
export default function Text({ content }) {
return <h1>{content}</h1>;
}
And the story (stories.mdx):
import { Story, Meta, Canvas } from "#storybook/components";
import Text from ".";
<Meta title="MDX/Text" component={Text} />
# Checkbox
Here is the text component:
<Canvas>
<Story name="defaut">
<Text text="hello" />
</Story>
</Canvas>
How to fix this?
Try to do it this way:
import { Story, Meta, Canvas } from "#storybook/components";
import Text from ".";
<Meta title="MDX/Text" component={Text} />
export const Template = (args) => <Text {...args} />
# Checkbox
Here is the text component:
<Canvas>
<Story name="Primary" args={{ text: 'hello' }}>
{Template.bind({})}
</Story>
</Canvas>
import Text from ".";
I think this might be where the problem is, seems like it's an infinite loop

Jest - unexpected identifier - Component testing w Jest react-native

I keep getting this error when trying to test a button component. I have changed Jest's config settings here and there but nothing has worked, can anyone tell me the answer so I can stop pulling my hair out?
I am using expo to demo the app, the problem seems to lie within the font that it's trying to render on the nav button, Jest/React doesn't understand it.
The failure:
FAIL tests/Components/NavigationButton.test.js
● Test suite failed to run
C:\..\node_modules\#expo\vector-icons\Zocial.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Zocial from './build/Zocial';
^^^^^^
SyntaxError: Unexpected identifier
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (node_modules/react-native-elements/src/helpers/getIconType.js:1:1)
NavigationButton.js:
import React from "react";
import { StyleSheet } from "react-native";
import { Button } from "react-native-elements";
import Icon from "react-native-vector-icons/FontAwesome";
import { withNavigation } from 'react-navigation';
const NavigationButton =(props) => {
return (
<Button data-test="nav_button"
icon={<Icon name={props.icon} size={30} color="white" style={styles.iconStyle} />}
raised
color="white"
buttonStyle={styles.button}
title={props.title}onPress={() => props.navigation.navigate(props.navName)}
/>
);
};
const styles = StyleSheet.create({
button: {
minWidth:150,
alignSelf:'center',
},
iconStyle:{
marginHorizontal:10
}
});
export default withNavigation(NavigationButton);
NavigationButton.test.js:
/**
* #format
*/
import 'react-native';
import React from 'react';
import { shallow } from 'enzyme';
import { findByTestAtt } from '../../Utils/test_utils';
import NavigationButton from '../../src/Components/NavigationButton'
// Note: this is just for use with Jest snapshot testing
// and comes packaged with react-native init project.
// You do not need this if using Enzyme 'toMatchSnapshot' etc.
import renderer from 'react-test-renderer';
// setup for shallow rendering component, saves having to do it in every test in this file
const setup = (props = {}) => {
const component = shallow(<NavigationButton {...props} />);
return component;
};
describe('NavigationButton tests: ', () => {
let component;
beforeEach(() => {
component = setup();
});
it('Button renders correctly: ', () => {
console.log(component.debug());
const wrapper = findByTestAtt(component, 'nav_button');
expect(wrapper.length).toBe(1);
});
});
Using the jest-expo preset solved the problem for me. The documentation explains it well: https://www.npmjs.com/package/jest-expo. The issue seemed to be that the import keyword wasn't being transformed, I'm not clear on why but it came up in an issue here: https://github.com/expo/expo/issues/5296

error in displaying pdf in react-pdf

I am new new to react, I am trying to display a pdf file on browser. I am getting an error as failed to load PDF. I am trying to run the sample program given in https://www.npmjs.com/package/react-pdf.
App.js
import React, { Component } from 'react';
import { Document, Page } from 'react-pdf';
class MyApp extends Component {
state = {
numPages: null,
pageNumber: 1,
}
onDocumentLoad = ({ numPages }) => {
this.setState({ numPages });
}
render() {
const { pageNumber, numPages } = this.state;
return (
<div>
<Document
file="./1.pdf"
onLoadSuccess={this.onDocumentLoad}
>
<Page pageNumber={pageNumber} />
</Document>
</div>
);
}
}
export default MyApp;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Error screenshot
Question is old but hope this help someone. I faced this issue and found a solution here https://github.com/wojtekmaj/react-pdf/issues/321.
import { Document, Page, pdfjs } from 'react-pdf';
Add this to your constructor.
constructor(props){
super(props);
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
}
You load the file using file="./1.pdf" I believe that might be the problem.
If you have a file structure like:
src
App.js
components
ShowPdfComponent.js
1.pdf
public
bundle.js
Then you need to move the 1.pdf to public folder like this:
src
App.js
components
ShowPdfComponent.js
public
bundle.js
1.pdf
Because when your compiled javascript code is being executed from public/bundle.js and bundle.js does not know how to get to src/components/1.pdf in file system.
There might be also a difference between production/development environment if you are using webpack and webpack-dev-server.
Look at react-pdf example. It has flat file structure. That is the reason why it works.
if you are using create-react-app then you need to import differently like
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'
because it uses webpack under the hood.
You can import the pdf file using import samplePdf from './1.pdf' and can use directly like file={samplePdf} in your Document tag.
Here is the minimum setup you need to be able to display your pdf in react TypeScript:
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
const YourComponentReact = ({url}: {url: string}) => {
return (<Document file={url}>
<Page pageNumber={1} />
</Document>)
}
You can add a quick button if you want to be able to change pages
You only need to download react-pdf and #types/react-pdf if you use typescript.
adding pdfjs to import and using it like this hellped
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
in the same file i need to show my pdf

Resources