I have done a lot of looking but there is suprisingly little documentation in regard to reactstrap carousel image responsiveness.
My ReactStrap carousel resizes responsively but the images do not.
Options I have researched/tried:
CSS via className in the carousel component itself? This is the one I thought might be best, but I haven't found a combination of background-size, height, and max-width that resizes the image properly.
srcset ? I'm not sure how to implement this or any other inline attribute, given that the carousel is a component
Perhaps some place in the carousel component itself?
Or is there a better way for me to modify the images?
Or is #media the answer via css?
`
const items = [
{
src: 'img1.png',
altText: '',
caption: ''
},
{
src: 'img2.png',
altText: '',
caption: 'Freedom Isn\'t Free'
},
{
src: 'img3.png',
altText: '',
caption: ''
}
];
class HomeCarousel extends Component {
constructor(props) {
super(props);
this.state = { activeIndex: 0 };
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
this.goToIndex = this.goToIndex.bind(this);
this.onExiting = this.onExiting.bind(this);
this.onExited = this.onExited.bind(this);
}
onExiting() {
this.animating = true;
}
onExited() {
this.animating = false;
}
next() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === items.length - 1 ? 0 : this.state.activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === 0 ? items.length - 1 : this.state.activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
render() {
const { activeIndex } = this.state;
const slides = items.map((item) => {
return (
<CarouselItem
className="carouselImg"
onExiting={this.onExiting}
onExited={this.onExited}
key={item.src}
>
<img src={item.src} alt={item.altText} />
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});
return (
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators items={items} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
);
}
}
export default HomeCarousel;
`
Good day and Hello,
I already tried this reactstrap with the Carousel component in my reactjs app.
I solved this by adding bootstrap 4 classess "d-block w-100".
I created this in my reactstrap Carousel component and in this element
from this:
<img src={item.src} alt={item.altText} />
I changed to:
<img className="d-block w-100" src={item.src} alt={item.altText} />
I just copied these classes (d-block w-100) from bootstrap 4 documentation
https://getbootstrap.com/docs/4.0/components/carousel/
This is my example that I used Reactstrap Carousel with Dynamic data from my WordPress Rest API data.
https://github.com/jun20/React-JS-and-WP-Rest-API/tree/home-carousel-final
.carousel-item > img {
width: 100%;
}
... will fix your problem.
And it has nothing to do with Reactstrap. That's probably why you didn't find much. Has to do with the TwBs Carousel alone. I personally don't see any reason why that rule is not part of TwBs carousel CSS, because everyone expects that <img> to have a width of 100% of its parent.
If you want to limit it to a particular carousel, modify the selector accordingly.
Another frequently requested TwBs carousel mod is:
.carousel-control-prev,.carousel-control-next {
cursor:pointer;
}
Given bootstrap uses flexbox, you can make the reactstrap carousel images responsive by adding this to your css:
.carousel-item, .carousel-item.active {
align-items:center;
}
This seems to prevent the image height from stretching. Worked for me!
Based on the reactstrap Carousel example 1 on this page https://reactstrap.github.io/components/carousel/
Here's how I got it to be responsive in my use case:
<CarouselItem
onExiting={() => setAnimating(true)}
onExited={() => setAnimating(false)}
key={item.src}
>
<img src={item.src} alt={item.altText} style={{ width: "100%"}}/>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
So, passing in style={{ width: "100%"}} to the img tag, made my oversized images fit the screen perfectly and may work for others coming here.
Related
When working with Embedded Zoom Component, the Zoom SDK return an element which you need to place it inside an html element
the problem is how to resize and position the returned component inside my code after rendering
const client = ZoomMtgEmbedded.createClient();
function getSignature(e) {
e.preventDefault();
// ... some code to get the signature
startMeetingZoomMtgEmbedded(response.signature);
}
function startMeetingZoomMtgEmbedded(signature) {
let meetingSDKElement = document.getElementById('meetingSDKElement');
client.init({
debug: true,
zoomAppRoot: meetingSDKElement,
language: 'en-US',
customize: {
meetingInfo: ['topic', 'host', 'mn', 'pwd', 'telPwd', 'invite', 'participant', 'dc', 'enctype'],
toolbar: {
buttons: [
{
text: 'Custom Button',
className: 'CustomButton',
onClick: () => {
console.log('custom button');
}
}
]
}
}
});
client.join({
apiKey: apiKey,
signature: signature,
meetingNumber: meetingNumber,
password: passWord,
userName: userName,
userEmail: userEmail,
tk: registrantToken,
success: (success) => {
console.log('success');
},
error: (error) => {
console.log(error);
}
});
}
return (
<div className="App">
<main>
<h1>Zoom Meeting SDK Sample React</h1>
{/* For Component View */}
<div id="meetingSDKElement"></div>
<button onClick={getSignature}>Join Meeting</button>
</main>
</div>
);
So my question is how to modify the style and the position of the component before or after the rendering of the code by the Zoom SDK.
For Resizing , You will find details in the following documentation link :
Zoom Documentation for resizing component view
For Positioning, You will find details in the following documentation link :
Zoom Documentation for positioning component view
The only way to resize camera view is editing #ZOOM_WEB_SDK_SELF_VIDEO id. So, you have to edit other classes also to make buttons, containers and etc resize like camera view does, but it is totally buggy and i don't think it is a good idea pay all this effort to a workaround, besides that, in next versions maybe they bring built in properties to do this job.
Just for example, this is the result when you change #ZOOM_WEB_SDK_SELF_VIDEO:
#ZOOM_WEB_SDK_SELF_VIDEO {
width: 720%;
height: 480%;
}
In general way, you can modify the style and position of your component by using reactive CSS styling.
In zoom way you can use (zoom web meeting SDK)
(a) "popper: {}" properties for positioning elements
(b) "viewSizes: {}" properties for default meeting canvas size
(c) for styling use "id" and "class" for reactive CSS styling
popper use:
client.init({
...
customize: {
video: {
popper: {
anchorElement: meetingSDKElement,
placement: 'top'
}
},
}
...
})
viewSizes use:
client.init({
...
customize: {
video: {
viewSizes: {
default: {
width: 1000,
height: 600,
}
}
},
}
...
})
I would like to add a 33% to the Wordpress Block "Button". So far it has 25%,50%,75% and 100%. Is it possible to insert my new value into the existing width selector?
I'm guessing Block Filters are the way to go.
I think I also found the way to get the settings object which might then help me to find out what I need to overwrite. However simply adding this code to my admin.js does not produce any output. Where would I need to load this?
const filterBlocks = (settings) => {
if (settings.name !== 'core/buttons') {
return settings
}
console.log(settings);
return settings;
}
Quick solution: Add a custom CSS class in the Buttons' block properties under "Advanced > Additional CSS class(es)" then define the custom width in your theme style.css
Detailed solution:
By using wp.hooks.addFilter() you can add a new control to the Button block with as many extra custom width options as you need. The Button blocks preset widths are defined within the function WidthPanel() of the blocks edit.js function:
function WidthPanel( { selectedWidth, setAttributes } ) {
...
return (
...
<ButtonGroup aria-label={ __( 'Button width' ) }>
{ [ 25, 50, 75, 100 ].map( ( widthValue ) => {
...
}
}
To add a new width value of 33% to the block, we need to add our own new button control to the InspectorControls and then use wp.hooks.addFilter() to add this to the existing core Button block, eg:
index.js
import { createHigherOrderComponent } from '#wordpress/compose';
import { Fragment } from '#wordpress/element';
import { InspectorControls } from '#wordpress/block-editor';
import { PanelBody, Button } from '#wordpress/components';
const withInspectorControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { setAttributes } = props;
let widthValue = 33; // must be a number
return (
<Fragment>
<BlockEdit {...props} />
<InspectorControls>
<PanelBody title="Custom Width">
<Button
key={widthValue}
isSmall
variant={widthValue}
onClick={() => setAttributes({ width: widthValue })}
>
{widthValue}%
</Button>
</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withInspectorControl');
wp.hooks.addFilter(
'editor.BlockEdit',
'core/button',
withInspectorControls
);
Next, a new additional css style needs to be added that (matches the existing width presets structure) for the new custom width, eg:
style.scss
$blocks-block__margin: 0.5em;
&.wp-block-button__width-33 {
width: calc(33.33% - #{ $blocks-block__margin });
}
And there you have it..
The easiest way to put all the code above together/working is to create your own Gutenberg block (and that in itself can be challenging if you aren't familiar with the process or ReactJS). I too have come across similiar challenges with Gutenberg, so I wanted to provide a detailed solution for this kind of issue that works.
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%
}
I have following React code
Code
What I would like is to when I hover my "E-commerce" picture App component background should change on "E-commerce" picture background.
So respectively and for other pictures.
I will be very grateful if you help me solve this problem.
Context, according to the React docs, should be used only for truly global state like current user or theme. Using context for components makes them less reusable.
updated code
Your component tree is App -> SolutionBox -> SolutionItem.
You want to "react" to an event in SolutionItem in App but there is SolutionBox inbetween them so you have to thread the event thru SolutionBox to App.
Step 1
Add a prop to SolutionItem called on OnHover, this will be a function call back that any parent component can use to react to changes.
function SolutionsSectionBoxItem({ solutionIMG, onHover }) {
let callOnHover = state => {
if (_.isFunction(onHover)) {
onHover(state);
}
};
return (
<div className="solutions-section-item-box">
<img
src={solutionIMG}
alt=""
onMouseEnter={() => {
callOnHover(true);
}}
onMouseLeave={() => {
callOnHover(false);
}}
className="solutions-section-item-img"
/>
</div>
);
}
Step 2
Add a prop to SolutionBoxItem called on BGChanged, this will again be a function call back that will be called when any solutionitem onhover happens. This function will take a menuName string and pass either the current menu name or default.
function SolutionsSectionBox({ onBGChanged }) {
let callBGChanged = menuName => {
if (_.isFunction(onBGChanged)) {
onBGChanged(menuName);
}
};
return (
<div className="solutions-section-box-box">
<SolutionItem
solutionIMG={Ecommerce}
onHover={state => {
callBGChanged(state === true ? "Ecommerce" : "default");
}}
/>
<SolutionItem
solutionIMG={SalesMarketing}
onHover={state => {
callBGChanged(state === true ? "SalesMarketing" : "default");
}}
/>
<SolutionItem
solutionIMG={Analytics}
onHover={state => {
callBGChanged(state === true ? "Analytics" : "default");
}}
/>
<SolutionItem
solutionIMG={Middleware}
onHover={state => {
callBGChanged(state === true ? "Middleware" : "default");
}}
/>
</div>
);
}
Step 3
In the App component listen for the changes. In here we now set state when ever the mouse enters or leaves a solution item. From here you have to change the background, you are using css to control the background url, this will be harder since you now need css class for each background type. You could use the bgImage state value to change the name of the extra css className like 'AppSalesMarketing', 'AppEcommerce', etc.
export default function App() {
const [bgImage, setbgImage] = useState(E);
const onBGChanged = menuName => {
setbgImage(menuName);
};
return (
<div className={`App ${bgImage === "default" ? "" : `App${bgImage}`}`}>
<SolutionBox onBGChanged={onBGChanged} />
</div>
);
}
In CSS
Leave the original App class but based on the bgImage value add an additional one using the name of the bgImage + App like below to cascade down the updated background-image value.
.AppEcommerce {
background-image: url(https://placekitten.com/600/600);
}
.AppSalesMarketing {
background-image: url(https://placekitten.com/500/800);
}
.AppAnalytics {
background-image: url(https://placekitten.com/800/500);
}
.AppMiddleware {
background-image: url(https://placekitten.com/700/700);
}
Extra
I added lodash to test that the incoming props are functions before I call them, it is good to do defensive programming because you never know who may use your component in the future.
let callBGChanged = menuName => {
if (_.isFunction(onBGChanged)) {
onBGChanged(menuName);
}
};
Two ways to solve the problem. One is passing down a function to update state, the other is to useContext. In this case it makes sense to use context because you are passing down a function through multiple components that do not care about the function.
First thing to do is make the background image dynamic in the div's style and use context:
// Put this outside the component
export const BackgroundContext = React.createContext(null);
// -- snip
const [backgroundImage, setBackgroundImage] = useState(Ecommerce);
const updateBackgroundImage = newImage => setBackgroundImage(newImage);
// -- snip
<BackgroundContext.Provider value={updateBackgroundImage}>
<div className="App" style={{ backgroundImage: `url(${backgroundImage})` }}>
{/* -- snip */}
</BackgroundContext.Provider>
Now in your SolutionsSectionBoxItem component you can import the background context:
import BackgroundContext from "../App";
Then using that context and react's mouseover api, update the selected background image:
const setBackgroundImage = useContext(BackgroundContext);
// -- snip
<img onMouseOver={() => setBackgroundImage(solutionIMG)} {/* -- snip -- */} />
You can read more here: https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down
I am working on a react component and I need to limit the displayed text in a field that changes based on a input component. I am trying to make it so when the text box input becomes longer than the width of the component, to display what can fit followed by ... . I have something that works but it uses width: field to set how wide the text can go and I am looking for a responsive way to make it fit more or less text
<span
className='itemTitle'
onMouseLeave={this.handleMouseLeave}
id = 'itemTitle'
style = {{width: '420px', "whiteSpace": "nowrap",
overflow:"hidden !important",
'textOverflow': "ellipsis",
'display': 'inline-block'}}>
{prompt || card.get('promptText')}
</span>
The solution I came up with is as follows.
From the parent component which renders a Title Component, I add a ref and on add a resize eventlistener which sends new props to the ItemTitle component.
<div ref={input => {{this.rangeInput = input}}}>
<ItemTitle
prompt={prompt}
{...this.props}
width = {this.state.width}
/>
</div>
updateDimensions = () => {
this.setState({
width: this.rangeInput.offsetWidth
})
}
componentDidMount() {
this.updateDimensions();
window.addEventListener("resize", this.updateDimensions);
}
/**
* Remove event listener
*/
componentWillUnmount() {
window.removeEventListener("resize", this.updateDimensions);
}
Then in ItemTitle.js
<span
className='itemTitle'
onMouseLeave={this.handleMouseLeave}
id = 'itemTitle'
style = {{width: this.state.width - 140, "whiteSpace": "nowrap",
overflow:"hidden !important",
'textOverflow': "ellipsis",
'display': 'inline-block'}}>
{prompt || card.get('promptText')}
</span>