Why is gatsby-plugin-image missing image prop? - reactjs

I am working on improving my image sizes and noticed that gatsby image was deprecated so I decided to try on the gatsby-plugin-image. On static images like this:
<StaticImage
src="../images/image.png"
alt="software design"
layout={'fullWidth'}
formats={['auto', 'webp']}
/>
is working fine. But when working on the images from netlify cms I get that following error Missing image prop even I have following:
<GatsbyImage
image={refImage}
alt={refImage}
layout={'fullWidth'}
formats={['auto', 'webp']}
/>
The whole file is as follows.
import React from 'react'
import PropTypes from 'prop-types'
import { GatsbyImage, getImage } from 'gatsby-plugin-image'
import * as S from './styled'
import './postitem.css'
const ReferenceItem = ({
slug,
background,
category,
date,
title,
description,
image,
timeToRead,
}) => {
const refImage = getImage(image)
return (
<S.BlogColumn>
<article className="post" key={slug}>
<S.BlogColumn>
{image && (
<GatsbyImage
image={refImage}
alt={refImage}
layout={'fullWidth'}
formats={['auto', 'webp']}
/>
/* <img
style={{
display: 'block',
width: '100%',
height: 'auto',
}}
src={`/${image}`}
alt={image}
/> */
)}
{!image && (
<img
style={{
display: 'block',
width: '100%',
height: 'auto',
}}
src={require('../../../static/assets/img/cover.webp')}
alt="cover"
/>
)}
</S.BlogColumn>
<S.BlogColumn>
<div className="post-content">
<h2 className="post-title">{title}</h2>
<p className="post-item-description">{description}</p>
<span className="post-date">
{date} —
</span>
<span className="post-words">
{timeToRead} minute read
</span>
</div>
</S.BlogColumn>
</article>
</S.BlogColumn>
)
}
ReferenceItem.propTypes = {
slug: PropTypes.string.isRequired,
background: PropTypes.string,
category: PropTypes.string,
date: PropTypes.string.isRequired,
timeToRead: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string,
}
export default ReferenceItem

The image needs to be of type GatsbyImageData as processed by gatsby-plugin-sharp or another source plugin that generates the correct format.
Additionally, the props you're passing to GatsbyImage will not work. StaticImage takes props, GatsbyImage needs that information to be passed to the sharp query that generates the images. For example,
{
image {
childImageSharp {
gatsbyImageData(layout: FULL_WIDTH)
}
}
}

They both can take props but Static Image can't get passed props from another component. No passing down to static image. The documentation for the plugin lists which props are for both, and which aren't.
The one that can take the passing down props is Dynamic one, GatsbyImage.

