storybook doesn't find components based on chakra-ui - reactjs

i was trying storybook and chakra ui.
Down below is how I structured my folders,
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/preset-create-react-app"
]
}
and this is my storybook config.
unluckly i receive an error, it seems like storybook doesn't find my components.
can someone help me to understand what's wrong ?
Why storybook doesn't find my components ?
-----------Update------------
this is the story that I tried to added
import React from 'react';
import {
Menu,
MenuButton,
} from '#chakra-ui/core';
export function MenuComp() {
return (
<Menu>
<MenuButton>Games</MenuButton>
</Menu>
);
}
MenuComp.storyName = 'test';

I started with an easier component and followed strictly the tutorial
i will wrote here a little guide that, I hope, will simplify the reader life.
1.I wrote a simple component in path "src/components/CustomButton"
import React, { FC } from 'react';
import { Button } from '#chakra-ui/core';
interface ButtonProps {
size: string | any;
variantColor: string;
}
const CustomButton: FC<ButtonProps> = ({ size, variantColor }) => (
<Button variantColor={variantColor} size={size}>
Button
</Button>
);
export default CustomButton;
2.I added the relative story component in "src/stories/CustomButton.stories.tsx
import React from 'react';
import CustomButton from 'components/CustomButton/index';
export default {
component: CustomButton,
title: 'CustomButton',
};
const Template = (args:any) => <CustomButton {...args} />;
export const Default: any = Template.bind({});
Default.args = {
size: 'md',
variantColor: 'green',
};
3.At this point it's really important configure your file preview.js that you will find the folder ".storybook", thanks to this commit chakraUiCommit i figured out how to include the theme provider in every storybook component
import React from 'react'
import {addDecorator} from '#storybook/react'
import {ThemeProvider, CSSReset} from '#chakra-ui/core'
addDecorator((storyFn) => (
<ThemeProvider>
<CSSReset />
{storyFn()}
</ThemeProvider>
))
well, at this point i solved my problem, and this is my final result

Related

react dynamic component type example

