Skip to content

Commit

Permalink
Zoom in-out animation on CVV field
Browse files Browse the repository at this point in the history
  • Loading branch information
jasminmif committed Dec 24, 2019
1 parent 06de3b5 commit a502ca6
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 106 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"prettier.singleQuote": true,
"javascript.preferences.quoteStyle": "single",
"prettier.tabWidth": 4
}
33 changes: 21 additions & 12 deletions src/screens/MainScreen/components/card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const CARDS = {
mastercard: '^5[1-5]',
discover: '^6011',
unionpay: '^62',
troy: '^9792',
troy: '^9792'
};

class Card extends Component {
Expand Down Expand Up @@ -57,13 +57,14 @@ class Card extends Component {
}
};

outlineElementStyle = element => element
? {
width: `${element.offsetWidth}px`,
height: `${element.offsetHeight}px`,
transform: `translateX(${element.offsetLeft}px) translateY(${element.offsetTop}px)`
}
: null;
outlineElementStyle = element =>
element
? {
width: `${element.offsetWidth}px`,
height: `${element.offsetHeight}px`,
transform: `translateX(${element.offsetLeft}px) translateY(${element.offsetTop}px)`
}
: null;

componentDidUpdate(prevProps) {
const { currentFocusedElm } = this.props;
Expand Down Expand Up @@ -291,13 +292,21 @@ class Card extends Component {
className="card-item__bg"
/>
</div>
<div className="card-item__band"/>
<div className="card-item__band" />
<div className="card-item__cvv">
<div className="card-item__cvvTitle">CVV</div>
<div className="card-item__cvvBand">
{cardCvv.map((val, index) => (
<span key={index}>*</span>
))}
<TransitionGroup>
{cardCvv.map((val, index) => (
<CSSTransition
classNames="zoom-in-out"
key={index}
timeout={250}
>
<span>*</span>
</CSSTransition>
))}
</TransitionGroup>
</div>
<div className="card-item__type">
<img
Expand Down
34 changes: 34 additions & 0 deletions src/screens/MainScreen/components/card/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@
@media screen and (max-width: 360px) {
margin-bottom: 15px;
}

span {
display: inline-block;
}
}
}

Expand Down Expand Up @@ -441,3 +445,33 @@
.slide-fade-up-exit-done {
opacity: 0;
}

.zoom-in-out-enter {
transform: translateY(6px) scale(3.5);
transition-delay: 0.1s;
filter: blur(0.4px);
opacity: 0;
}

.zoom-in-out-enter-active {
transition: all 250ms ease-in-out;
transform: translateY(0px) scale(1);
filter: blur(0px);
opacity: 1;
}

.zoom-in-out-enter-done {
opacity: 1;
}

.zoom-in-out-exit {
opacity: 1;
}

.zoom-in-out-exit-active {
transition: all 150ms ease-in-out;
transition-delay: 0.1s;
transform: translateY(4px) scale(2.3);
filter: blur(0.4px);
position: relative;
}
188 changes: 94 additions & 94 deletions src/screens/MainScreen/index.js
Original file line number Diff line number Diff line change
@@ -1,109 +1,109 @@
import React, { useState, useRef } from 'react';
import CForm from './components/form';
import Card from './components/card';
import React, { useState, useRef } from "react";
import CForm from "./components/form";
import Card from "./components/card";

const defaultCardNo = '#### #### #### ####';
const defaultCardHolderName = 'FULL NAME';
const defaultCardMonth = '';
const defaultCardYear = '';
const defaultCardCvv = '';
const defaultCardNo = "#### #### #### ####";
const defaultCardHolderName = "FULL NAME";
const defaultCardMonth = "";
const defaultCardYear = "";
const defaultCardCvv = "";

