Skip to content

Commit

Permalink
Partial feature: BSB Input (#3105)
Browse files Browse the repository at this point in the history
* chore(deps): update dependency express to v4.21.2 (#3061)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-plugin-testing-library to v6.5.0 (#3060)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-plugin-storybook to v0.11.1 (#3058)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @changesets/cli to v2.27.11 (#3070)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency msw to v2.7.0 (#3074)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency globals to v15.14.0 (#3072)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency prettier to v3.4.2 (#3075)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @rollup/plugin-node-resolve to v15.3.1 (#3071)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* bsb input component

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
  • Loading branch information
m1aw and renovate[bot] authored Jan 22, 2025
1 parent df83f04 commit 3e2271d
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 215 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
},
"devDependencies": {
"@adyen/adyen-web-server": "1.0.0",
"@changesets/cli": "2.27.10",
"@changesets/cli": "2.27.11",
"@changesets/get-github-info": "0.6.0",
"concurrently": "8.2.2",
"prettier": "3.3.3"
"prettier": "3.4.2"
}
}
8 changes: 4 additions & 4 deletions packages/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"@rollup/plugin-commonjs": "26.0.3",
"@rollup/plugin-eslint": "9.0.5",
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-node-resolve": "15.3.0",
"@rollup/plugin-node-resolve": "15.3.1",
"@rollup/plugin-replace": "5.0.7",
"@rollup/plugin-terser": "0.4.4",
"@size-limit/preset-big-lib": "11.1.6",
Expand All @@ -113,9 +113,9 @@
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-react": "7.37.2",
"eslint-plugin-storybook": "0.8.0",
"eslint-plugin-testing-library": "6.2.2",
"globals": "15.8.0",
"eslint-plugin-storybook": "0.11.1",
"eslint-plugin-testing-library": "6.5.0",
"globals": "15.14.0",
"husky": "9.1.7",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
Expand Down
32 changes: 20 additions & 12 deletions packages/lib/src/components/PayTo/PayTo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ Types (previously in their own file)
*/
import { UIElementProps } from '../internal/UIElement/types';
import { TxVariants } from '../tx-variants';
import PayToInput from './components/PayToInput';
import { PayIdFormData } from './components/PayIDInput';
import { PayToIdentifierEnum } from './components/IdentifierSelector';
import PayToComponent, { PayToComponentData } from './components/PayToComponent';
import { BSBFormData } from './components/BSBInput';

export interface PayToConfiguration extends UIElementProps {
paymentData?: any;
data?: PayToData;
placeholders?: any; //TODO
}