How/Where can i add types to the dynamic component Icons[name] ?
import * as Icons from "react-icons/fa";
const DynamicFaIcon = ({ name }: any) => {
const IconComponent = Icons[name];
return <IconComponent />;
};
You could just grap the keys from the import, since its a JS object like any other:
import * as Icons from "react-icons/fa";
const DynamicFaIcon = ({ name }: {name: keyof typeof Icons}) => {
const IconComponent = Icons[name];
return <IconComponent />;
};
I would be careful about importing literally everything from that package though. There's over 1,500 components in there, does any application actually make use of all of them? You'll end up bundling way more than you need.
This is my answer on dynamic icons problem, is it your question answer ?? , maybe it will help you, use it like this `
import React from 'react';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import {library} from '#fortawesome/fontawesome-svg-core';
import * as Icons from '#fortawesome/free-solid-svg-icons';
const iconList = Object.keys(Icons)
.filter((key) => key !== 'fas' && key !== 'prefix')
.map((icon) => Icons[icon]);
library.add(...iconList);
const Feature = ({ carFeature }) => {
console.log(carFeature);
return (
<div>
<FontAwesomeIcon icon={carFeature?.icon} color="#ddd" />
<h3>{carFeature?.name}</h3>
<p>{carFeature?.desc}</p>
</div>
);
};
export default Feature;
If no then try this
Not the OP's direct issue but for users encountering this error for libraries not under their control, one can suppress this error is by adding:
{
...
"suppressImplicitAnyIndexErrors": true,
...
}
to the tsconfig.json file.
Read more here Question Answer

How do I bundle MUI theme with rollup

I've been working on pulling our existing react FE components out of our main repo, and into a separate repo that I am bundling with rollup. Our old code was using makeStyles and I have been switching that over to styled-components but still keeping the previous MUI theme. I've setup storybook and am wrapping that in styled components theme provider, in order to access the theme inside the styled components.
The structure looks like
components
\src
index.ts(imports and exports components)
\theme(MUI theme)
\components
\buttons
button.tsx(react button code)
index.ts(imports and exports button)
\lib(rollup spits this out)
Finally, to the question. After I bundle everything with rollup, I do an NPM install, and import it into a different project. The problem is, I'm not getting the proper theming in the imported components. Here is a somewhat simplified version of my button.
import React from "react";
import { Button as MaterialButton, ButtonProps } from "#material-ui/core";
import styled from "styled-components";
export interface MyButtonProps extends ButtonProps {
error?: boolean;
target?: string;
}
const StyledButton = styled(MaterialButton)`
&.error {
background: ${(props) => props.theme.palette.error.main};
color: #fff;
&:hover {
background: ${(props) => props.theme.palette.error.main};
}
}
`;
const Button = ({
error,
className,
...rest}: MyButtonProps) => {
className += error ? " error" : "";
return (
<StyledButton
{...rest}
className={className}
>
{children}
</StyledButton>
);
};
export default Button;
So, if I put error attribute on the button, I do get the correct color from my theme. However, if I put color="primary" I do not get the correct color. I also don't have any of my base styles from the theme.
I haven't been able to figure out how to get this theme into the components I'm bundling with rollup. Finally, here is my rollup config.
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";
import svg from "rollup-plugin-svg-import";
const packageJson = require("./package.json");
export default {
input: "src/index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
sourcemap: true,
},
{
file: packageJson.module,
format: "esm",
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
svg(),
typescript({ useTsconfigDeclarationDir: true }),
postcss({
extensions: [".css"],
}),
],
};
For anyone who has stumbled upon this and is curious about the answer. Here is what I ended up doing. Hopefully this is the correct solution. One thing that is a bummer, I end up with MUI ThemeProvider giving me it's generated class names. This means in my styled components, I'll occasionally need to do this to target things [class^="MuiSvgIcon-root"], but maybe i can access the class through props, still messing with it. Anyway, here is the button.
import React from "react";
import { Button as MaterialButton, ButtonProps } from "#material-ui/core";
import styled from "styled-components";
import { ThemeProvider } from "#material-ui/core/styles";
import theme from "../../../theme";
export interface MyButtonProps extends ButtonProps {
error?: boolean;
target?: string;
}
const StyledButton = styled(MaterialButton)`
&.error {
background: ${theme.palette.error.main};
color: #fff;
&:hover {
background: ${theme.palette.error.main};
}
}
`;
const Button = ({
error,
size,
variant,
endIcon,
children,
className,
...rest
}: MyButtonProps) => {
if (className && error) {
className += " error";
} else if (!className && error) {
className = "error";
}
return (
<ThemeProvider theme={theme}>
<StyledButton
{...rest}
variant={variant}
size={size}
endIcon={endIcon}
className={className}
>
{children}
</StyledButton>
</ThemeProvider>
);
};
export default Button;
I guess each component will need to be wrapped.

Storybook not applying styles from .module.css file

I'm trying to use Storybook 6.1.20 for a very simple component in my project which uses Next.js, React and Typescript, however Storybook does not apply the styles that I have defined in my .module.css file. The styles are however applied when I start the project itself via npm run dev
This is my component that I want to display in Storybook (Rating.tsx):
import React from "react"
import ratingStyles from '../../../styles/Rating.module.css'
export interface RatingProps {
value: number
}
const Rating: React.FC<RatingProps> = ({value}) => {
return (
<span className={ratingStyles.text}>
{value}
</span>
)
}
export default Rating
The css file (Rating.module.css):
.text {
font-weight: 600;
font-size: 200px;
}
The story file (Rating.stories.tsx)
import React from 'react'
import { Story, Meta } from '#storybook/react';
import Rating, { RatingProps } from '../components/generic/Rating'
export default {
title: 'Rating',
component: Rating,
} as Meta
const Template: Story<RatingProps> = (args) => <Rating {...args}/>
export const FirstStory = Template.bind({})
FirstStory.args = {
value: 10
}

Is this only possible with external URLs and not local?

I'm trying to make a photo gallery using react-images, the URLs are correct but the photos themselves are not loading into my web app. I get the broken image icon when switching themodalIsOpen:false to true.
Ive tried looking up examples of the same problems and alternatives, like if the component was configured right or if I am extending it right in the class.
import React, { Component } from 'react';
import Carousel, { Modal, ModalGateway } from 'react-images';
import blksmith from '../images/gallery/illustration/Blacksmith.jpg';
import mage from '../images/gallery/illustration/Mage.jpg';
const images =
[
{
src:{blksmith}
} ,
{
src:{mage}
}
];
class illuGallery extends Component {
state = { modalIsOpen: false }
toggleModal = () => {
this.setState(state => ({ modalIsOpen: !state.modalIsOpen }));
}
render() {
const { modalIsOpen } = this.state;
return (
<ModalGateway>
{modalIsOpen ? (
<Modal onClose={this.toggleModal}>
<Carousel
views={images}
/>
</Modal>
) : null}
</ModalGateway>
);
}
}
export default illuGallery;
This is in the actual gallery.js file, the web page that renders the gallery.
import React from 'react';
import Layout from "../components/layout";
import IlluPhotos from "../components/illustrationGallery";
import SEO from "../components/seo";
import './gallery.scss';
const GalleryPage = () => {
return (
<Layout>
<div style={{width:'100%',height:'250px'}}>
<SEO title="Gallery" />
<IlluPhotos/>
</div>
</Layout>
)
}
export default GalleryPage;
I am seeking some feedback on how to get this to work and what I did wrong, or what I should explore more.
So I ended up adding the pictures I wanted for the gallery to the public folder as mentioned farther down in this post
Since the https://localhost:8000 was appearing in front of the links to the images I wanted to use.
Thank you all for helping me find the answer!!
You don't need to import images.
According to react-images documentation, you just need to pass path to image as a string to <Carousel> component, like in this example below:
import React from 'react';
import Carousel from 'react-images';
const images = [{ src: 'path/to/image-1.jpg' }, { src: 'path/to/image-2.jpg' }];
class Component extends React.Component {
render() {
return <Carousel views={images} />;
}
}

TS2604: When importing 'material-ui' button from one package to another

My team is implementing a new front-end for our application and has decided to switch from standard react to typescript. I am fairly new at developing and have been stuck on this issue for several days. Essentially we have two repositories, one that holds our components, and the other that ties them together for a front-end application. We connect these via lerna/yarn link.
The problem I face lies when importing our version of the material-ui button component from the other library and also applies to several other components. When doing so, it fails to compile.
The code in the component library compiles correctly. However we receive this error only when importing it to the other application.
I have tried several things to try to solve this issue, first modifying the Button.d.ts file within our dist/ folder within the component changing the type of ReactComponent exported, changing interface to class, etc. Second, modifying the tsconfig.json to include adjusting multiple options available via the documents, changing the "types" path, etc.
Here are what I believe to be the relevant files within the component library:
Button.d.ts:
import React from 'react';
import { ButtonProps as MuiButtonProps } from '#material-ui/core/Button';
export interface ButtonProps extends MuiButtonProps {
defaultMargin?: boolean;
classes: {
root: string;
};
}
declare const _default: React.ComponentType<Pick<React.PropsWithChildren<ButtonProps>, "disabled" || "mini" & import("#material-ui/core/styles").StyledComponentProps<"root">>;
export default _default;
Button.tsx:
import React, { Fragment } from 'react';
import clsx from 'clsx';
import { withStyles, createStyles } from '#material-ui/core/styles';
import { default as MuiButton, ButtonProps as MuiButtonProps } from '#material-ui/core/Button';
export interface ButtonProps extends MuiButtonProps {
defaultMargin?: boolean,
classes: {
root: string
}
};
const styles = () => createStyles({
root: {
margin: '1.5em'
}
});
const Button: React.SFC<ButtonProps> = (props: ButtonProps) => {
return (
<Fragment>
<MuiButton
className={clsx({
[props.classes!.root]: props.classes!.root
})} {...props}>
</MuiButton>
</Fragment>
)
};
Button.defaultProps = {
variant: 'contained',
color: 'primary',
size: 'medium',
disabled: false
};
export default withStyles(styles)(Button);
tsconfig.json:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"paths": { "*": ["types/*"] },
"outDir": "types"
},
"declaration": true,
"include": ["src", "types"],
"types": "dist/core/src/index.d.ts",
"main": "dist/index.js",
"files": [
"dist/core/src/index.d.ts"
]
}
And here within the main application library
App.tsx:
import React, { Component } from 'react';
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Button } from '#our-company/our-component-library-core'
import { Grid } from '#our-company/our-component-library-layout'
import { get } from 'lodash'
import './App.css';
import authenticationActions from '../reducers/authentication/actions'
import userActions from '../reducers/user/actions'
type Props = {
authDispatch: {
login: (args: any) => any,
logout: () => any
},
userDispatch: {
fetchUser: () => any
},
user: object
}
type State = {
count: number;
}
class App extends Component<Props, State> {
componentDidMount () {
this.props.authDispatch.login({email: 'email#email.com', password: '123456789'})
this.props.userDispatch.fetchUser()
this.props.authDispatch.logout()
}
render() {
const { user } = this.props
return (
<div className="App">
<header className="App-header">
<Grid container>
<Button variant="contained" color="primary">HELLO </Button>
<h1>{ get(user, ['user', 'attributes', 'email']) }</h1>
</Grid>
</header>
</div>
);
}
}
function mapStateToProps (state: any) {
const {
user
} = state
return {
user
}
}
function mapDispatchToProps (dispatch: any) {
return {
userDispatch: bindActionCreators(userActions, dispatch),
authDispatch: bindActionCreators(authenticationActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
I expect the code to compile, however it fails with a
ERROR in [at-loader] ./src/app/App.tsx:37:12
TS2604: JSX element type 'Button' does not have any construct or call signatures.
You are exporting a button component you have created:
const Button
The export is a default export:
export default withStyles(styles)(Button);
Whatever is the result of withStyles call, is not something that can be used as a JSX element.

Resources