How to write an mdx story for react component? - css

I have created simple image component and imported the image. Now, I would like to display it with storybook, but not sure how to pass this component correctly inside a story.mdx file. Could you please help?
Here is the image component:
import { string, urlPropType } from "prop-types"
import * as Styled from "./Image.styled"
import image from "./image/cutedog.jpg"
const Image = ({ src, alt }) => (
<Styled.Image>
<img src={image} alt={dog} />
</Styled.Image>
)
Image.propTypes = {
src: urlPropType.isRequired,
alt: string.isRequired,
}
export default Image
here is styled.component:
import styled from "#emotion/styled"
export const Image = styled.div`
display: inline block;
float: left;
width: 100%;
border radius: 5rem;
`
And I already started to write mdx story, but it si not working so far :(
import { Meta, Canvas, Story, ArgsTable } from "#storybook/addon-docs"
import Image from "../Image"
<Meta title="Components/Image" component={Image} />
# Image
<Canvas>
<Story
name="Overview"
args={{
src: "arrowDown",
alt: "medium",
}}
>
{Template.bind()}
</Story>
</Canvas>
<ArgsTable />
export const Template = (args) => <Image {...args} />
maybe someone could help ?

Related

Can't get google fonts to work with styles components and ReactJS

I have tied everything and I cannot get google fonts to render when using styled components. It always shows the default sans-serif. I have tried to use other google fonts too but have had no success.
In my header.styles.jsx I have:
export const Title = styled.div`
#import url('https://fonts.googleapis.com/css2?family=Dancing+Script&display=swap');
font-size: 72px;
font-family: 'Dancing Script', sans-serif;
`;
and here is where I try and use it:
import { Title } from './header.styles';
const Header = ({ hidden }) => {
return (
<sc.HeaderContainer>
<sc.LogoContainer to={'/'}>
<Logo className={'logo'} />
</sc.LogoContainer>
<Title>
My Title Here
</Title>
<sc.OptionsContainer style={{ paddingRight: '80px' }}>
<sc.OptionLink to={'/shop'}>SHOP</sc.OptionLink>
<sc.OptionLink to={'/contact'}>CONTACT</sc.OptionLink>
<UserMenu />
<CartIcon />
</sc.OptionsContainer>
{hidden ? null : <CartDropdownContainer />}
</sc.HeaderContainer>
);
};
I suggest you to set a link tag inside index.html to import the font, or following the below:
https://pt.stackoverflow.com/questions/428287/como-utilizar-fontes-customizadas-no-react

react-images: image in carousel not centred

I would like to center the selected image instead of having it showing on the left hand side.
See image of behaviour:
I'm using the packages from the sandbox below in Next.js 11 with TailwindCSS 2.2.4:
https://codesandbox.io/s/5vn3lvz2n4
Dependencies:
"react-images": "^1.2.0-beta.7",
"react-photo-gallery": "^8.0.0"
I'm having a hard time targeting the CSS class, but I narrowed down to:
class="react-images__view react-images__view--isModal css-1qrom1v css-1ycyyax" using the browser dev tool in Safari.
Below is my PhotoLibrary file:
import React, { useState, useCallback } from "react";
import Gallery from "react-photo-gallery";
import Carousel, { Modal, ModalGateway } from "react-images";
import { photos } from "../data/photoData";
export default function PhotoLibrary() {
const [currentImage, setCurrentImage] = useState(0);
const [viewerIsOpen, setViewerIsOpen] = useState(false);
const openLightbox = useCallback((event, { photo, index }) => {
setCurrentImage(index);
setViewerIsOpen(true);
}, []);
const closeLightbox = () => {
setCurrentImage(0);
setViewerIsOpen(false);
};
return (
<div>
<Gallery photos={photos} onClick={openLightbox} />
<ModalGateway>
{viewerIsOpen ? (
<Modal onClose={closeLightbox}>
<Carousel
currentIndex={currentImage}
views={photos.map((x) => ({
...x,
srcset: x.srcSet,
caption: x.title,
}))}
/>
</Modal>
) : null}
</ModalGateway>
</div>
);
}
Has anyone played around with the carousel in Next.js and able to see what I'm doing wrong? If you have a better solution I'm open to that too.
Add the following CSS to your globals.css file.
.react-images__view-image--isModal {
display: inline-block;
left: 50%
}

Theme with React and Redux

i am trying to make a theme system on a react project that uses redux with a reducer that manages themes according to the user's local storage. But here my problem is that I used css files to define my styles on all of my components. However, I have all my logic with 2 javascript objects for light or dark mode. So I can't use js in css files unless I use css variables but I don't know how.
Here is my structure :
In my app.js I imported useSelector and useDispatch from react redux to access the global state :
import React from 'react';
import './App.css';
import Footer from './components/Footer';
import Header from './components/Header';
import Presentation from './components/Presentation';
import Projects from './components/Projects';
import Skills from './components/Skills';
import Timeline from './components/Timeline';
import { switchTheme } from './redux/themeActions';
import { useSelector, useDispatch } from 'react-redux';
import { lightTheme, darkTheme } from './redux/Themes';
function App() {
const theme = useSelector(state => state.themeReducer.theme);
const dispatch = useDispatch();
return (
<div className="App">
<Header />
<input type='checkbox' checked={theme.mode === 'light' ? true : false}
onChange={
() => {
if(theme.mode === 'light') {
dispatch(switchTheme(darkTheme))
} else {
dispatch(switchTheme(lightTheme))
}
}} />
<div className="top">
<div className="leftPart">
<Presentation />
<Skills />
</div>
<Timeline />
</div>
<Projects />
<Footer />
</div>
);
}
export default App;
and in themes.js I have my 2 objects which represent the themes :
export const darkTheme = {
mode: 'dark',
PRIMARY_BACKGROUND_COLOR: '#171933',
SECONDARY_BACKGROUND_COLOR: '#1e2144',
TERTIARY_BACKGROUND_COLOR: '#0a0c29',
PRIMARY_TEXT_COLOR: '#eee',
SECONDARY_TEXT_COLOR: '#ccc',
PRIMARY_BORDER_COLOR: '#aaa'
}
export const lightTheme = {
mode: 'light',
PRIMARY_BACKGROUND_COLOR: '#D3CEC8',
SECONDARY_BACKGROUND_COLOR: '#E5DFD9',
TERTIARY_BACKGROUND_COLOR: '#C1BFBC',
PRIMARY_TEXT_COLOR: '#222',
SECONDARY_TEXT_COLOR: '#333',
PRIMARY_BORDER_COLOR: '#555'
}
You can make use of data attributes.
I have done the same in one my project like so :-
[data-color-mode="light"] {
--color-focus-ring: #7daee2;
--color-link-hover: #0039bd;
--color-primary-bg: #eef6ff;
--color-primary-text: #212121;
--color-primary-border: #98b2c9;
--color-secondary-bg: #c3d7f0;
--color-secondary-text: #1a1a1a;
}
[data-color-mode="dark"] {
--color-focus-ring: #5355d4;
--color-link-hover: #4183c4;
--color-primary-bg: #080808;
--color-primary-text: #f1f1f1;
--color-primary-border: #525252;
--color-secondary-bg: #191919;
--color-secondary-text: #d8d5d5;
}
You can add the attribute to your top-level element (assuming div) like so:-
<div className="appContainer" data-color-mode="light" ref={appRef}> ></div>
Now use that appRef to change the data-color-mode attribute as well update the localstorage in one function. Updating the data-color-mode allows you to toggle between css variable colors easily. In my code, I have done this the following way:-
const toggleColorMode = () => {
const nextMode = mode === "light" ? "dark" : "light";
// container is appRef.current only
container?.setAttribute("data-color-mode", nextMode);
setMode(nextMode);
};
I am not using redux for this. Simply React Context API is being used by me but it's doable in your scenario as well.
You can take more reference from the repo - https://github.com/lapstjup/animeccha/tree/main/src
Note - I think there are other routes where people go with CSS-IN-JS but I haven't explored them yet. This solution is one of the pure css ways.
Fun fact - Github has implemented their newest dark mode in a similar way and that's where I got the idea as well. You can inspect their page to see the same attribute name :D.

svg image not showing on react.js

I have been following a YouTube tutorial for making a website using react.js.
index.js:
import { Img, ImgWrap } from './InfoElements';
const InfoSection = ({ img, alt)} => {
return(
<>
<ImgWrap>
<Img src={img} alt={alt}/>
</ImgWrap>
</>
)
}
export default InfoSection
I have been exporting image src from another folder named Data.js
Data.js:
export const homeObjOne = {
img: require("../../images/svg-1.svg"),
alt: 'error404'
}
I used styled-components for style
InfoElements.js:
export const ImgWrap = styled.div`
max-width: 555px;
height: 100%;
`;
export const Img = styled.img`
width: 100%;
margin: 0 0 10px 0;
padding-right: 0;
`;
Here image is placed on
src->images->svg-1.svg
I tried using other images like jpe, jpg and png rather than svg but still its not working. The image is not showing on background.
Here is the picture the way image return:
Here is the path of image folder:
I have been tried all other image format and result is same..Is their anything I done wrong
Your structure is falling victim to a default export naming issue. When you require your image in Data.js, you're setting it as a module. If you want to access the URL of the image, you need to use:
export const homeObjOne = {
img: require("../../images/svg-1.svg").default, //note the default part at the end
alt: 'error404'
}
Although this could be made cleaner using imports:
import homeObjOne from "../../images/svg-1.svg";
export const homeObjOne = {
img: homeObjOne, //no need for default here, thanks to import
alt: 'error404'
}
Note: If you inspect your image whilst it is broken, you'll see the src will be [object Object].
Follow this article https://www.freecodecamp.org/news/unable-to-find-images-based-on-url-in-react/.
Move images folder under /public not /src.
In data.js
img: "./images/svg-1.svg"
Or use you can use import, like this import image1 from "./images/1.jpg

Styling material UI components

Not really a problem but something I’m not happy with. I'm using react + typescript + css modules + https://material-ui-next.com/. Problem is that when I need to style material ui components I have to use !important a lot. Question is if there is a way to create styles without important. I create a sample project to reproduce the problem https://github.com/halkar/test-css-modules
material-ui exposes many of their components for styling. There two ways to go about doing this.
Apply styles globally
You could style the components globally and apply it to the theme. An example of this would be something like this (copied from the docs http://www.material-ui.com/#/customization/themes):
import React from 'react';
import {cyan500} from 'material-ui/styles/colors';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import AppBar from 'material-ui/AppBar';
// This replaces the textColor value on the palette
// and then update the keys for each component that depends on it.
// More on Colors: http://www.material-ui.com/#/customization/colors
const muiTheme = getMuiTheme({
palette: {
textColor: cyan500,
},
appBar: {
height: 50,
},
});
class Main extends React.Component {
render() {
// MuiThemeProvider takes the theme as a property and passed it down the hierarchy
// using React's context feature.
return (
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar" />
</MuiThemeProvider>
);
}
}
export default Main;
As you can see in here, appBar component have a height of 50px meaning that every time you add an appbar component to your app down the tree where you applied the muiTheme, it will give it a height of 50px. This is a list of all the styles you can apply for each component https://github.com/callemall/material-ui/blob/master/src/styles/getMuiTheme.js.
Apply styles using style attribute
To apply the styles to individual components, you can usually use the style property and pass it the styles you want.
This is another example from the docs where a margin of 12px is applied to a RaisedButton.
import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
const style = {
margin: 12,
};
const RaisedButtonExampleSimple = () => (
<div>
<RaisedButton label="Default" style={style} />
<RaisedButton label="Primary" primary={true} style={style} />
<RaisedButton label="Secondary" secondary={true} style={style} />
<RaisedButton label="Disabled" disabled={true} style={style} />
<br />
<br />
<RaisedButton label="Full width" fullWidth={true} />
</div>
);
export default RaisedButtonExampleSimple;
Now, the styles are defined in the same file but you could define them in a separate file and import them to the file where you are using the components.
If you want to apply multiple styles then you can use the spread operator like so: style={{...style1,...style2}}.
Usually, you are styling a specific thing in the component (root element) with the style property but some components have more than one property to style different elements of the component. Under properties in this page http://www.material-ui.com/#/components/raised-button, you can see that there are style property, labelStyle and rippleStyle to style different parts of RaisedButton.
Check the properties under the component that you are using and see which style property you could use, otherwise check the available global style properties you could override. Hope this helps!
I should've used JssProvider and tell it to put material UI styles before mine in the page head section.
import JssProvider from 'react-jss/lib/JssProvider';
import { create } from 'jss';
import { createGenerateClassName, jssPreset } from 'material-ui/styles';
const generateClassName = createGenerateClassName();
const jss = create(jssPreset());
// We define a custom insertion point that JSS will look for injecting the styles in the DOM.
jss.options.insertionPoint = document.getElementById('jss-insertion-point');
function App() {
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
...
</JssProvider>
);
}
export default App;
you have to use the component API's. You can't set style to the components imported from libraries just with css if the component has API's to get style.
*Update
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Button from 'material-ui/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .30)',
},
label: {
textTransform: 'capitalize',
},
};
function Classes(props) {
return (
<Button
classes={{
root: props.classes.root, // class name, e.g. `classes-root-x`
label: props.classes.label, // class name, e.g. `classes-label-x`
}}
>
{props.children ? props.children : 'classes'}
</Button>
);
}
Classes.propTypes = {
children: PropTypes.node,
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Classes);

Resources