export interface PayToData extends PayIdFormData {
export interface PayToData extends PayIdFormData, BSBFormData, PayToComponentData {
shopperAccountIdentifier: string;
}

Expand All @@ -38,15 +39,22 @@ const config = {
};

const getAccountIdentifier = (state: PayToData) => {
switch (state.selectedIdentifier) {
case PayToIdentifierEnum.email:
return state.email;
case PayToIdentifierEnum.abn:
return state.abn;
case PayToIdentifierEnum.orgid:
return state.orgid;
case PayToIdentifierEnum.phone:
return `${state.phonePrefix}-${state.phoneNumber}`;
// if it's BSB Input type merge bankAccount with BSB
if (state.selectedInput === 'bsb-option') {
return `${state.bsb}-${state.bankAccountNumber}`;
} else if (state.selectedInput === 'payid-option') {
// otherwise use the option in the dropdown
switch (state.selectedIdentifier) {
case PayToIdentifierEnum.email:
return state.email;
case PayToIdentifierEnum.abn:
return state.abn;
case PayToIdentifierEnum.orgid:
return state.orgid;
case PayToIdentifierEnum.phone:
// merge the phone prefix and number - see comment in ticket
return `${state.phonePrefix}-${state.phoneNumber}`;
}
}
};
/**
Expand Down Expand Up @@ -118,7 +126,7 @@ export class PayToElement extends UIElement<PayToConfiguration> {

return (
<CoreProvider i18n={this.props.i18n} loadingContext={this.props.loadingContext} resources={this.resources}>
<PayToInput
<PayToComponent
data={this.props.data}
placeholders={this.props.placeholders}
setComponentRef={this.setComponentRef}
Expand Down
134 changes: 123 additions & 11 deletions packages/lib/src/components/PayTo/components/BSBInput.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,129 @@
import { h } from 'preact';
import Fieldset from '../../internal/FormFields/Fieldset';
import { useEffect, useRef } from 'preact/hooks';
import useForm from '../../../utils/useForm';
import { getErrorMessage } from '../../../utils/getErrorMessage';
import Field from '../../internal/FormFields/Field';
import { useCoreContext } from '../../../core/Context/CoreProvider';
import InputText from '../../internal/FormFields/InputText';
import { bsbValidationRules } from './validate';
import './PayIDInput.scss';
import { phoneFormatters } from '../../internal/PhoneInput/validate';
import { ComponentMethodsRef } from '../../internal/UIElement/types';

export default function BSBInput() {
// const { i18n } = useCoreContext();
export interface BSBFormData {
bsb: string;
bankAccountNumber: string;
firstName: string;
lastName: string;
}

export interface BSBInputProps {
defaultData: BSBFormData;
placeholders: any; //TODO
onChange: (e) => void;
setComponentRef: (ref: ComponentMethodsRef) => void;
}

const BASE_SCHEMA = ['bankAccountNumber', 'bsb', 'firstName', 'lastName'];

export default function BSBInput({ setComponentRef, defaultData, placeholders, onChange }: BSBInputProps) {
const { i18n } = useCoreContext();

const form = useForm<BSBFormData>({
schema: BASE_SCHEMA,
defaultData: defaultData,
rules: bsbValidationRules,
formatters: phoneFormatters
});
const { handleChangeFor, triggerValidation, data, errors, valid, isValid } = form;

// standard onChange propagate to parent state
useEffect(() => {
onChange({ data, valid, errors, isValid });
}, [data, valid, errors, isValid]);

const payToRef = useRef<ComponentMethodsRef>({
showValidation: triggerValidation
});

useEffect(() => {
setComponentRef(payToRef.current);
}, [setComponentRef]);

return (
<Fieldset classNameModifiers={['payto__bsb_input']} label={'payto.bsb.header'} description={'payto.bsb.description'}>
<Field
label={i18n.get('payto.bsb.label.bankAccountNumber')}
classNameModifiers={['col-60', 'bankAccountNumber']}
errorMessage={getErrorMessage(i18n, errors.bankAccountNumber, i18n.get('payto.bsb.label.bankAccountNumber'))}
name={'bankAccountNumber'}
i18n={i18n}
>
<InputText
name={'bankAccountNumber'}
value={data.bankAccountNumber}
onInput={handleChangeFor('bankAccountNumber', 'input')}
onBlur={handleChangeFor('bankAccountNumber', 'blur')}
placeholder={placeholders?.bankAccountNumber}
required={true}
/>
</Field>

// TODO type this
// const { handleChangeFor, triggerValidation, data, valid, errors } = useForm<any>({
// schema: ['beneficiaryId']
// });
//
// const [status, setStatus] = useState<string>('ready');
<Field
label={i18n.get('payto.bsb.label.bsb')}
classNameModifiers={['col-40', 'bsb']}
errorMessage={getErrorMessage(i18n, errors.bsb, i18n.get('payto.bsb.label.bsb'))}
name={'bsb'}
i18n={i18n}
>
<InputText
name={'bsb'}
value={data.bsb}
onInput={handleChangeFor('bsb', 'input')}
onBlur={handleChangeFor('bsb', 'blur')}
placeholder={placeholders?.bsb}
required={true}
/>
</Field>

// this.setStatus = setStatus;
// this.showValidation = triggerValidation;
<Field
label={i18n.get('firstName')}
classNameModifiers={['col-50', 'firstName']}
errorMessage={getErrorMessage(i18n, errors.firstName, i18n.get('firstName'))}
name={'firstName'}
i18n={i18n}
>
<InputText
name={'firstName'}
value={data.firstName}
classNameModifiers={['firstName']}
onInput={handleChangeFor('firstName', 'input')}
onBlur={handleChangeFor('firstName', 'input')}
placeholder={placeholders?.firstName}
spellCheck={false}
required={true}
/>
</Field>

return <p>BSBInput.tsx</p>;
<Field
label={i18n.get('lastName')}
classNameModifiers={['col-50', 'lastName']}
errorMessage={getErrorMessage(i18n, errors.lastName, i18n.get('lastName'))}
name={'lastName'}
i18n={i18n}
>
<InputText
name={'lastName'}
value={data.lastName}
classNameModifiers={['lastName']}
onInput={handleChangeFor('lastName', 'input')}
onBlur={handleChangeFor('lastName', 'blur')}
placeholder={placeholders?.lastName}
spellCheck={false}
required={true}
/>
</Field>
</Fieldset>
);
}
12 changes: 7 additions & 5 deletions packages/lib/src/components/PayTo/components/PayIDInput.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
@import 'styles/variable-generator';

.adyen-checkout__fieldset--payto__payid_input {
margin-top: token(spacer-070);

.adyen-checkout__fieldset__fields {
.adyen-checkout__payto-component {
.adyen-checkout__fieldset {
margin-top: token(spacer-070);
gap: 0 token(spacer-060);

.adyen-checkout__fieldset__fields {
margin-top: token(spacer-070);
gap: 0 token(spacer-060);
}
}
}
76 changes: 76 additions & 0 deletions packages/lib/src/components/PayTo/components/PayToComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { h } from 'preact';
import LoadingWrapper from '../../internal/LoadingWrapper';
import SegmentedControl from '../../internal/SegmentedControl';
import { useState } from 'preact/hooks';
import { SegmentedControlOptions } from '../../internal/SegmentedControl/SegmentedControl';
import PayIDInput from './PayIDInput';
import BSBInput from './BSBInput';
import { useCoreContext } from '../../../core/Context/CoreProvider';

export type PayToInputOption = 'payid-option' | 'bsb-option';

export type PayToComponentData = { selectedInput: PayToInputOption };

const inputOptions: SegmentedControlOptions<PayToInputOption> = [
{
value: 'payid-option',
label: 'PayID',
htmlProps: {
id: 'payid-option', // TODO move this to i18n
'aria-controls': 'payid-input',
'aria-expanded': true // TODO move this logic to segmented controller
}
},
{
value: 'bsb-option',
label: 'BSB and account number', // TODO move this to i18n
htmlProps: {
id: 'bsb-option',
'aria-controls': 'bsb-input',
'aria-expanded': false // TODO move this logic to segmented controller
}
}
];

export default function PayToComponent(props) {
const { i18n } = useCoreContext();

const [status, setStatus] = useState<string>('ready');

this.setStatus = setStatus;

const defaultOption = inputOptions[0].value;
const [selectedInput, setSelectedInput] = useState<PayToInputOption>(defaultOption);

const onChange = ({ data, valid, errors, isValid }) => {
// merge selected input to as data, this keep the input layers untouched
props.onChange({ data: { selectedInput: selectedInput, ...data }, valid, errors, isValid });
};

return (
<LoadingWrapper>
<div className="adyen-checkout__payto-component">
<SegmentedControl selectedValue={selectedInput} options={inputOptions} onChange={setSelectedInput} />
{selectedInput === 'payid-option' && (
<PayIDInput
setComponentRef={props.setComponentRef}
onChange={onChange}
defaultData={props.data}
onError={props.onError}
placeholders={props.placeholders}
/>
)}
{selectedInput === 'bsb-option' && (
<BSBInput
setComponentRef={props.setComponentRef}
onChange={onChange}
defaultData={props.data}
placeholders={props.placeholders}
/>
)}

{props.showPayButton && props.payButton({ status, label: i18n.get('confirmPurchase') })}
</div>
</LoadingWrapper>
);
}
62 changes: 0 additions & 62 deletions packages/lib/src/components/PayTo/components/PayToInput.tsx

This file was deleted.

Loading

0 comments on commit 3e2271d

Please sign in to comment.