How to insert JSX in Storybook control - reactjs

Running Storybook I'd like to navigate to my component and play with Docs tab and check its behavior as I change control value for each property. I implemented a component Footer that could receive string | JSX.Element | React.FunctionComponent types (I'm using TypeScript along ReactJS).
Unfortunately, when I type <div>my jsx</div> inside control field, a red border comes up pointing error and doesn't update the component in the preview as expected.
This is the screen I'm trying to insert into control field:
In the .stories.js file I have at the end:
export const Default = Template.bind({});
Default.args = {
subscribe: "Replace me by the Subscribe component of Design System.",
brand: <figure>Put branding logo here!</figure>,
links: <div><div>first column of links</div><div>second column of links</div></div>,
bottom: "All rights reserved."
}
The Links text is the default value for link property (from the actual React component file). As the code and image above can show us, it seems the JSX argument passed on Default.args in .stories.js file is completely ignored.
I'd like to insert a JSX into control field of storybook playground and then get Footer component live updated with JSX component rendered in the preview. How can I achieve that?

Related

import { styled } from '#mui/material/styles'; displayName not showing

Using Mui styled function to style both jsx elements and MUI components. The displayName is not showing when I debug the element in Chrome or any browser for that matter.
Anyone know how to fix this.
I'm using Vite for my setup.
const MyComponent = styled('div')`
display: flex;
`;
As you can see from the below screenshot its not showing MyComponent display name instead its showing css-1vht943
You can see class only inside the Element tab. When you click on one of the lines which contains the class name.
You can find all the CSS related to that class under the styles tab including display name for your case. Please check the image below
If you want to have a name I think you can use styled('div', { name: 'MyTheme'}), then you will see something like <div class="css-t7mscw-MyTheme-root"></div>. Don't know if this is what you want, but here it is vaguely mentioned in the doc.

Storybook - How to set preview layout centered for only some components, not for all components

I am building storybook and have following problem.
I want to set layout centered in preview.
I tried
export const parameters = {
layout: 'centered',
};
in the .storybook/preview.js
But this sets layout centered for all components.
Is there any good way to show in center for only some components?
The Storybook documentation contains a section for component level layout.
Instead of configuring it globally in the preview, you can add it to the individual story file.
// *.stories.js|jsx|ts|tsx
export default {
// Other config options...
// Sets the layout parameter component wide.
parameters: {
layout: 'centered',
},
};

Description and default value not appearing in Storybook when rendering React/Mui components

I'm using Storybook v6.5.9 to render out my React/MUI components. Everything works fine, but I can't get the description or default value to appear in the canvas under the Controls tab:
The description appears fine when looking at the Docs tab:
There's nothing in the default export and I haven't changed any default options out of the box.
According to the React Storybook docs under controls here
Under the directory of .storybook/preview.js
We need to add the following under controls key
export const parameters = {
.....
controls: {
expanded: true
}
.....
}
This ensures that each control is viewed in expanded mode globally (both in Canvas and Docs tabs)

Passing properties from DropzoneArea to Dropzone

I am using DropzoneArea:
import { DropzoneArea } from 'material-ui-dropzone';
which is based on react-dropzone.
Dropzone from:
import Dropzone from 'react-dropzone'
contains certain props, not exposed by DropzoneArea but available by Dropzone
For instance disabled.
I have several question regarding it:
When I create DropzoneArea component, is there a way to mark it as disabled?
Is there a way to pass original properties of Dropzone
And here is an original issue I try to solve, probably the solution is not the best one and there are alternatives:
When a user uploads a file to DropzoneArea, I can send it to the server via onChange handler. I'd like to disable the whole component, while server is processing a file, until we get a response back.
The DropzoneArea has the property dropzoneProps, which is an object that is being passed (as props) to the Dropzone:
<DropzoneArea
dropzoneProps={ { disabled: true} }
...
/>

How to get Material UI Icon SVG path? React Icon Picker

I have a react application using Material UI's Icons. The main objective is to have an Icon Picker, where a user can select a MUI Icon and that selected icon's SVG path is saved within the state.
This svg path will then be saved out to an API where it can be displayed in various places. etc.
I've searched through documentation on MUI's site regarding icons, but it's all about implementation, which I can do just fine. I've looked for an npm package, without much luck.
I did come across this package (https://github.com/DMDc0de/material-ui-icon-picker), which is essentially what I'd like the picker to be - but it outputs the icon's name for an icon component <i />. Not what I want. I need the source of the SVG path.
Any direction towards this would be super helpful.
Go to the icon site: https://material.io/tools/icons/
Click on an icon
Click on "Selected icon" button (bottom left)
Click on the "SVG" button to download the SVG version
Alternatively, go to the GitHub repo and download the SVGs there.
One way of doing that programmatically is to load the component and to render it in a string. Then to extract the path from the string.
To do so, we can use the renderToString or renderToMarkupString method of ReactDomServer.
Than we can extract the path from the generated string. We can either parse the svg XML with the DOMParser or with a regexp.
Here's an example in TypeScript:
import EditIcon from '#material-ui/icons/Edit';
import ReactDOMServer from 'react-dom/server';
export function getEditIconPath(): string {
const iconString = ReactDOMServer.renderToString(<EditIcon />);
const parser = new DOMParser();
const svgDoc = parser.parseFromString(iconString, 'image/svg+xml');
const iconPath = svgDoc.querySelector('path')?.getAttribute('d') as string;
return iconPath;
}
Another way to achieve that would be to use the React Test Renderer, thus we can get directly a json including the different properties (including the path). However, it looks like this method is around 10 times slower than the previous method.
Here's an example with the second method:
import EditIcon from '#material-ui/icons/Edit';
import TestRenderer from 'react-test-renderer'; // ES6
export function getEditIconPath(): string {
const iconComponent = TestRenderer.create(<EditIcon />);
const iconJson = iconComponent.toJSON();
const path = iconJson.children[0].props.d;
return path;
}

Resources