Typescript conversion of DynamicForm Component (https://github.com/woocommerce/woocommerce-admin/pull/6981)
This commit is contained in:
parent
f0b494142e
commit
9fda36439e
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
// Making use of typescript no-shadow instead, fixes issues with enum.
|
||||
'no-shadow': 'off',
|
||||
'@typescript-eslint/no-shadow': [ 'error' ],
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -6,8 +6,8 @@ import interpolateComponents from 'interpolate-components';
|
|||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import {
|
||||
Link,
|
||||
SettingsForm,
|
||||
WooRemotePaymentSettings,
|
||||
DynamicForm,
|
||||
WooRemotePaymentForm,
|
||||
Spinner,
|
||||
} from '@woocommerce/components';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
@ -29,7 +29,7 @@ export const PaymentConnect = ( {
|
|||
|
||||
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
||||
const { createNotice } = useDispatch( 'core/notices' );
|
||||
const slot = useSlot( `woocommerce_remote_payment_settings_${ key }` );
|
||||
const slot = useSlot( `woocommerce_remote_payment_form_${ key }` );
|
||||
const hasFills = Boolean( slot?.fills?.length );
|
||||
const [ state, setState ] = useState( 'loading' );
|
||||
const [ fields, setFields ] = useState( null );
|
||||
|
@ -70,6 +70,8 @@ export const PaymentConnect = ( {
|
|||
} );
|
||||
|
||||
const updateSettings = async ( values ) => {
|
||||
recordConnectStartEvent( key );
|
||||
|
||||
const options = {};
|
||||
|
||||
fields.forEach( ( field ) => {
|
||||
|
@ -107,15 +109,15 @@ export const PaymentConnect = ( {
|
|||
const getField = ( fieldId ) =>
|
||||
fields.find( ( field ) => field.id === fieldId );
|
||||
|
||||
for ( const [ valueKey, value ] of Object.entries( values ) ) {
|
||||
const field = getField( valueKey );
|
||||
for ( const [ fieldKey, value ] of Object.entries( values ) ) {
|
||||
const field = getField( fieldKey );
|
||||
// Matches any word that is capitalized aside from abrevitions like ID.
|
||||
const label = field.label.replace( /([A-Z][a-z]+)/g, ( val ) =>
|
||||
val.toLowerCase()
|
||||
);
|
||||
|
||||
if ( ! value ) {
|
||||
errors[ valueKey ] = `Please enter your ${ label }`;
|
||||
if ( ! ( value || field.type === 'checkbox' ) ) {
|
||||
errors[ fieldKey ] = `Please enter your ${ label }`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,13 +140,12 @@ export const PaymentConnect = ( {
|
|||
},
|
||||
} );
|
||||
|
||||
const DefaultSettings = ( props ) => (
|
||||
<SettingsForm
|
||||
const DefaultForm = ( props ) => (
|
||||
<DynamicForm
|
||||
fields={ fields }
|
||||
isBusy={ isOptionsRequesting }
|
||||
onSubmit={ updateSettings }
|
||||
onButtonClick={ () => recordConnectStartEvent( key ) }
|
||||
buttonLabel={ __( 'Proceed', 'woocommerce-admin' ) }
|
||||
submitLabel={ __( 'Proceed', 'woocommerce-admin' ) }
|
||||
validate={ validate }
|
||||
{ ...props }
|
||||
/>
|
||||
|
@ -168,9 +169,9 @@ export const PaymentConnect = ( {
|
|||
return (
|
||||
<>
|
||||
{ hasFills ? (
|
||||
<WooRemotePaymentSettings.Slot
|
||||
<WooRemotePaymentForm.Slot
|
||||
fillProps={ {
|
||||
defaultSettings: DefaultSettings,
|
||||
defaultForm: DefaultForm,
|
||||
defaultSubmit: updateSettings,
|
||||
defaultFields: fields,
|
||||
markConfigured: () => markConfigured( key ),
|
||||
|
@ -179,7 +180,7 @@ export const PaymentConnect = ( {
|
|||
/>
|
||||
) : (
|
||||
<>
|
||||
<DefaultSettings />
|
||||
<DefaultForm />
|
||||
<p>{ helpText }</p>
|
||||
</>
|
||||
) }
|
||||
|
|
|
@ -120,7 +120,7 @@ export const RemotePayments = ( { query } ) => {
|
|||
};
|
||||
|
||||
const currentMethod = useMemo( () => {
|
||||
if ( ! methods.length || ! query.method || isResolving ) {
|
||||
if ( ! query.method || isResolving || ! methods.length ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# DynamicForm
|
||||
|
||||
A component to handle form state and provide input helper props.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
const initialValues = { firstName: '' };
|
||||
|
||||
<DynamicForm
|
||||
fields={ fields }
|
||||
onSubmit={ ( values ) => {
|
||||
setSubmitted( values );
|
||||
} }
|
||||
isBusy={ false }
|
||||
onChange={ () => {} }
|
||||
validate={ () => ( {} ) }
|
||||
submitLabel="Submit"
|
||||
/>;
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| ------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `fields` | {} or [] | [] | An object to describe the structure and types of all fields, matching the structure returned by the [Settings API](https://docs.woocommerce.com/document/settings-api/) |
|
||||
| `isBusy` | Boolean | false | Boolean indicating busy state of submit button |
|
||||
| `onSubmit` | Function | `noop` | Function to call when a form is submitted with valid fields |
|
||||
| `onChange` | Function | `noop` | Function to call when any values on the form are changed |
|
||||
| `validate` | Function | `noop` | A function that is passed a list of all values and should return an `errors` object with error response |
|
||||
| `submitLabel` | String | "Proceed" | Label for submit button. |
|
||||
|
||||
### Fields structure
|
||||
|
||||
Please reference the [WordPress settings API documentation](https://docs.woocommerce.com/document/settings-api/) to better understand the structure expected for the fields property. This component accepts the object returned via the `settings` property when querying a gateway via the API, or simply the array provided by `Object.values(settings)`.
|
||||
|
||||
### Currently Supported Types
|
||||
|
||||
- Text
|
||||
- Password
|
||||
- Checkbox
|
||||
- Select
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Button } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Form } from '../index';
|
||||
import {
|
||||
TextField,
|
||||
PasswordField,
|
||||
CheckboxField,
|
||||
SelectField,
|
||||
} from './field-types';
|
||||
|
||||
import { Field, FormInputProps } from './types';
|
||||
|
||||
type DynamicFormProps = {
|
||||
fields: Field[] | { [ key: string ]: Field };
|
||||
validate: ( values: Record< string, string > ) => Record< string, string >;
|
||||
isBusy?: boolean;
|
||||
onSubmit?: ( values: Record< string, string > ) => void;
|
||||
onChange?: (
|
||||
value: Record< string, string >,
|
||||
values: Record< string, string >[],
|
||||
result: boolean
|
||||
) => void;
|
||||
submitLabel?: string;
|
||||
};
|
||||
|
||||
const fieldTypeMap = {
|
||||
text: TextField,
|
||||
password: PasswordField,
|
||||
checkbox: CheckboxField,
|
||||
select: SelectField,
|
||||
default: TextField,
|
||||
};
|
||||
|
||||
export const DynamicForm: React.FC< DynamicFormProps > = ( {
|
||||
fields: baseFields = [],
|
||||
isBusy = false,
|
||||
onSubmit = () => {},
|
||||
onChange = () => {},
|
||||
validate = () => ( {} ),
|
||||
submitLabel = __( 'Proceed', 'woocommerce-admin' ),
|
||||
} ) => {
|
||||
// Support accepting fields in the format provided by the API (object), but transform to Array
|
||||
const fields =
|
||||
baseFields instanceof Array ? baseFields : Object.values( baseFields );
|
||||
|
||||
const getInitialConfigValues = () =>
|
||||
fields.reduce(
|
||||
( data, field ) => ( {
|
||||
...data,
|
||||
[ field.id ]:
|
||||
field.type === 'checkbox'
|
||||
? field.value === 'yes'
|
||||
: field.value,
|
||||
} ),
|
||||
{}
|
||||
);
|
||||
|
||||
return (
|
||||
<Form
|
||||
initialValues={ getInitialConfigValues() }
|
||||
onChangeCallback={ onChange }
|
||||
onSubmitCallback={ onSubmit }
|
||||
validate={ validate }
|
||||
>
|
||||
{ ( {
|
||||
getInputProps,
|
||||
handleSubmit,
|
||||
}: {
|
||||
getInputProps: ( name: string ) => FormInputProps;
|
||||
handleSubmit: () => void;
|
||||
} ) => {
|
||||
return (
|
||||
<div className="woocommerce-component_dynamic-form">
|
||||
{ fields.map( ( field ) => {
|
||||
if (
|
||||
field.type &&
|
||||
! ( field.type in fieldTypeMap )
|
||||
) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(
|
||||
`Field type of ${ field.type } not current supported in DynamicForm component`
|
||||
);
|
||||
/* eslint-enable no-console */
|
||||
return null;
|
||||
}
|
||||
|
||||
const Control =
|
||||
fieldTypeMap[ field.type || 'default' ];
|
||||
return (
|
||||
<Control
|
||||
key={ field.id }
|
||||
field={ field }
|
||||
{ ...getInputProps( field.id ) }
|
||||
/>
|
||||
);
|
||||
} ) }
|
||||
|
||||
<Button
|
||||
isPrimary
|
||||
isBusy={ isBusy }
|
||||
onClick={ () => {
|
||||
handleSubmit();
|
||||
} }
|
||||
>
|
||||
{ submitLabel }
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
} }
|
||||
</Form>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { CheckboxControl } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ControlProps } from '../types';
|
||||
|
||||
export const CheckboxField: React.FC< ControlProps > = ( {
|
||||
field,
|
||||
onChange,
|
||||
...props
|
||||
} ) => {
|
||||
const { label, description } = field;
|
||||
|
||||
return (
|
||||
<CheckboxControl
|
||||
onChange={ ( val ) => onChange( val ) }
|
||||
title={ description }
|
||||
label={ label }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { TextField } from './field-text';
|
||||
import { ControlProps } from '../types';
|
||||
|
||||
export const PasswordField: React.FC< ControlProps > = ( props ) => {
|
||||
return <TextField { ...props } type="password" />;
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useMemo } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SelectControl } from '../../index';
|
||||
import { ControlProps } from '../types';
|
||||
|
||||
type SelectControlOption = {
|
||||
key: string;
|
||||
label: string;
|
||||
value: { id: string };
|
||||
};
|
||||
|
||||
const transformOptions = ( options: Record< string, string > ) =>
|
||||
Object.entries( options ).map( ( [ key, value ] ) => ( {
|
||||
key,
|
||||
label: value,
|
||||
value: { id: key },
|
||||
} ) );
|
||||
|
||||
export const SelectField: React.FC< ControlProps > = ( {
|
||||
field,
|
||||
...props
|
||||
} ) => {
|
||||
const { description, label, options = {} } = field;
|
||||
|
||||
const transformedOptions: SelectControlOption[] = useMemo(
|
||||
() => transformOptions( options ),
|
||||
[ options ]
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectControl
|
||||
title={ description }
|
||||
label={ label }
|
||||
options={ transformedOptions }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { TextControl } from '../../index';
|
||||
import { ControlProps } from '../types';
|
||||
|
||||
export const TextField: React.FC< ControlProps & { type?: string } > = ( {
|
||||
field,
|
||||
type = 'text',
|
||||
...props
|
||||
} ) => {
|
||||
const { label, description } = field;
|
||||
|
||||
return (
|
||||
<TextControl
|
||||
type={ type }
|
||||
title={ description }
|
||||
label={ label }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
export * from './field-text';
|
||||
export * from './field-password';
|
||||
export * from './field-checkbox';
|
||||
export * from './field-select';
|
|
@ -0,0 +1 @@
|
|||
export * from './dynamic-form';
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { SettingsForm } from '@woocommerce/components';
|
||||
import { DynamicForm } from '@woocommerce/components';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
||||
const fields = [
|
||||
|
@ -48,8 +48,8 @@ const fields = [
|
|||
label: 'Checkbox style',
|
||||
description: 'This is an example checkbox field.',
|
||||
type: 'checkbox',
|
||||
value: 'yes',
|
||||
default: 'yes',
|
||||
value: 'no',
|
||||
default: 'no',
|
||||
tip: 'This is an example checkbox field.',
|
||||
placeholder: '',
|
||||
},
|
||||
|
@ -64,22 +64,19 @@ const validate = ( values ) => {
|
|||
for ( const [ key, value ] of Object.entries( values ) ) {
|
||||
const field = getField( key );
|
||||
|
||||
if ( ! value ) {
|
||||
errors[ key ] =
|
||||
field.type === 'checkbox'
|
||||
? 'This is required'
|
||||
: `Please enter your ${ field.label.toLowerCase() }`;
|
||||
if ( ! ( value || field.type === 'checkbox' ) ) {
|
||||
errors[ key ] = `Please enter your ${ field.label.toLowerCase() }`;
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const SettingsExample = () => {
|
||||
const DynamicExample = () => {
|
||||
const [ submitted, setSubmitted ] = useState( null );
|
||||
return (
|
||||
<>
|
||||
<SettingsForm
|
||||
<DynamicForm
|
||||
fields={ fields }
|
||||
onSubmit={ ( values ) => setSubmitted( values ) }
|
||||
validate={ validate }
|
||||
|
@ -90,9 +87,9 @@ const SettingsExample = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const Basic = () => <SettingsExample />;
|
||||
export const Basic = () => <DynamicExample />;
|
||||
|
||||
export default {
|
||||
title: 'WooCommerce Admin/components/SettingsForm',
|
||||
component: SettingsForm,
|
||||
title: 'WooCommerce Admin/components/DynamicForm',
|
||||
component: DynamicForm,
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
.woocommerce-component-settings {
|
||||
.woocommerce-component_dynamic-form {
|
||||
.components-base-control {
|
||||
margin-top: $gap;
|
||||
margin-bottom: $gap;
|
|
@ -0,0 +1,22 @@
|
|||
export type Field = {
|
||||
id: string;
|
||||
type: 'text' | 'password' | 'checkbox' | 'select';
|
||||
title: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
default?: string;
|
||||
class?: string;
|
||||
css?: string;
|
||||
options?: Record< string, string >;
|
||||
tip?: string;
|
||||
value?: string;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export type FormInputProps = React.InputHTMLAttributes< HTMLInputElement > & {
|
||||
onChange: ( value: string | boolean ) => void;
|
||||
};
|
||||
|
||||
export type ControlProps = FormInputProps & {
|
||||
field: Field;
|
||||
};
|
|
@ -64,5 +64,5 @@ export { default as ViewMoreList } from './view-more-list';
|
|||
export { default as WebPreview } from './web-preview';
|
||||
export { Badge } from './badge';
|
||||
export { default as WooRemotePayment } from './woo-remote-payment';
|
||||
export { default as WooRemotePaymentSettings } from './woo-remote-payment-settings';
|
||||
export { SettingsForm } from './settings-form';
|
||||
export { default as WooRemotePaymentForm } from './woo-remote-payment-form';
|
||||
export { DynamicForm } from './dynamic-form';
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# SettingsForm
|
||||
|
||||
A component to handle form state and provide input helper props.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
const initialValues = { firstName: '' };
|
||||
|
||||
<SettingsForm
|
||||
fields={ fields }
|
||||
onSubmit={ ( values ) => {
|
||||
setSubmitted( values );
|
||||
} }
|
||||
isBusy={ false }
|
||||
onButtonClick={ () => {} }
|
||||
onChange={ () => {} }
|
||||
validate={ () => ( {} ) }
|
||||
buttonLabel="Submit"
|
||||
/>;
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `fields` | {} or [] | [] | An object to describe the structure and types of all fields, matching the structure returned by the [Settings API](https://docs.woocommerce.com/document/settings-api/) |
|
||||
| `isBusy` | Boolean | false | Boolean indicating busy state of submit button |
|
||||
| `onButtonClick` | Function | `noop` | Callback function executed when submit button is clicked (in addition to form submission) |
|
||||
| `onSubmit` | Function | `noop` | Function to call when a form is submitted with valid fields |
|
||||
| `onChange` | Function | `noop` | Function to call when any values on the form are changed |
|
||||
| `validate` | Function | `noop` | A function that is passed a list of all values and should return an `errors` object with error response |
|
||||
| `buttonLabel` | String | "Proceed" | Label for submit button. |
|
||||
|
||||
### Fields structure
|
||||
|
||||
Please reference the [WordPress settings API documentation](https://docs.woocommerce.com/document/settings-api/) to better understand the structure expected for the fields property. This component accepts the object returned via the `settings` property when querying a gateway via the API, or simply the array provided by `Object.values(settings)`.
|
||||
|
||||
### Currently Supported Types
|
||||
|
||||
- Text
|
||||
- Password
|
||||
- Checkbox
|
||||
- Select
|
|
@ -1,96 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Button } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Form } from '../index';
|
||||
import {
|
||||
SettingText,
|
||||
SettingPassword,
|
||||
SettingCheckbox,
|
||||
SettingSelect,
|
||||
} from './types';
|
||||
|
||||
const typeMap = {
|
||||
text: SettingText,
|
||||
password: SettingPassword,
|
||||
checkbox: SettingCheckbox,
|
||||
select: SettingSelect,
|
||||
default: SettingText,
|
||||
};
|
||||
|
||||
export const SettingsForm = ( {
|
||||
fields: baseFields = [],
|
||||
isBusy = false,
|
||||
onSubmit = () => {},
|
||||
onButtonClick = () => {},
|
||||
onChange = () => {},
|
||||
validate = () => ( {} ),
|
||||
buttonLabel = __( 'Proceed', 'woocommerce-admin' ),
|
||||
} ) => {
|
||||
// Support accepting fields in the format provided by the API (object), but transform to Array
|
||||
const fields =
|
||||
baseFields instanceof Array ? baseFields : Object.values( baseFields );
|
||||
|
||||
const getInitialConfigValues = () => {
|
||||
if ( fields ) {
|
||||
return fields.reduce(
|
||||
( data, field ) => ( {
|
||||
...data,
|
||||
[ field.id ]: field.value,
|
||||
} ),
|
||||
{}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Form
|
||||
initialValues={ getInitialConfigValues() }
|
||||
onChangeCallback={ onChange }
|
||||
onSubmitCallback={ onSubmit }
|
||||
validate={ validate }
|
||||
>
|
||||
{ ( { getInputProps, handleSubmit } ) => {
|
||||
return (
|
||||
<div className="woocommerce-component-settings">
|
||||
{ fields.map( ( field ) => {
|
||||
if ( field.type && ! ( field.type in typeMap ) ) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(
|
||||
`Field type of ${ field.type } not current supported in SettingsForm component`
|
||||
);
|
||||
/* eslint-enable no-console */
|
||||
return null;
|
||||
}
|
||||
|
||||
const Control = typeMap[ field.type || 'default' ];
|
||||
return (
|
||||
<Control
|
||||
key={ field.id }
|
||||
field={ field }
|
||||
{ ...getInputProps( field.id ) }
|
||||
/>
|
||||
);
|
||||
} ) }
|
||||
|
||||
<Button
|
||||
isPrimary
|
||||
isBusy={ isBusy }
|
||||
onClick={ ( event ) => {
|
||||
handleSubmit( event );
|
||||
onButtonClick();
|
||||
} }
|
||||
>
|
||||
{ buttonLabel }
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
} }
|
||||
</Form>
|
||||
);
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
export { SettingText } from './setting-text';
|
||||
export { SettingPassword } from './setting-password';
|
||||
export { SettingCheckbox } from './setting-checkbox';
|
||||
export { SettingSelect } from './setting-select';
|
|
@ -1,17 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { CheckboxControl } from '@wordpress/components';
|
||||
|
||||
export const SettingCheckbox = ( { field, ...props } ) => {
|
||||
const { label, id, description } = field;
|
||||
|
||||
return (
|
||||
<CheckboxControl
|
||||
title={ description }
|
||||
key={ id }
|
||||
label={ label }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SettingText } from './setting-text';
|
||||
|
||||
export const SettingPassword = ( props ) => {
|
||||
return <SettingText { ...props } type="password" />;
|
||||
};
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useMemo } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SelectControl } from '../../index';
|
||||
|
||||
const transformOptions = ( options ) => {
|
||||
return Object.keys( options ).reduce( ( all, curr ) => {
|
||||
all.push( {
|
||||
key: curr,
|
||||
label: options[ curr ],
|
||||
value: { id: curr },
|
||||
} );
|
||||
return all;
|
||||
}, [] );
|
||||
};
|
||||
|
||||
export const SettingSelect = ( { field, ...props } ) => {
|
||||
const { description, id, label, options = {} } = field;
|
||||
|
||||
const transformedOptions = useMemo( () => transformOptions( options ), [
|
||||
options,
|
||||
] );
|
||||
|
||||
return (
|
||||
<SelectControl
|
||||
title={ description }
|
||||
label={ label }
|
||||
key={ id }
|
||||
options={ transformedOptions }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,18 +0,0 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { TextControl } from '../../index';
|
||||
|
||||
export const SettingText = ( { field, type = 'text', ...props } ) => {
|
||||
const { id, label, description } = field;
|
||||
|
||||
return (
|
||||
<TextControl
|
||||
type={ type }
|
||||
title={ description }
|
||||
key={ id }
|
||||
label={ label }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -39,4 +39,4 @@
|
|||
@import 'view-more-list/style.scss';
|
||||
@import 'web-preview/style.scss';
|
||||
@import 'badge/style.scss';
|
||||
@import 'settings-form/style.scss';
|
||||
@import 'dynamic-form/style.scss';
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# WooRemotePaymentForm Slot & Fill
|
||||
|
||||
A Slotfill component that will replace the <DynamicForm /> component involved in displaying the form while adding a gateway via the payment task.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
<WooRemotePaymentForm id={ key }>
|
||||
{({defaultForm: DefaultForm}) => <p>Fill Content</p>}
|
||||
</WooRemotePaymentForm>
|
||||
|
||||
<WooRemotePaymentForm.Slot id={ key } />
|
||||
```
|
||||
|
||||
### WooRemotePaymentForm (fill)
|
||||
|
||||
This is the fill component. You must provide the `id` prop to identify the slot that this will occupy. If you provide a function as the child of your fill (as shown above), you will receive some helper props to assist in creating your fill:
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---------------- | --------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `defaultForm` | Component | The default instance of the <DynamicForm> component. Any provided props will override the given defaults |
|
||||
| `defaultSubmit` | Function | The default submit handler that is provided to the <Form> component |
|
||||
| `defaultFields` | Array | An array of the field configuration objects provided by the API |
|
||||
| `markConfigured` | Function | A helper function that will mark your gateway as configured |
|
||||
|
||||
### WooRemotePaymentForm.Slot (slot)
|
||||
|
||||
This is the slot component, and will not be used as frequently. It must also receive the required `id` prop that will be identical to the fill `id`.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ----------- | ------ | ---------------------------------------------------------------------------------- |
|
||||
| `fillProps` | Object | The props that will be provided to the fills, by default these are described above |
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Slot, Fill } from '@wordpress/components';
|
||||
|
||||
const WooRemotePaymentForm = ( { id, ...props } ) => (
|
||||
<Fill name={ 'woocommerce_remote_payment_form_' + id } { ...props } />
|
||||
);
|
||||
|
||||
WooRemotePaymentForm.Slot = ( { id, fillProps } ) => (
|
||||
<Slot
|
||||
name={ 'woocommerce_remote_payment_form_' + id }
|
||||
fillProps={ fillProps }
|
||||
/>
|
||||
);
|
||||
|
||||
export default WooRemotePaymentForm;
|
|
@ -1,32 +0,0 @@
|
|||
# WooRemotePaymentSettings Slot & Fill
|
||||
|
||||
A Slotfill component that will replace the <Settings /> component involved in displaying the form while adding a gateway via the payment task.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
<WooRemotePaymentSettings id={ key }>
|
||||
{({defaultSettings: DefaultSettings}) => <p>Fill Content</p>}
|
||||
</WooRemotePaymentSettings>
|
||||
|
||||
<WooRemotePaymentSettings.Slot id={ key } />
|
||||
```
|
||||
|
||||
### WooRemotePaymentSettings (fill)
|
||||
|
||||
This is the fill component. You must provide the `id` prop to identify the slot that this will occupy. If you provide a function as the child of your fill (as shown above), you will receive some helper props to assist in creating your fill:
|
||||
|
||||
| Name | Type | Description |
|
||||
| ----------------- | --------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| `defaultSettings` | Component | The default instance of the <SettingsForm> component. Any provided props will override the given defaults |
|
||||
| `defaultSubmit` | Function | The default submit handler that is provided to the <Form> component |
|
||||
| `defaultFields` | Array | An array of the field configuration objects provided by the API |
|
||||
| `markConfigured` | Function | A helper function that will mark your gateway as configured |
|
||||
|
||||
### WooRemotePaymentSettings.Slot (slot)
|
||||
|
||||
This is the slot component, and will not be used as frequently. It must also receive the required `id` prop that will be identical to the fill `id`.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ----------- | ------ | ---------------------------------------------------------------------------------- |
|
||||
| `fillProps` | Object | The props that will be provided to the fills, by default these are described above |
|
|
@ -1,17 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Slot, Fill } from '@wordpress/components';
|
||||
|
||||
const WooRemotePaymentSettings = ( { id, ...props } ) => (
|
||||
<Fill name={ 'woocommerce_remote_payment_settings_' + id } { ...props } />
|
||||
);
|
||||
|
||||
WooRemotePaymentSettings.Slot = ( { id, fillProps } ) => (
|
||||
<Slot
|
||||
name={ 'woocommerce_remote_payment_settings_' + id }
|
||||
fillProps={ fillProps }
|
||||
/>
|
||||
);
|
||||
|
||||
export default WooRemotePaymentSettings;
|
|
@ -76,6 +76,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
== Unreleased ==
|
||||
|
||||
- Fix: Autocompleter for custom Search in CompareFilter #6911
|
||||
- Dev: Converting <SettingsForm /> component to TypeScript. #6981
|
||||
- Enhancement: Adding Slotfills for remote payments and SettingsForm component. #6932
|
||||
- Fix: Make `Search` accept synchronous `autocompleter.options`. #6884
|
||||
- Add: Consume remote payment methods on frontend #6867
|
||||
|
|
Loading…
Reference in New Issue