It seems that problem was react native version 0.65 where the `headerTransparent: true makes the button not work properly in android device. And is fixed in the next version.

Related

how to pass the overlayProps into Panel

How can I pass the styles overlayProps into the Panel component as it is stated in https://developer.microsoft.com/en-us/fluentui#/controls/web/panel
I tried:
<Panel
overlayProps={{styles:{backgroundColor:'red'}}}
/>
But does not seems to work
The only thing missing from the original source is root, which is the target element in the overlay.
This snippet (full example) shows a Panel with a red overlay. (full example)
const PanelBasicExample: React.FunctionComponent = () => {
return (
<div>
<Panel
headerText="Sample panel"
isOpen={true}
overlayProps={{ className: "foo", styles: { root: { backgroundColor: "red" }}}}
>
<p>Content goes here.</p>
</Panel>
</div>
);
};
layerProps is an optional props to pass to the Layer component hosting the panel.Do you have a Layer Component?
Also, styles can have a className as properties, you may try to give the component a customised name and adapt the css.
i guess you can check out the "Panel - custom navigation" provided in your link.
it has something like below to override searchbox. I think Panel should be the same since it also accepts a similar styles prop.
const searchboxStyles = { root: { margin: '5px', height: 'auto', width: '100%' } };
<SearchBox
placeholder="Search here..."
styles={searchboxStyles}
ariaLabel="Sample search box. Does not actually search anything."
/>

http://localhost:3000/[object%20Object] not found 404

In my react app, this is an array of filenames I get from server side
const photos = ["01-1913.JPG", "01-1913.1.jpg", "01-1913.2.jpg"]
and here is how I use it with JSX
{
photos.map(entry => {
return (
<div key={entry}>
<PhotoItem key={entry} url={`${process.env.REACT_APP_NODE_SERVER}/${entry}`} />
</div>
)
})
}
const PhotoItem = (url) => {
return (
<img
src={url}
onError={this.addDefaultSrc}
alt="photoItem"
style={{
width: "500px",
height: "600px",
border: "1px solid #123C69",
}}
></img>
);
};
```
I can not figure out why I am not getting the photo (only the dummy photo from the onError event I've used) and if it has anything to do with the Object%object error. Any help would be appreciated.
As mentioned in the comments, the PhotoItem component should look like this:
// Note that here props are named "props" instead of "url"
const PhotoItem = (props) => {
return (
<img
src={props.url}
onError={this.addDefaultSrc}
alt="photoItem"
style={{
width: "500px",
height: "600px",
border: "1px solid #123C69",
}}
></img>
);
};
Note that the first argument that a react component receives is props. So even if you name it url, the value that you are looking for url lives in url.url.
I also recommend to deconstruct your props like this:
const PhotoItem = ({url}) => {
return (
<img
src={url}
...
></img>
);
};
I faced this error on the developer console on a Next.js project right after upgrading Next from v10 to v12.
Turns out using an image as <img src={require()}/> is not working anymore, and throws this error.
Instead to fix the issue, you need to use Next's (almost) drop in replacement of Image component as;
import Image from 'next/image'
...
<Image src={require()}/>
This will fix the issue, if your Next project is throwing this error.

Resize google map frame in react js

Currently using google-maps-react component in a contact form for a sales page. This code has successfully imported the map and it is viewable in the dimensions 450x350. My issue is, is that despite the image being 450x350 the frame or i guess div that the map api sits in still thinks the map is still default size so it pushes my entire site out with white space that is removed when i remove the Map API. No amount of adding styles as dimensions to anything around the map has fixed this.
What do i pass into the map in order to effect the size of the frame and not just the image itself?
import React, { Fragment } from "react";
import ContactForm from "../contactus/ContactForm";
import { Map, Marker, GoogleApiWrapper } from "google-maps-react";
const ContactUs = props => {
const style = {
maxWidth: "450px",
height: "350px",
overflowX: "hidden",
overflowY: "hidden"
};
return (
<Fragment>
<h2 className='lead text-primary text-center'>Get in touch</h2>
<div className='grid-2'>
<div>
<h4>Priority Consulting</h4>
<ul>
<li>
1234 Sherman Way <br />
Sherman Oaks, CA 90210
</li>
<li>info#priorityconsulting.com</li>
<li>1-800-324-3423</li>
</ul>
<Map google={props.google} style={style} />
</div>
<div>
{" "}
<ContactForm />
</div>
</div>
</Fragment>
);
};
export default GoogleApiWrapper({
apiKey: "MYKEY"
})(ContactUs);
I went back into my code and found an updated version, that made it to a final version of the site. Unfortunately the site is no longer live so cant verify if this is the best answer but, like I said its in my code, so it probably solves.
const style = {
maxWidth: "450px",
height: "350px",
overflowX: "hidden",
overflowY: "hidden"
};
const containerStyle = {
maxWidth: "450px",
height: "350px"
};
<Map google={props.google} style={style} containerStyle={containerStyle} />

Access Gatsby Component from a function

I am trying to access a Gatsby component (Anime) from outside of it.
Can not figure out what instance name this would have or how to name it.
Here is my code:
import React from 'react'
import PropTypes from 'prop-types'
import PreviewCompatibleImage from '../components/PreviewCompatibleImage'
import Anime from 'react-anime';
import VisibilitySensor from 'react-visibility-sensor';
function onChange (isVisible) {
console.log('Element is now %s', isVisible ? 'visible' : 'hidden')
}
const FeatureGrid = ({ gridItems }) => (
<div className="columns is-multiline">
<VisibilitySensor onChange={onChange}>
<Anime delay={(e, i) => i * 100}
scale={[.1, .9]}
autoplay={false}>
{gridItems.map(item => (
<div key={item.text} className="column is-3">
<section className="section">
<div className="has-text-centered">
<div
style={{
width: '160px',
display: 'inline-block',
}}
>
<PreviewCompatibleImage imageInfo={item} />
</div>
</div>
<p>{item.text}</p>
</section>
</div>
))}
</Anime>
</VisibilitySensor>
</div>
)
FeatureGrid.propTypes = {
gridItems: PropTypes.arrayOf(
PropTypes.shape({
image: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
text: PropTypes.string,
})
),
}
export default FeatureGrid
I want to get the animation to trigger from the onChange function.
How do I get the name or set the name of the Anime component so I can access it from the function?
Or is there another way I should address this?
Using a Gatsby starter netlify CMS as the base, so extending on their code, but seems that const is not the route I should take.
I want the animation to trigger when it becomes visible.
Any suggestions?
According to the docs react-visibility-sensor :
You can pass a child function, which can be convenient if you don't need to store the visibility anywhere
so maybe instead of using the onchange function you can just pass the isVisible parameter, something like:
<VisibilitySensor>
{({isVisible}) =>
<Anime delay={(e, i) => i * 100}
// the rest of your codes here ...
</Anime>
}
</VisibilitySensor>
Otherwise you can convert this function to a react component and set states, etc..

How to Style React-Icons

I am trying to figure out how to style icons that I import using react-icons.
In particular, I would like to be able to create a look similar to this:
That is to say, I'd like to add a background color, padding, border-radius, etc. However, I can't find an easy way to do that.
I can add a size and color prop and that will change the actual size and color of the icon. But there is no easy way for me to change the other elements.
Does anyone know how I can do this (or can they recommend a different library that can help me with this)?
Use IconContext as mentioned in the Docs.
function BlueLargeIcon() {
return (
<IconContext.Provider
value={{ color: 'blue', size: '50px' }}
>
<div>
<FaBeer />
</div>
</IconContext.Provider>
);
}
To target specific Icon Components, you can use the style prop or use the same API (see Configurations) on the component itself:
const style = { color: "white", fontSize: "1.5em" }
<FaFacebookF style={style} />
// API
<FaFacebookF color="white" fontSize="1.5em" />
Colours of some icons can't be changed. For example, I tried to change the colour of { GrClose } icon by doing this:
<GrClose
className="icon"
style={{
position: 'absolute',
top: '20px',
right: '20px',
}}
size="50px"
color="white"
onClick={handleExit}
/>
It just didn't change, when I replaced my icon with { AiOutlineClose } icon it worked!
I think the easiest way here would be to just pass the className prop directly to the Icon you'd like to apply styles to. Source Code in a CodeSandbox. I've used tailwindcss classes here, but you could use your own just as easily.
import React from "react";
import "./styles.css";
import {
FaFacebookF,
FaTwitter,
FaInstagram,
FaPinterest
} from "react-icons/fa";
export default function App() {
let circleClasses = "inline-block p-7 rounded-full w-20 mx-auto";
let iconStyles = { color: "white", fontSize: "1.5em" };
return (
<div className="App grid grid-cols-2 sm:grid-cols-4 gap-2 w-3/4 mx-auto">
<h1 className="col-span-full">Icon Demo</h1>
<span style={{ background: "#3B5998" }} className={circleClasses}>
<FaFacebookF style={iconStyles} />
</span>
<span style={{ background: "#1DA1F2" }} className={circleClasses}>
<FaTwitter style={iconStyles} />
</span>
<span style={{ background: "black" }} className={circleClasses}>
<FaInstagram style={iconStyles} />
</span>
<span style={{ background: "#BD081C" }} className={circleClasses}>
<FaPinterest style={iconStyles} />
</span>
</div>
);
}
If you'd like a little more context as to how this works, we can take a dive into the source code for react-icons.
If you take a look at where the IconContext is defined within react-icons, you can see the allowed props:
export interface IconContext {
color?: string;
size?: string;
className?: string;
style?: React.CSSProperties;
attr?: React.SVGAttributes<SVGElement>;
}
export const DefaultContext: IconContext = {
color: undefined,
size: undefined,
className: undefined,
style: undefined,
attr: undefined,
};
export const IconContext: React.Context<IconContext> = React.createContext && React.createContext(DefaultContext);
Indeed, you're able to pass in color, size, style, additional svg attributes, and even a className string. But, this requires that you wrap the Icon component in the context.
When you install react-icons, all of the icons are added into the node_modules directory in a format that looks like this:
// THIS FILE IS AUTO GENERATED
var GenIcon = require('../lib').GenIcon
module.exports.Fa500Px = function Fa500Px (props) {
return GenIcon({"tag":"svg","attr":{"viewBox":"0 0 448 512"},"child":[{"tag":"path","attr":{"d":"M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"}}]})(props);
};
If we take a look at the source code for GenIcon we can get a bit more context for how this is working.
import * as React from 'react';
import { IconContext, DefaultContext } from './iconContext';
export interface IconTree {
tag: string;
attr: {[key: string]: string};
child: IconTree[];
}
function Tree2Element(tree: IconTree[]): React.ReactElement<{}>[] {
return tree && tree.map((node, i) => React.createElement(node.tag, {key: i, ...node.attr}, Tree2Element(node.child)));
}
export function GenIcon(data: IconTree) {
return (props: IconBaseProps) => (
<IconBase attr={{...data.attr}} {...props}>
{Tree2Element(data.child)}
</IconBase>
);
}
export interface IconBaseProps extends React.SVGAttributes<SVGElement> {
children?: React.ReactNode;
size?: string | number;
color?: string;
title?: string;
}
export type IconType = (props: IconBaseProps) => JSX.Element;
export function IconBase(props:IconBaseProps & { attr?: {} }): JSX.Element {
const elem = (conf: IconContext) => {
const {attr, size, title, ...svgProps} = props;
const computedSize = size || conf.size || "1em";
let className;
if (conf.className) className = conf.className;
if (props.className) className = (className ? className + ' ' : '') + props.className;
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
{...conf.attr}
{...attr}
{...svgProps}
className={className}
style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
height={computedSize}
width={computedSize}
xmlns="http://www.w3.org/2000/svg"
>
{title && <title>{title}</title>}
{props.children}
</svg>
)
};
return IconContext !== undefined
? <IconContext.Consumer>{(conf: IconContext) => elem(conf)}</IconContext.Consumer>
: elem(DefaultContext);
}
So, GenIcon is a function that accepts an object with an interface of IconTree which includes tag, attr and child properties. We can see this in action in the generated code above. GenIcon returns a function itself. This function accepts props as an argument which implements the IconBaseProps interface. The IconBaseProps interface extends React.SVGAttributes which include className and style. Those are then passed as props to the IconBase component here:
export function GenIcon(data: IconTree) {
return (props: IconBaseProps) => (
<IconBase attr={{...data.attr}} {...props}>
{Tree2Element(data.child)}
</IconBase>
);
}
To get a sense of how IconBase actually works with respect to the IconContext let's check out its return statement:
return IconContext !== undefined
? <IconContext.Consumer>{(conf: IconContext) => elem(conf)}</IconContext.Consumer>
: elem(DefaultContext);
Here, we can see that IconBase will invoke a function called elem (defined inside the body of IconBase) either way. So, IconBase will use the IconContext if one is defined, wrapping the returned element in IconContext.Consumer and calling elem with the IconContext. But, if IconContext is not defined in this scope, IconBase will use the DefaultContext instead.
To understand how this is working, we need to look at the elem function defined inside of IconBase. Here's the full source again:
const elem = (conf: IconContext) => {
const {attr, size, title, ...svgProps} = props;
const computedSize = size || conf.size || "1em";
let className;
if (conf.className) className = conf.className;
if (props.className) className = (className ? className + ' ' : '') + props.className;
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
{...conf.attr}
{...attr}
{...svgProps}
className={className}
style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
height={computedSize}
width={computedSize}
xmlns="http://www.w3.org/2000/svg"
>
{title && <title>{title}</title>}
{props.children}
</svg>
)
};
So, if you take a look at the code relating to className, you can see that we can actually add className to the Context and/or the props directly (<FaFacebook className="bg-blue" />) and they'll actually be combined and applied to the returned svg
let className;
if (conf.className) className = conf.className;
if (props.className) className = (className ? className + ' ' : '') + props.className;
Also, the styles defined in either the Context or the props will be combined and applied to the svg
style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
One thing to note here is that all of the styles and classes are being applied directly to the returned svg element. So, in your case, you'd probably need to have a wrapping element to build out the border-radius and background color and then apply the relevant styles for color and size directly to the svg.
Simply add "color" property to
Like This:
<Icon color="blue" />
import {IconContext} from "react-icons";
class App extends component {
return (
<div>
<IconContext.Provider value={{ className="myReact-icons"}}>
<FaBeer />
</IconContext.Provider>
</div>
);
}
css example below
.myreact-icons { color: red;
height: 40px;
}
There is a simpler way to change the color of a react-icon.you can choose everything inside the svg icon with .icon > * use the css fill to fill the svg path.
```
.icon > * {
fill: #B3B3B3;
}
.icon > *:hover {
fill: #747474;
}
```
You can do it by simply adding colour property to icon, same goes for other properties like size.
<BiXCircle size={40} color="red" />
<HiOutlineInformationCircle
size= {40}
color="#777C92"
className = "m-1 cursor-pointer hover: stroke-[#E5765D]"
/>
Color changes on Grommet Icons don't apply. You can try with others either by passing a class and target it with css or directly inside <IconExample color={'blue'} />
function blackReactIcons () {
return(
<div>
<FaTwitter fill='#000' />
<FaLinkedinIn fill='#000' />
<FaGithub fill='#000' />
</div>
);
}
It is so easy just capsule your **icon** in **span tag**
<div className="social-icons">
<span>
<FaGithub/>
</span>
</div>
then style it using **CSS**
.social-icons span{
margin: 10px;
font-size: 20px;
color: var(--grey);
}
.social-icons span:hover{
color:black
}
You can export them as an object(s) with other properties and map through them.
import { FaInstagram, FaTwitter } from 'react-icons/fa';
export const socialIcons = [
{
icon: <FaInstagram
style={{ height: '30px', width: '30px' }}
/>,
title: 'Instagram',
link: '',
color: '#C13584',
isOpen: false,
id: 'instagram',
},
{
icon: <FaTwitter
style={{ height: '30px', width: '30px' }}/>,
title: 'Twitter',
link: '',
color: '#00acee',
isOpen: false,
id: 'twitter',
},
];
import { socialIcons } from '../';
// ...
<div>
{socialIcons.map((social) => (
<div>
<a href={social.link}>
<button style={{ color: social.color }}
id={social.id}>
{social.icon}
</button>
</a>
</div>
))}
</div>
In your styles.scss or css
.iconFaFacebook {
color: blue;
font-size: 2.5rem;
}
<FaFacebook className={styles.iconFaFacebook} />

Resources