CSSTransition not working with stripe elements React - reactjs

I have a CSSTransition that works until I add the CardElement from "#stripe/react-stripe-js";
<CSSTransition
classNames="method"
in={radio === 'add-card'}
exit={!(radio === 'add-card')}
timeout={500}
unmountOnExit>
<form id="payment-form" onSubmit={handleSubmit} className="stripe-ad">
<input
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter Email Address (Optional)"
/>
<CardElement id="card-element" options={cardStyle} onChange={handleChange} />
{error && (
<div className="card-error" role="alert">
{error}
</div>
)}
<p className={succeeded ? "result-message" : "result-message hidden"}>
Payment succeeded, see the result in your
<a
href={`https://dashboard.stripe.com/test/payments`}
>
{" "}
Stripe dashboard.
</a> Refresh the page to pay again.
</p>
</form>
</CSSTransition>
When I comment out the , the transition will work properly over the 500ms time interval. When I leave the Card element in, it will refuse to adhere to the transition rules.
I'm using the base cardstyle
const cardStyle = {
style: {
base: {
color: "#32325d",
fontFamily: 'Arial, sans-serif',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#32325d"
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
}
};
The problem is that the CardElement either has its own transition on mount, or the style needs to be changed. Has anyone ever had this issue with the stripe element on transition?

I suspect that this will not work as the Elements exist within a Stripe-hosted iframe. Only certain styles are supported on Elements:
https://stripe.com/docs/js/appendix/style
I suggest opening an issue on github with a minimal example of this, for example forked from the codesandbox demo.
https://github.com/stripe/react-stripe-js/issues

Related

React not rendering component with inline styling on IOS

I ran into a problem with my component not re-rendering after a state change, when using props driven inline styling, on IOS/iphone (not tested on ipad).
Here is the code sandbox: https://codesandbox.io/s/confident-meitner-2sju9?file=/src/FlexboxGap.jsx
Edit: adding the code here too as requested:
import { useState } from "react";
import "./FlexboxGap.styles.css";
function FlexboxGap({ visible, containerCat, propertiesCat }) {
const [gap, setGap] = useState(0);
const [rowGap, setRowGap] = useState(0);
const [columnGap, setColumnGap] = useState(0);
function onGapChange(event) {
setGap(event.target.value);
setRowGap(event.target.value);
setColumnGap(event.target.value);
}
function onRowChange(event) {
setRowGap(event.target.value);
}
function onColumnChange(event) {
setColumnGap(event.target.value);
}
return (
<div className="main-container">
<div>
{" "}
<div>gap: {gap}px</div>
<input
type="range"
className="slider-bar"
min={0}
max={20}
value={gap}
onChange={onGapChange}
/>
</div>
<div>
{" "}
<div>row-gap: {rowGap}px</div>
<input
type="range"
className="slider-bar"
min={0}
max={20}
value={rowGap}
onChange={onRowChange}
/>
</div>
<div>
{" "}
<div>column-gap: {columnGap}px</div>
<input
type="range"
className="slider-bar"
min={0}
max={20}
value={columnGap}
onChange={onColumnChange}
/>
</div>
<div
style={{
width: "100vw",
height: "250px",
backgroundColor: "grey",
display: "flex",
flexFlow: "row wrap",
justifyContent: "flex-start",
alignContent: "flex-start",
rowGap: `${rowGap}px`,
columnGap: `${columnGap}px`
}}
>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
<div className="graph-item">item</div>
{/* This last invisible div is a hack to "force" react to re-render, by referencing the props rowGap and columnGap.
Otherwise, the rerender fails to happen on iphones. Working on Android
and desktop */}
<div className="hack-ghost">{`${rowGap}${columnGap}`}</div>
</div>
</div>
);
}
export default FlexboxGap;
While the state of rowGap and rowColumn is successfully changed, as well as the style, the div that depends on it does not get updated on iphones (fully updated).
Works on desktop and android devices.
I found a hack by adding a div that references the 2 states I need, and everything now "works".
The problem is:
1- it is hacky and
2-i am not sure i fully understand what is going on.
I thought of this hack by thinking that "i needed react to notice that the state changed inside this element".
Is it an issue with the way that inline css works // an ios implementation particularity?
Kind regards.

React Hook Form reset Controller (value) to default

Here is an example of my component, wrapped into Controller
<div className="mt-1">
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={selectedMonth}
render={({ field }) => (
< SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => monthSelect(field.value)), [selectedMonth]}/>
)}
/>
</div>
For now I am just trying to reset it with a button. Later I'd love to conditionally reset, depending on the value in a sibling component. Would be great to get it work with the button in the first place:
<input
style={{ display: "block", marginTop: 20 }}
type="button"
onClick={() =>
reset(selectedBirthMonth)
}
value="Reset with values"
/>
I get en error: selectedBirthMonth is not defined. Bassicaly, what I am aming for,on click, the whole component goes to default / a state it had when first rendered. What am I missing?
reset didn't do the job somehow, but setValue did. However I am setting to a value, not to the original state after first render, but in my case it's same.
<input
style={{ display: "block", marginTop: 20 }}
type="button"
onClick={() =>
etValue('selectedBirthMonth', lastAvaliableMonth)
}
value="Reset with values"
/>

