Skip to content

Commit

Permalink
update demo script to include a function version
Browse files Browse the repository at this point in the history
Illustrates how to work around issue #20
  • Loading branch information
nathanstitt committed Mar 16, 2020
1 parent 2942a8b commit 333af14
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 26 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -38,7 +38,7 @@ class MySillyCheckoutForm extends React.PureComponent {
onAuthorizationSuccess() {
this.setState({ isBraintreeReady : true });
}

onDataCollectorInstanceReady(err, dataCollectorInstance) {
if(!err) this.device_data = dataCollectorInstance.deviceData
}
Expand Down Expand Up @@ -76,7 +76,7 @@ class MySillyCheckoutForm extends React.PureComponent {
}
```

See [demo site](https://nathanstitt.github.io/react-braintree-fields/) for a working example. It renders [demo.jsx](demo.jsx)
See [demo site](https://nathanstitt.github.io/react-braintree-fields/) for a working example. It renders [demo/demo-class.jsx](demo-class.jsx) There's also a [demo/demo-functional.jsx](functional version) available that illustrates how to work around the issue of storing a function reference using setState that was discovered in #20

## Braintree Component

Expand Down
16 changes: 5 additions & 11 deletions demo.jsx → demo/demo-class.jsx
@@ -1,10 +1,8 @@
import { render } from 'react-dom';
import React from 'react';
import { Braintree, HostedField } from '../src/index';

import { Braintree, HostedField } from './src/index';


class BraintreeHostedfieldDemo extends React.PureComponent {
class Demo extends React.PureComponent {

constructor(props) {
super(props);
Expand All @@ -21,15 +19,13 @@ class BraintreeHostedfieldDemo extends React.PureComponent {
state = {}

onError(error) {
this.setState({ error });
this.setState({ error: error.message || String(error) });
}

getToken() {
this.tokenize().then(
token => this.setState({ token, error: null }),
).catch(
error => this.setState({ token: null, error }),
);
).catch(error => this.onError(error));
}

onCardTypeChange({ cards }) {
Expand Down Expand Up @@ -128,6 +124,4 @@ class BraintreeHostedfieldDemo extends React.PureComponent {
}
}

render((
<BraintreeHostedfieldDemo />
), document.getElementById('root'));
export default Demo;
122 changes: 122 additions & 0 deletions demo/demo-functional.jsx
@@ -0,0 +1,122 @@
import { render } from 'react-dom';
import React from 'react';
import { Braintree, HostedField } from '../src/index';

const Demo = () => {
const [tokenize, setTokenizeFunc] = React.useState()
const [cardType, setCardType] = React.useState('')
const [error, setError] = React.useState(null)
const [token, setToken] = React.useState(null)
const [focusedFieldName, setFocusedField] = React.useState('')
const numberField = React.useRef()
const cvvField = React.useRef();
console.log({ focusedFieldName })
const onAuthorizationSuccess = () => {
numberField.current.focus();
}

const onDataCollectorInstanceReady = (collector) => {
// DO SOMETHING with Braintree collector as needed
}

const handleError = (error) => {
setError(error.message || String(error));
}

const onFieldBlur = (field, event) => setFocusedField('')
const onFieldFocus = (field, event) => setFocusedField(event.emittedBy)

const onCardTypeChange = ({ cards }) => {
if (1 === cards.length) {
const [card] = cards;

setCardType(card.type);

if (card.code && card.code.name) {
cvvField.current.setPlaceholder(card.code.name);
} else {
cvvField.current.setPlaceholder('CVV');
}

} else {
setCardType('');
cvvField.current.setPlaceholder('CVV');
}
}

const getToken = () => {
tokenize()
.then(setToken)
.catch(handleError);
}

const renderResult = (title, obj) => {
if (!obj) { return null; }
return (
<div>
<b>{title}:</b>
<pre>{JSON.stringify(obj, null, 4)}</pre>
</div>
);
}

return (
<div>
<Braintree
className="demo"
authorization='sandbox_g42y39zw_348pk9cgf3bgyw2b'
onAuthorizationSuccess={onAuthorizationSuccess}
onDataCollectorInstanceReady={onDataCollectorInstanceReady}
onError={handleError}
onCardTypeChange={onCardTypeChange}
getTokenRef={ref => setTokenizeFunc(() => ref)}
styles={{
'input': {
'font-size': 'inherit',
},
':focus': {
'color': 'blue'
},
}}
>
{renderResult('Error', error)}
{renderResult('Token', token)}

<div>
Number:
<HostedField
type="number"
className={focusedFieldName == 'number' ? 'focused' : ''}
onBlur={onFieldBlur}
onFocus={onFieldFocus}
prefill="4111 1111 1111 1111"
ref={numberField}
/>
<p>Card type: {cardType}</p>
Date:
<HostedField
type="expirationDate"
onBlur={onFieldBlur}
onFocus={onFieldFocus}
className={focusedFieldName == 'expirationDate' ? 'focused' : ''}
/>
Month:
<HostedField type="expirationMonth" />
Year:
<HostedField type="expirationYear" />
CVV:
<HostedField type="cvv" placeholder="CVV" ref={cvvField} />
Zip:
<HostedField type="postalCode" />
</div>

</Braintree>
<div className="footer">
<button onClick={getToken}>Get nonce token</button>
</div>
</div>
)

}

export default Demo;
7 changes: 7 additions & 0 deletions demo/index.js
@@ -0,0 +1,7 @@
import { render } from 'react-dom';
import React from 'react';
import { Braintree, HostedField } from '../src/index';
//import Demo from './demo-class.jsx'
import Demo from './demo-functional.jsx'

render(React.createElement(Demo), document.getElementById('root'));
14 changes: 1 addition & 13 deletions webpack.config.js
Expand Up @@ -4,7 +4,7 @@ const path = require('path');
const config = {
mode: 'development',
entry: {
demo: __dirname + '/demo.jsx',
demo: __dirname + '/demo/index.js',
},
output: {
path: __dirname + '/docs',
Expand All @@ -17,18 +17,6 @@ const config = {
loader: 'babel-loader',
test: /\.jsx?$/,
exclude: /node_modules/,
options: {
plugins: [
'babel-plugin-transform-class-properties',
'babel-plugin-transform-function-bind',
'babel-plugin-transform-react-jsx',
].map(require.resolve),
presets: [
[require.resolve('babel-preset-es2015'), { modules: false }],
require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-1'),
],
},
},
],
},
Expand Down

0 comments on commit 333af14

Please sign in to comment.