I'm trying to use react lazy. I don't want the suspense to cover the page, but when it loads a component it shows the suspense blocked icon on the whole page.
How can I show it just where the component is supposed to be?
The lazy function:
const LandingPage = lazy(() =>
import('./auth/landing/landing').then(({ LandingPage }) => ({ default: LandingPage }))
);
<Suspense fallback={<Loader />}>
<LandingPage />
</Suspense>
The loader component:
import React from 'react';
import classnames from 'classnames';
import styled from 'styled-components';
// eslint-disable-next-line import/no-default-export
export default React.memo(styled(({ className }) => (
<div className={classnames('loader', className)}>
<span className="loader__ball loader__ball--1" />
<span className="loader__ball loader__ball--2" />
<span className="loader__ball loader__ball--3" />
</div>
))`
display: flex;
position: absolute;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
span.loader__ball {
display: inline-block;
margin: auto 0.25rem;
height: 0.75rem;
width: 0.75rem;
border-radius: 0.375rem;
background: #000000;
&.loader__ball--1,
&.loader__ball--2,
&.loader__ball--3 {
animation: bulging 2s infinite ease-in-out;
}
&.loader__ball--1 {
animation-delay: -0.4s;
}
&.loader__ball--2 {
animation-delay: -0.2s;
}
#keyframes bulging {
0%,
80%,
100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
}
`);
thanks to anyone who will answer:)
This probably happens because of your CSS.
position: absolute;
width: 100%;
height: 100%;
If you don't have a container (where your Suspense is positioned in) with position: relative you will end up with a ball absolute positioned and stretched over your entire screen.
I put your snippet in a plain HTML/CSS fiddle, so you can see what to do:
https://jsfiddle.net/qLzcuo7h/
As you can see you would expect that your loader is within the both component boxes. But they aren't.
What you need to add is position: relative to the .component to make it work.
In you given code I can't see what element your parent is, since the Suspense is the outer element. I can't see where you will put that element.
The below fiddle is with the relative addition.
https://jsfiddle.net/qLzcuo7h/1/
Hope this will clear things up.
Related
I am trying to create draggable cards that can also flip over on click.
This is my card
import { useState } from 'react'
import './Card.scss'
function Card() {
const [flip, setFlip] = useState(false)
return (
<div className={`card ${flip ? "flip" : ""}`}>
<div className="front" onClick={()=>{setFlip(!flip)}}>
<h1>Front</h1>
</div>
<div className="back" onClick={()=>{setFlip(!flip)}}>
<h1>Back</h1>
</div>
</div>
)
}
export default Card
This is the Draggable wrapper for the Card
import Draggable from 'react-draggable'
import Card from './Card'
function DraggableCard() {
return (
<Draggable>
<div>
<Card />
</div>
</Draggable>
)
}
export default DraggableCard
This is the CSS that is supposed to trigger onClick for the Card to flip
.card {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
border-radius: 20px;
transform: perspective(1000px) rotateY(var(--rotate-y, 0deg))
translate(var(--translate-y, 0))
rotate(var(--rotate, 0deg));
transition: transform 0.7s;
transform-style: preserve-3d;
cursor: pointer;
height: 300px;
width: 200px;
background-color: rgb(219, 14, 14);
}
.front {
position: absolute;
}
.back {
position: absolute;
transform: rotateY(180deg);
}
.front, .back {
height: 100%;
width: 100%;
backface-visibility: hidden;
transition: transform 1s;
}
.card.flip {
--rotate-y: -180deg;
}
The onClick handler in the Card should change the useState for "flip" and then, in turn, alter the className from "card" to "card flip" this should then trigger the CSS to flip the card. I can see that the className is not changing on click.
I saw that the Draggable README talked about using
Use an intermediate wrapper (<Draggable><span>...</span></Draggable>) in this case.
I added the extra <div> around the Card component in DraggableCard, but it did not seem to change the outcome. Did I miss understanding the README from react-draggable?
I assume that it is being overridden by the Draggable component but am struggling to figure out how not to let this happen.
I have a simple application in Vue.js and I have a component that loads 1 image and 2 texts on the screen, very simple.
However I noticed that every time the image takes a few milliseconds to load than the texts, giving an impression of slowness.
One more piece of information, sometimes it loads quickly and sometimes it takes a while to load. Does this have to do with my machine's performance?
Is there a way for me to optimize this image loading so that it doesn't show the customer this loading?
**Dispenser.vue**
<template>
<div>
<gui-action1 :imageName="this.imageName" :title="this.title" :message="this.message" :showLoader="false">
</gui-action1>
</div>
</template>
<script>
import Action1 from '../../Guidance/Action1.vue'
export default {
data(){
return{
optionSelected: this.$route.params.optionSelected,
imageName: 'Organization_Image_Interaction_WaitCountReal',
title: 'Ainda não finalizamos',
message: 'Aguarde a contagem das notas'
}
},
components: {
'gui-action1': Action1
},
created(){
setTimeout( () => this.$router.push({ path: "/withdraw/finishing"}), 4000);
}
}
</script>
<style >
#media screen and (max-width: 1280px) {
}
</style>
**Action.vue (Component)**
<template>
<div class="guidance">
<div class="guidance-title" >
{{title}}
</div>
<div class="guidance-image" >
<img :src="require('../../../static/' +`${imageName}`+ '.svg')">
</div>
<div class="guidance-message" >
{{message}}
</div>
<div v-bind:class="{ 'loader': showLoader }" ></div>
</div>
</template>
<script>
export default {
props: ['imageName', 'title', 'message', 'showLoader'],
data(){
return{
imageNameDefault: 'Organization_Image_Interaction_WaitCountReal'
}
}
}
</script>
<style>
#media screen and (max-width: 1280px) {
.guidance{
position: relative;
top: 70px;
left: 30px;
}
.guidance-image{
position: relative;
top:200px;
left: 220px;
}
.guidance-title{
position: relative;
top:140px;
left: -40px;
font-size: 55px;
color: white;
text-align: center;
}
.guidance-message{
position: absolute;
width: 100%;
top:650px;
left: -40px;
font-size: 55px;
color: white;
text-align: center;
}
.loader {
border: 7px solid #f3f3f3; /* Light grey */
border-top: 7px solid #386083; /* Blue */
border-radius: 50%;
width: 130px;
height: 130px;
animation: spin 1.5s linear infinite;
position: relative;
left: 518px;
top: -80px;
opacity: 60%;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
}
</style>
You could use cloudinary-vue for some super simple but performant image loading.
It could allow for some simple image placeholder while loading with only
<cld-image
public-id="sample"
loading="lazy">
<cld-placeholder
type="vectorize">
</cld-placeholder>
</cld-image>
Here is a Gatsby.js (React) demo but it show pretty clearly how it works with Cloudinary: https://using-gatsby-image.gatsbyjs.org/blur-up/ (click on Blur up, Traced SVG etc on top of the page).
Ofc, Cloudinary will also resize it to your screen accordingly, may format it into .webp or even .avif (beta), serve it from a cool CDN and do can do a lot of plenty other stuff. Cannot recommend it enough tbh. Check their documentation and give it a try, it's free so you don't have much to lose.
There is a LOT to webperf (too much for a simple answer here), and here is probably one of the best article (redacted each year) about this topic, you will get an exhaustive list of things to implement if you want a blazing fast website: https://www.smashingmagazine.com/2021/01/front-end-performance-2021-free-pdf-checklist/
I am attempting to create a CTA component at the top of my react application, that contains the navbar and the CTA text. After successfully completing the component, I am noticing a minor bug that I would like to resolve. I am only providing my image with a width of 100% and no defined height. This causes the divs beneath the image to flicker upwards until the image has fully loaded. I know not providing the image with a defined height is causing it because the bug goes away when I provide the image with a random height. I am wondering if there is a way to provide the image with a responsive height that would behave in a similar way to just providing my image with 100% width.
my css code is as follows:
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
}
.container .container-background {
opacity: 0.25;
}
.container-background-img {
width: 100%;
position: relative;
}
.container .content {
position: relative;
z-index: 1;
}
.app-outer {
max-width: 1170px;
margin: 0 auto;
position: relative;
padding: 0rem 1rem;
}
#media only screen and (max-width: 1170px) {
.container-background-img {
height: 656px;
object-fit: cover;
}
}
#media only screen and (max-width: 768px) {
.container-background-img {
height: 653px;
object-fit: cover;
}
}
/* CODE ADDED */
#navbar {
position: absolute;
top: 0;
left: 0;
right: 0;
}
#content {
position: absolute;
top: 20%;
}
my jsx code is as follows:
import React from "react";
import "./styles.css";
export default function App() {
return (
<>
<div className="container">
<div className="container-background">
<img
id="rob"
src="https://i.imgur.com/iyFtMNA.jpg"
alt="bg"
className="container-background-img"
/>
</div>
<div id="content" className="content">
I am the CTA
</div>
<div id="navbar">
<div
style={{
backgroundColor: "white",
height: 100,
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
I am the navbar
</div>
</div>
</div>
<div>I am beneath the cta</div>
</>
);
}
the following link I have provided contains a code sandbox: https://codesandbox.io/s/issue-react-forked-4lsdm?file=/src/App.js:0-868
Please Note: *** within the code sandbox the issue is not very apparent, but within my react application it is much more noticeable
As you mentioned, the issue is not really clear to see from your sandbox code.
I am not sure this would fix your issue but instead of using image tag try setting your CTA component to have background-image() instead.
Make sure to add other background css attributes too such as
background-repeat: no-repeat;
background-size: cover;
background-posistion: center;
padding-bottom: 60%;
Make sure to add padding-bottom: 60% (Your image seems to have a 3:2(w:h) ratio);
Hopefully, this works for you!
I have a basic app with a text editor and a title bar. I don't want scrollbars to appear on the side unless the text editor goes into overflow. Even then, I don't want the titlebar to disappear during the scroll. Right now, it does.
I think there's some CSS witchcraft I'm missing here, or maybe I've done something wrong.
Using React, JS, and Electron. The text editor is Quill.js if that matters. Used create-react-app.
App.css:
.App {
min-height: 100%;
margin: 0;
background-color: red;
}
.editor {
background-color: rgb(29, 29, 29);
color: rgb(201, 201, 201);
min-width: 100%;
height: 100%;
position: absolute;
margin-top: 30px;
}
.app-bar {
-webkit-app-region: drag;
min-width: 100%;
background-color: green;
position: fixed;
height: 30px;
}
App.js:
import React, { Component } from 'react'
import ReactQuill from 'react-quill';
import './App.css';
import 'react-quill/dist/quill.bubble.css';
export class App extends Component {
constructor() {
super();
}
render() {
return (
<div className="App">
<div className="app-bar">
test
</div>
<div>
<ReactQuill theme="bubble" className="editor" />
</div>
</div>
);
}
}
export default App;
Screenshot of what I mean:
When I scroll down the text stays there, but the colour scrolls:
Try add this,
body{
margin-bottom:30px;
}
i have a Card and a Modal component like so
class Card extends Component {
constructor() {
super();
this.state = { showModal: false }
}
render() {
const { showModal } = this.state;
return (
{/* Some code */}
{showModal && <Modal />}
)
}
}
So, I don't want to render my Modal until it is required. Logic.
The Modal's job, in this context, is to display the full content of the Card component (The Card has a fixed height, so I cannot displaying every bit of information in there).
Now, at a higher level I have the following:
class App extends Component {
/* Some Code */
render() {
return (
<div>
<Content /> {/* Our content */}
<Overlay /> {/* Our all-purpose-overlay (we need it for the Modal) */}
</div>
)
}
}
The problem is that my Card component has the style position: relative and the Modal component has the a z-index and the style position: absolute.
I did some research and I read that nested elements with non-static
position will not work the same way regarding the z-index. The z-index will take effect only within the non-static element.
So I cannot make my Modal appear above the the Overlay component. Furthermore, The Card component has a overflow:hidden property. And so, the Modal gets cropped.
Here is a simple demonstration.
function toggleModal() {
var app = document.getElementById("app");
app.classList.toggle("-modal");
}
:root {
background: #ddd;
}
#app,
#overlay {
height:100vh;
width:100%;
}
#app {
display: flex;
align-items: center;
justify-content: center;
}
/* Overlay */
#overlay {
position: absolute;
top: 0;
left: 0;
z-index: 1;
visibility: hidden;
background: rgba(0,0,0,0.3);
}
.-modal #overlay {
visibility: visible !important;
}
/* Card */
#card {
position: relative;
width: 250px;
padding: 1em;
border-radius: 5px;
background: white;
overflow: hidden; /* Problem */
}
.content {
padding: 4em 0;
text-align: center;
}
.btn {
padding: 1em 2em;
border:none;
color:white;
float: right;
cursor: pointer;
transition: 0.2s ease;
background: #00abff;
}
.btn:hover {
background: #0c9de4;
}
/* Modal */
#modal {
width: 300px;
position: absolute;
top:0;
left: 50px; /* Modal Gets clipped */
visibility: hidden;
background-color:red;
}
.-modal #modal {
visibility: visible;
}
<div id="app">
<div id="card">
<div class="content">content</div>
<button class="btn" onclick="toggleModal()">Display Modal</button>
<div id="modal">
<div class="content">
<div>Modal</div>
<div>With same content</div>
<div>(under the Overlay and also cropped)</div>
</div>
</div>
</div>
<div id="overlay" onclick="toggleModal()"></div>
</div>
Question : How should I organize my components so that I do not get this problem?
I thought of having only one Modal at top level. Then I simply display it. But I need to render the children of the Card into the Modal.
How should I proceed?
Since you are using React, what I would actually recommend is to use a Portal to render your modal. One thing Portals solve in React are precisely this issue. If you are using a more recent version of React (16+) then you already have access to portals.
If you are using an older version of React, that is okay. You can use an implementation like this (react-portal) instead.
Now you will have your components/markup rendered in a totally separate React tree outside of the context of your containing <div> that has position: relative on it and you can absolute or fixed position it wherever you need to.