Autoclose bootstrap 5 Dropdown without toggle in React

I have a search field that shows data as dropdown.item when user is typing. The library is React Bootstrap (bootstrap 5). This is working great. The dropdown is showing. The problem is that the dropdown persist when clicking outside or navigating to a new link. The dropdown is in a header that does not get rerendered with the rest of the page. Using NextJS. Any tips on how to close a dropdown that has no toggle?
<form className="d-none d-sm-inline-block" style={{ zIndex: "1000" }}>
<div className="input-group input-group-navbar">
<input
type="text"
className="form-control"
placeholder="Søk"
aria-label="Search"
onChange={(event) => {
setSearchTerm(event.target.value);
}}
/>
<button className="btn" type="button">
<Icon.Search className="align-middle" />
</button>
</div>
{searchData.length >= 1 && (
<Dropdown style={{ position: "absolute", background: "white" }} autoClose="outside">
{searchData.slice(0, 10).map((element, index) => {
return (
<Link key={element.agressoResourceId} href={`employees/69918`} passHref replace={true}>
<Dropdown.Item>
{element.firstname} - {element.lastname}
</Dropdown.Item>
</Link>
);
})}
</Dropdown>
)}
</form>
The solution was to use onBlur event and hide the dropdown. The problem comes with the onblure is triggered before you press the item. The solution here was to use a setTimeout of 200ms.

Is the z-index incorrect for these radio toggles behind the Semantic-UI-React Loading component?

I'm working on a form that has Semantic-UI Radio toggles, and the loader and the toggle's appear to be loading in the wrong z-index.
I checked the css and the toggle contains the following
.ui.toggle.checkbox label:after {
z-index: 2;
}
while the loader is
.ui.dimmer {
z-index: 1000;
}
which seems like the appropriate behaviour. I want the toggles to be behind the loader to present the best user experience. Can anyone tell me if the current behaviour is by design or not? Trying to determine if this is a bug to be reported or a feature to be requested or if there's a problem with my implementation.
My code (edited for brevity)
import { Form, Dropdown, DropdownItemProps, Dimmer, Loader, Button, Icon, Segment } from "semantic-ui-react";
return (
<Fragment>
<div style={{ display: "flex", flexDirection: "column" }}>
<div className="ui segments">
<PageHeader
text="Some text"
subText="Some subtext"
pageIcon="cogs icon"
/>
</div>
<Dimmer.Dimmable dimmed={loading}>
<Dimmer simple active={loading}>
<Loader>Loading</Loader>{" "}
</Dimmer>
<Form onSubmit={() => save()}>
<Form.Checkbox
label="Label 1"
checked={display}
onChange={(e, { checked }) => setDisplay(!!checked)}
toggle
/>
<Form.Input
label="Label 2"
placeholder="Placeholder"
value={data}
onChange={(e, { value }) => setData(value)}
/>
</Form.Group>
</Form>
</Dimmer.Dimmable>
</div>
</Fragment>
);
The comment helped me out. The problem was resolved using https://coder-coder.com/z-index-isnt-working/#alternative-solution-remove-positioning-from-the-content-so-it-wont-limit-the-modals-z-index from the suggestion.
I used a sticky position for the form element. Not necessarily the best solution but it sufficed for this purpose.

