I have created a react-bootstrap carousel with some images I load via graphql and gatsby-image-sharp (the source images are in directus).
I see the images are created in the code, but they never get assigned the "active" class. When I put the images outside of the carousel, they are shown correctly one below the other, so the retrieval seems to work fine.
If I manually add an item before and/or after the graphql images, those slides get shown correctly.
I also see that in case I put a slide before and after the graphql ones, the first "normal" slide gets shown and when the transaction is started, I get a delay corresponding to the number of generated slides before the next statically created slide is shown again.
When inspecting the site with the react development tools, I see the working slides have a transaction key of ".0" and ".2", while the non-working slides between them have transaction keys of ".1:0:0", ".1:0:1", etc...:
React devtools tree
The code I use to generate this is included below:
import React from "react"
import { Row, Col, Container, Carousel } from "react-bootstrap"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import Img from "gatsby-image"
const IndexPage = ({ data }) => (
<Layout pageInfo={{ pageName: `index` }}>
<SEO title="Home" keywords={[`gatsby`, `react`, `bootstrap`]} />
<Container className="text-center">
<Row>
<Col>
<Carousel>
<Carousel.Item>
<div className="d-block w-100 gatsby-image-wrapper">
<h1>test</h1>
</div>
</Carousel.Item>
{data.allDirectusSlideshow.edges.map((slideShow) => {
return slideShow.node.images.map((image) => {
const sharp = data.allImageSharp.edges.find((imageSharp) => (
imageSharp.node.fluid.originalName === image.filename_disk))
return <>
<Carousel.Item key={sharp.node.id}>
<h1>Image</h1>
<Img fluid={sharp.node.fluid} className="d-block w-100" />
</Carousel.Item>
</>
})
})}
<Carousel.Item>
<h1>Test 2</h1>
</Carousel.Item>
</Carousel>
</Col>
</Row>
</Container>
</Layout>
)
export const query = graphql`
query {
allDirectusSlideshow(filter: {title: {eq: "Voorpagina"}}) {
edges {
node {
title
images {
filename_disk
}
}
}
}
allImageSharp {
edges {
node {
id
fluid {
originalName
...GatsbyImageSharpFluid
}
}
}
}
}
`
export default IndexPage
As the directus api for this site is not public, I have put up a generated code example here (note: only the homepage works)
Apparently, bootstrap carousel expects its items to be a direct child of the carousel. This means that react fragments don't work over here.
Changing this:
return <>
<Carousel.Item key={sharp.node.id}>
<h1>Image</h1>
<Img fluid={sharp.node.fluid} className="d-block w-100" />
</Carousel.Item>
</>
To this solves the issue:
return (
<Carousel.Item key={sharp.node.id}>
<h1>Image</h1>
<Img fluid={sharp.node.fluid} className="d-block w-100" />
</Carousel.Item>
)
Related
<script setup lang="ts">
import * as Vue from 'vue';
import { G, ROLES } from '#/G';
import * as DTO from '#/DTO';
import { FilterMatchMode, FilterOperator } from 'primevue/api'
import { ref, onMounted } from 'vue';
import { RouterLink } from 'vue-router';
const recs = Vue.ref<DTO.IWebPages[]>();
G.doAjaxAsync<DTO.IWebPages[]>('webpages/ForUserAtClient',null).then(o => {
if (o !== null)
recs.value = o;})
const filters = Vue.ref();
const clearFilter = () => {
initFilters();};
const initFilters = () =>
{filters.value = {'global'{value:'',matchMode:FilterMatchMode.CONTAINS },}};
initFilters()
</script>
<template>
<div class="grid">
<div class="col-12 lg:col-12 xl:col-12">
<div class="card mb-0">
<h3>Data Page Menu</h3>
</div>
<br />
<DataTable
:value="recs"
:paginator="true" class="p-datatable-gridlines"
:rows="15" dataKey=""
:rowHover="true"responsiveLayout="scroll"paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
:alwaysShowPaginator="false"currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
v-model:filters="filters" filterDisplay="menu" :globalFilterFields="['company']">
<template #empty>
No records
</template>
<Column field="company" header="Company" />
<Column field="dataType" header="Type" />
<Column field="screenText" header="Text" class="p-link" />
<template>
Above is my code which displays data in three columns. The last row screenText has text values for example NewAssignent. I want to make that text a router link to another page called NewAssignment. The tags and are PrimeVue tags. Wrappers over html table, row and column tags. If you see the third column I placed a class="p-link" but it makes the whole cell clickable. I want the text to be recognized as there are different pages and they should link to these values inside column cell. The other cell value is search so it will go to search page. The data coming from the API for the third column should be links to other pages.
here in the Image the src={product.image} in not pulling any images from my product.js local arrays of objects
but its working on the other pages and also works if put the direct path as src="../images/vibestick.jpg"
import React from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Image, ListGroup, Card, Button } from 'react-bootstrap'
import Rating from '../components/Rating'
import products from '../product'
const ProductScreen = ({ match }) => {
const product = products.find( (p) => p._id === match.params.id )
return (
<>
<Link className="btn btn-light my-3" to="/home">
Go Back
</Link>
<Row>
<Col md={6}>
<Image src={product.image} alt={product.name} fluid />
</Col>
<Col md={3}>
<ListGroup variant="flush" >
<ListGroup.Item>
<h2>{product.name}</h2>
</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</>
)
}
export default ProductScreen
I would like to return an image as a widget.
I put my photo.png in a folder images next to myFile.jsx.
I have always the same error :
Can't walk dependency graph: Cannot find module './images/photo.png' form /Users/macbookpro/Library/Application Support/Übersicht/widgets/my file/myFile.jsx required by /Users/macbookpro/Library/Application Support/Übersicht/widgets/my file/myFile.jsx
I have also tried to: move the photo to my Desktop, use require, use import .. from ...
Here there is the code:
import { css } from "uebersicht";
// import photo from "./images/photo.jpg";
// import photo from "./Users/macbookpro/Desktop/photo.png";
export const render = () => {
return (
<div>
<img src="./images/photo.png" />
{/* <img src="./Users/macbookpro/Desktop/photo.png" /> */}
{/* <img src={require("./images/photo.png")} /> */}
{/* <img src={require("./Users/macbookpro/Desktop/photo.png")} /> */}
</div>
);
};
Since myFile.jsx is actually act as a component for uebersicht you have to include your widget folder name in you src.
For example if your photo.png is in example.widget/images folder, your should be:
<img src="example.widget/images/photo.png/>
Lets say I have a bunch of local images that are part of my react project. I have a component that accepts props from higher up -- and one of the props is image name. So using , this could work. The tricky part is that I am using webpack, and I think thats why my images dont get displayed -- they arent pulled in.
So before I had converted my component to use props, the image name was hardcoded, and worked like this:
<img src={require('../images/products/image-aqua.png')}/>
but now it looks as following, and doesnt work:
<img src={this.props.productImageUrl} />
Essentially, I am trying to stradle react "on the fly" image names and webpack packing concepts (I do know about webpack url-loader and file-loader)
thank you
You should probably post your webpack so we can help you further. Your code above should work no problem.
Here is my webpack for img and such and it works as you are trying to use it.
{
test: /\.(jpg|jpeg|gif|png|tiff|svg)$/,
exclude: /\.glyph.svg/,
use: [
{
loader: 'url-loader',
options: {
limit: 6000,
name: 'image/[name].[ext]',
},
},
],
},
The only other issue you could be encountering is that your images aren't actually loaded when your component loads. Are you getting any errors or they just aren't showing?
class ProductList extends React.Component {
render() {
const product = Seed.products[0];
return (
<div className='ui unstackable items'>
<Product
id={product.id}
title={product.title}
description={product.description}
url={product.url}
votes={product.votes}
submitterAvatarUrl={`${product.submitterAvatarUrl}`}
productImageUrl={`${product.productImageUrl}`}
/>
</div>
);
}
}
class Product extends React.Component {
render() {
console.log("image name " + `${this.props.productImageUrl}`);
return (
<div className='item'>
<div className='image'>
<img src={`${this.props.productImageUrl}`} /> {/*this.props.productImageUrl*/}
</div>
<div className='middle aligned content'>
<div className='header'>
<a>
<i className='large caret up icon' />
</a>
{this.props.votes}
</div>
<div className='description'>
<a href={this.props.url}>
{this.props.title}
</a>
<p>
{this.props.description}
</p>
</div>
<div className='extra'>
<span>Submitted by:</span>
<img
className='ui avatar image'
src={`${this.props.submitterAvatarUrl}`}
/>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<ProductList />,
document.getElementById('content')
);
...
import aqua from '../images/products/image-aqua.png';
import daniel from '../images/avatars/daniel.jpg';
export default window.Seed = (function () {
function generateVoteCount() {
return Math.floor((Math.random() * 50) + 15);
}
const products = [
{
id: 1,
title: 'Yellow Pail',
description: 'On-demand sand castle construction expertise.',
url: '#',
votes: generateVoteCount(),
submitterAvatarUrl: daniel,
productImageUrl: aqua,
},
I am currently learning and practicing React.
I am trying to achieve a react web app that allows you to display and scroll through Nasa's picture of the day based on what date you choose. here's the api: api.nasa.gov/
the project is simple BUT. sometimes the url that the api returns, leads to an img and sometimes a youtube video. for example:
https://apod.nasa.gov/apod/image/1708/PerseidsTurkey_Tezel_960.jpg
or
https://www.youtube.com/embed/Zy9jIikX62o?rel=0
I have managed to display both cases using an iframe. I know this is not ideal for the imgs because I cannot format it properly with css and it just looks bad with the scroll bars, sizing etc..but won't display the video..
this is what the react component looks like (using bootstrap)
detail.js
import React, { Component } from 'react';
export default class Detail extends Component {
render() {
return (
<div className="video-detail col-md-12">
<div className="embed-responsive embed-responsive-16by9">
<iframe className="embed-responsive-item" src={this.props.url}>
</iframe>
</div>
</div>
);
}
}
I would like to images also to display responsively, centered and original aspect ratio but also still have the videos display properly as they are.
I have tried putting an additional <img> underneath the <iframe> but that just renders the image twice. Is there a way to render an <img> or <iframe> conditionally?
I am wondering what strategy should I try next? Any ideas?
Thanks!
you should use conditional rendering
const isImage = this.props.url.split().pop() === 'jpg';
return (
{
isImage ? <img src={this.props.url} />
: <iframe className="embed-responsive-item" src={this.props.url}>
</iframe>
}
)
or
const isImage = this.props.url.split().pop() === 'jpg';
return (
{
isImage && <img src={this.props.url} />
}
{
!isImage && <iframe className="embed-responsive-item" src={this.props.url}>
</iframe>
}
)
Yon don't even have to use a split().pop(). Just scan the API return for a media type (much simpler, really):
const Photo = props => (
<div>
<h3 className="m-5 text-center">{props.photo.title}</h3>
{props.photo.media_type === "image" ? (
<img className="rounded mx-auto d-block" src={props.photo.url} alt={props.photo.title} />
) : (
<iframe
title="space-video"
src={props.photo.url}
frameBorder="0"
gesture="media"
allow="encrypted-media"
allowFullScreen
className="mx-auto d-block"
/>
)}
<p className="col-md-8 offset-md-2 mt-5 pb-5">{props.photo.explanation}</p>
</div>