const MainScreen = () => {
const initialState = {
cardNumber: defaultCardNo,
cardHolder: defaultCardHolderName,
cardMonth: defaultCardMonth,
cardYear: defaultCardYear,
cardCvv: defaultCardCvv,
isCardFlipped: false,
currentFocusedElm: null
};
const [state, setState] = useState(initialState);
const initialState = {
cardNumber: defaultCardNo,
cardHolder: defaultCardHolderName,
cardMonth: defaultCardMonth,
cardYear: defaultCardYear,
cardCvv: defaultCardCvv,
isCardFlipped: false,
currentFocusedElm: null
};
const [state, setState] = useState(initialState);

const updateStateValue = ({ name, value }) => {
setState({
...state,
[name]: value || initialState[name]
});
};
const updateStateValue = ({ name, value }) => {
setState({
...state,
[name]: value || initialState[name]
});
};

const {
cardNumber,
cardHolder,
cardMonth,
cardYear,
cardCvv,
isCardFlipped
} = state;
let { currentFocusedElm } = state;
const {
cardNumber,
cardHolder,
cardMonth,
cardYear,
cardCvv,
isCardFlipped
} = state;
let { currentFocusedElm } = state;

// References for the Form Inputs
let formFieldsRefObj = {
cardNumber: useRef(),
cardHolder: useRef(),
cardDate: useRef(),
cardCvv: useRef()
};
// References for the Form Inputs
let formFieldsRefObj = {
cardNumber: useRef(),
cardHolder: useRef(),
cardDate: useRef(),
cardCvv: useRef()
};

let onCardElementClick = key => {
focusFormFieldByKey(key);
};
let onCardElementClick = key => {
focusFormFieldByKey(key);
};

let focusFormFieldByKey = key => {
formFieldsRefObj[key].current.focus();
};
let focusFormFieldByKey = key => {
formFieldsRefObj[key].current.focus();
};

// This are the references for the Card DIV elements
let cardElementsRef = {
cardNumber: null,
cardHolder: null,
cardDate: null
};
// This are the references for the Card DIV elements
let cardElementsRef = {
cardNumber: null,
cardHolder: null,
cardDate: null
};

let onCardFormInputFocus = (_event, inputName) => {
setState({
...state,
currentFocusedElm: cardElementsRef[inputName]
});
};
let onCardFormInputFocus = (_event, inputName) => {
setState({
...state,
currentFocusedElm: cardElementsRef[inputName]
});
};

let onCardInputBlur = event => {
setState({
...state,
currentFocusedElm: null
});
};
let onCardInputBlur = event => {
setState({
...state,
currentFocusedElm: null
});
};

return (
<div className="wrapper">
<CForm
onUpdateStateValue={updateStateValue}
cardNumberRef={formFieldsRefObj.cardNumber}
cardHolderRef={formFieldsRefObj.cardHolder}
cardDateRef={formFieldsRefObj.cardDate}
onCardInputFocus={onCardFormInputFocus}
onCardInputBlur={onCardInputBlur}
>
<Card
cardNumber={cardNumber}
cardHolder={cardHolder}
cardMonth={cardMonth}
cardYear={cardYear}
cardCvv={cardCvv}
isCardFlipped={isCardFlipped}
currentFocusedElm={currentFocusedElm}
onCardElementClick={onCardElementClick}
cardNumberRef={node =>
(cardElementsRef['cardNumber'] = node)
}
cardHolderRef={node =>
(cardElementsRef['cardHolder'] = node)
}
cardDateRef={node => (cardElementsRef['cardDate'] = node)}
></Card>
</CForm>
</div>
);
return (
<div className="wrapper">
<CForm
onUpdateStateValue={updateStateValue}
cardNumberRef={formFieldsRefObj.cardNumber}
cardHolderRef={formFieldsRefObj.cardHolder}
cardDateRef={formFieldsRefObj.cardDate}
onCardInputFocus={onCardFormInputFocus}
onCardInputBlur={onCardInputBlur}
>
<Card
cardNumber={cardNumber}
cardHolder={cardHolder}
cardMonth={cardMonth}
cardYear={cardYear}
cardCvv={cardCvv}
isCardFlipped={isCardFlipped}
currentFocusedElm={currentFocusedElm}
onCardElementClick={onCardElementClick}
cardNumberRef={node =>
(cardElementsRef["cardNumber"] = node)
}
cardHolderRef={node =>
(cardElementsRef["cardHolder"] = node)
}
cardDateRef={node => (cardElementsRef["cardDate"] = node)}
></Card>
</CForm>
</div>
);
};

export default MainScreen;

0 comments on commit a502ca6

Please sign in to comment.