How do I change text on the button for npm package react-microsoft-login?

I'm trying to build a login/register page that will allow multiple users to login/register with multiple login providers such as Microsoft, Google, Instragram etc.
I managed to figure out how to do it with Google and Instagram 3rd party npm packages however, with the Microsoft Login button, there is no option to change the text at all? Is this possible? I want to change it from "Sign in with Microsoft" to "Log in with Microsoft" and "Register with Microsoft" I have my own functionality to handle oAuth registration process.
Here is my code I'll only show the portion that I cannot figure out. In addition, this is the link that shows what props are available for the package.
Microsoft Login npm package doc
import React from 'react';
import { useDispatch } from 'react-redux';
import MicrosoftLogin from 'react-microsoft-login';
import { Link, useHistory } from 'react-router-dom';
import * as actions from 'redux/actions';
const microsoftResponse = (err, response) => {
console.log('err = ', err);
console.log('response successful', response);
};
const RegisterPage = () => {
const dispatch = useDispatch();
const history = useHistory();
return (
<Page title={'Register'}>
<div className={'loginContainer shadow-lg bg-white rounded'}>
<div className={'loginWrapper'}>
<div className={'row'}>
<div className={'col-md-6'}>
<div className={'wrapperOverlay px-4'}>
<h1 className={'text-center'} style={{ borderBottom: '4px solid #ff0000', color: '#ff0000', padding: '20px 0' }}><strong>Register</strong></h1>
<div className={'providers text-center'}>
<ButtonRow id={'loginProvider'}>
<MicrosoftLogin
clientId={xxxxxxxxx}
authCallback={microsoftResponse}
redirectUri={xxxxxxxxx}
/>
</ButtonRow>
</div>
<div className={'separator py-3'}>Or create a new local account</div>
<div className={'formContainer'}>
<Form
enableReinitialize
form={'exampleFormName'}
onSubmit={(values) => alert(JSON.stringify(values, null, 2))}
>
<FieldInput name={'email'} label={'Email'} type={'email'} placeholder={'Email Address'} />
<FieldInput name={'password'} label={'Password'} type={'password'} placeholder={'Password'} />
<FieldInput name={'confirmpassword'} label={'Confirm Password'} type={'password'} placeholder={'Confirm Password'} />
<div className={'resendConfirmation pb-3'}>
<Link to={'/resendemailConfirmation'}>Resend email confirmation</Link>
</div>
<Button className={'w-100 text-center'} type={'submit'} variant={'primary'} text={'Register'} style={{ fontSize: '20px' }} />
<div className={'form-group text-right'}>
<div className={'registerButton pt-3'}>
<span>Already have an Account?</span>
<Link to={'/login'}>
<span id={'question'}>Log In</span>
</Link>
</div>
</div>
</Form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Page>
);
};
export default RegisterPage;
You can't change text "as it is", because for a button used SVG image. But as workaround, you can pass your custom button by a children prop, with any text that you want.
<MicrosoftLogin clientId={clientId} authCallback={loginHandler}>
<button>Log in with Microsoft</button>
</MicrosoftLogin>
Few things to keep in mind:
you need to do styling for custom button from scratch
button styles should be based on Official Microsoft brand design

Resources