mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-26 06:47:17 +10:00
Merge pull request #1173 from sharetribe/update-final-form
Update Final Form et al.
This commit is contained in:
commit
dbfb5141a4
33 changed files with 144 additions and 100 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -14,6 +14,19 @@ way to update this template, but currently, we follow a pattern:
|
|||
|
||||
## Upcoming version 2019-XX-XX
|
||||
|
||||
- [change] Update final-form, final-form-arrays, react-final-form and react-final-form-arrays. This
|
||||
forced to make some code changes:
|
||||
|
||||
- Old recommendation of by-passing default field formatting or parsin isn't accepted anymore
|
||||
- `format={null}` => use identity function instead: `format={v => v}`
|
||||
- `parse={null}` => use identity function instead: `parse={v => v}`
|
||||
- Final Form passes input props (name, value, onChange, onBlur, etc. ) grouped inside input key
|
||||
- those props now include `type` attribute too.
|
||||
- We had old form naming pattern with prop 'form', which now conflicted with updated Final Form
|
||||
(The 'form' prop was used when Redux-Form was the form library)
|
||||
|
||||
[#1173](https://github.com/sharetribe/flex-template-web/pull/1173)
|
||||
|
||||
- [change] Update `react-dates` from v18.5.0 ti v20.3.0
|
||||
[#1171](https://github.com/sharetribe/flex-template-web/pull/1171)
|
||||
- [change] Update Prettier to v1.18.2
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
"express": "^4.16.4",
|
||||
"express-enforces-ssl": "^1.1.0",
|
||||
"express-sitemap": "^1.8.0",
|
||||
"final-form": "^4.11.0",
|
||||
"final-form-arrays": "^1.1.0",
|
||||
"final-form": "^4.18.5",
|
||||
"final-form-arrays": "^3.0.0",
|
||||
"helmet": "^3.18.0",
|
||||
"lodash": "^4.17.14",
|
||||
"mapbox-gl-multitouch": "^1.0.3",
|
||||
|
|
@ -37,8 +37,8 @@
|
|||
"react": "^16.8.6",
|
||||
"react-dates": "^20.3.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-final-form": "^4.0.2",
|
||||
"react-final-form-arrays": "^2.0.1",
|
||||
"react-final-form": "^6.3.0",
|
||||
"react-final-form-arrays": "^3.1.1",
|
||||
"react-google-maps": "^9.4.5",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-intl": "^2.9.0",
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ const BookingPanel = props => {
|
|||
{showBookingDatesForm ? (
|
||||
<BookingDatesForm
|
||||
className={css.bookingForm}
|
||||
formId="BookingPanel"
|
||||
submitButtonWrapperClassName={css.bookingDatesSubmitButtonWrapper}
|
||||
unitType={unitType}
|
||||
onSubmit={onSubmit}
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ EditListingWizard.defaultProps = {
|
|||
className: null,
|
||||
rootClassName: null,
|
||||
listing: null,
|
||||
updateInProgress: false,
|
||||
};
|
||||
|
||||
EditListingWizard.propTypes = {
|
||||
|
|
@ -340,6 +341,7 @@ EditListingWizard.propTypes = {
|
|||
onPayoutDetailsFormChange: func.isRequired,
|
||||
onPayoutDetailsSubmit: func.isRequired,
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
updateInProgress: bool,
|
||||
|
||||
// from withViewport
|
||||
viewport: shape({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { Form as FinalForm, FormSpy } from 'react-final-form';
|
|||
import * as validators from '../../util/validators';
|
||||
import FieldBirthdayInput from './FieldBirthdayInput';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
|
|
@ -25,7 +27,7 @@ const FormComponent = props => (
|
|||
id={`birthday`}
|
||||
name="birthday"
|
||||
label="Date of birth"
|
||||
format={null}
|
||||
format={identity}
|
||||
valueFromForm={values.birthDate}
|
||||
validate={validators.composeValidators(required, minAgeRequired)}
|
||||
/>
|
||||
|
|
@ -41,7 +43,7 @@ export const Empty = {
|
|||
onChange: formState => {
|
||||
const birthday = formState.values.birthday;
|
||||
if (birthday) {
|
||||
console.log('birthday changed to:', birthday.toUTCString());
|
||||
console.log('birthday changed to:', birthday);
|
||||
}
|
||||
},
|
||||
onSubmit: values => {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const formName = 'Styleguide.FieldBoolean.Form';
|
|||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
form={formName}
|
||||
formId={formName}
|
||||
render={fieldRenderProps => {
|
||||
const { form, handleSubmit, onChange, invalid, pristine, submitting } = props;
|
||||
const required = validators.requiredBoolean('This field is required');
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const formName = 'Styleguide.FieldCheckbox.Form';
|
|||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
form={formName}
|
||||
formId={formName}
|
||||
render={fieldRenderProps => {
|
||||
const { form, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { required, bookingDateRequired, composeValidators } from '../../util/val
|
|||
import { createTimeSlots } from '../../util/test-data';
|
||||
import FieldDateInput from './FieldDateInput';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const createAvailableTimeSlots = (dayCount, availableDayCount) => {
|
||||
const slots = createTimeSlots(new Date(), dayCount);
|
||||
const availableSlotIndices = Array.from({ length: availableDayCount }, () =>
|
||||
|
|
@ -64,7 +66,7 @@ export const Empty = {
|
|||
id: `EmptyDateInputForm.bookingDate`,
|
||||
label: 'Date',
|
||||
placeholderText: moment().format('ddd, MMMM D'),
|
||||
format: null,
|
||||
format: identity,
|
||||
validate: composeValidators(required('Required'), bookingDateRequired('Date is not valid')),
|
||||
onBlur: () => console.log('onBlur called from DateInput props.'),
|
||||
onFocus: () => console.log('onFocus called from DateInput props.'),
|
||||
|
|
@ -91,7 +93,7 @@ export const WithAvailableTimeSlots = {
|
|||
id: `AvailableTimeSlotsDateInputForm.bookingDate`,
|
||||
label: 'Date',
|
||||
placeholderText: moment().format('ddd, MMMM D'),
|
||||
format: null,
|
||||
format: identity,
|
||||
timeSlots: createAvailableTimeSlots(90, 60),
|
||||
validate: composeValidators(required('Required'), bookingDateRequired('Date is not valid')),
|
||||
onBlur: () => console.log('onBlur called from DateInput props.'),
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class FieldDateInputComponent extends Component {
|
|||
[css.pickerError]: hasError,
|
||||
});
|
||||
|
||||
const { onBlur, onFocus, ...restOfInput } = input;
|
||||
const { onBlur, onFocus, type, ...restOfInput } = input;
|
||||
const inputProps = {
|
||||
onBlur: input.onBlur,
|
||||
onFocus: input.onFocus,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ import DateRangeController from './DateRangeController';
|
|||
|
||||
const component = props => {
|
||||
const { input, controllerRef, ...rest } = props;
|
||||
return <DateRangeController ref={controllerRef} {...input} {...rest} />;
|
||||
const { type, ...restOfInput } = input;
|
||||
return <DateRangeController ref={controllerRef} {...restOfInput} {...rest} />;
|
||||
};
|
||||
|
||||
const FieldDateRangeController = props => {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import { LINE_ITEM_NIGHT, LINE_ITEM_DAY } from '../../util/types';
|
|||
import { createTimeSlots } from '../../util/test-data';
|
||||
import FieldDateRangeInput from './FieldDateRangeInput';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const createAvailableTimeSlots = (dayCount, availableDayCount) => {
|
||||
const slots = createTimeSlots(new Date(), dayCount);
|
||||
|
||||
|
|
@ -70,7 +72,7 @@ export const Empty = {
|
|||
endDatePlaceholderText: moment()
|
||||
.add(1, 'days')
|
||||
.format('ddd, MMMM D'),
|
||||
format: null,
|
||||
format: identity,
|
||||
validate: composeValidators(
|
||||
required('Required'),
|
||||
bookingDatesRequired('Start date is not valid', 'End date is not valid')
|
||||
|
|
@ -101,12 +103,12 @@ export const WithAvailableTimeSlotsNighlyBooking = {
|
|||
startDateId: 'WithAvailableTimeSlotsDateRangeNightly.bookingStartDate',
|
||||
startDateLabel: 'Start date',
|
||||
startDatePlaceholderText: moment().format('ddd, MMMM D'),
|
||||
endDateId: 'WithAvailableTimeSlotsDateRangeInputForm.bookingEndDate',
|
||||
endDateId: 'WithAvailableTimeSlotsDateRangeNightly.bookingEndDate',
|
||||
endDateLabel: 'End date',
|
||||
endDatePlaceholderText: moment()
|
||||
.add(1, 'days')
|
||||
.format('ddd, MMMM D'),
|
||||
format: null,
|
||||
format: identity,
|
||||
timeSlots: createAvailableTimeSlots(90, 60),
|
||||
validate: composeValidators(
|
||||
required('Required'),
|
||||
|
|
@ -137,12 +139,12 @@ export const WithAvailableTimeSlotsDailyBooking = {
|
|||
startDateId: 'WithAvailableTimeSlotsDateRangeDaily.bookingStartDate',
|
||||
startDateLabel: 'Start date',
|
||||
startDatePlaceholderText: moment().format('ddd, MMMM D'),
|
||||
endDateId: 'WithAvailableTimeSlotsDateRangeInputForm.bookingEndDate',
|
||||
endDateId: 'WithAvailableTimeSlotsDateRangeDaily.bookingEndDate',
|
||||
endDateLabel: 'End date',
|
||||
endDatePlaceholderText: moment()
|
||||
.add(1, 'days')
|
||||
.format('ddd, MMMM D'),
|
||||
format: null,
|
||||
format: identity,
|
||||
timeSlots: createAvailableTimeSlots(90, 60),
|
||||
validate: composeValidators(
|
||||
required('Required'),
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class FieldDateRangeInputComponent extends Component {
|
|||
) : null;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { onBlur, onFocus, ...restOfInput } = input;
|
||||
const { onBlur, onFocus, type, ...restOfInput } = input;
|
||||
const inputProps = {
|
||||
unitType,
|
||||
onBlur: this.handleBlur,
|
||||
|
|
|
|||
|
|
@ -4,12 +4,9 @@ import * as validators from '../../util/validators';
|
|||
import { Button } from '../../components';
|
||||
import FieldPhoneNumberInput from './FieldPhoneNumberInput';
|
||||
|
||||
const formName = 'Styleguide.FieldPhoneNumberInput.Form';
|
||||
|
||||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
form={formName}
|
||||
render={fieldRenderProps => {
|
||||
const { formId, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps;
|
||||
const required = validators.required('This field is required');
|
||||
|
|
@ -41,7 +38,7 @@ const FormComponent = props => (
|
|||
export const PhoneNumber = {
|
||||
component: FormComponent,
|
||||
props: {
|
||||
formId: 'PhoneNumberExample',
|
||||
formId: 'Styleguide.FieldPhoneNumberInput.Form',
|
||||
onChange: formState => {
|
||||
if (formState.dirty) {
|
||||
console.log('form values changed to:', formState.values);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@ import React from 'react';
|
|||
import { Form as FinalForm, FormSpy } from 'react-final-form';
|
||||
import { Button } from '..';
|
||||
import FieldRadioButton from './FieldRadioButton';
|
||||
const formName = 'Styleguide.FieldRadioButton.Form';
|
||||
|
||||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
form={formName}
|
||||
render={fieldRenderProps => {
|
||||
const {
|
||||
handleSubmit,
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ const formName = 'Styleguide.FieldReviewRating.Form';
|
|||
const FormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
form={formName}
|
||||
formId={formName}
|
||||
render={fieldRenderProps => {
|
||||
const { form, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps;
|
||||
const { formId, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps;
|
||||
const required = validators.required('This field is required');
|
||||
const submitDisabled = invalid || pristine || submitting;
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ const FormComponent = props => (
|
|||
>
|
||||
<FormSpy onChange={onChange} />
|
||||
<FieldReviewRating
|
||||
id={`${form}.rate1`}
|
||||
id={`${formId}.rate1`}
|
||||
name="rating"
|
||||
label="Rate your experience"
|
||||
validate={required}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ class FieldTextInputComponent extends Component {
|
|||
customErrorText,
|
||||
id,
|
||||
label,
|
||||
type,
|
||||
input,
|
||||
meta,
|
||||
onUnmount,
|
||||
|
|
@ -33,7 +32,7 @@ class FieldTextInputComponent extends Component {
|
|||
}
|
||||
|
||||
const { valid, invalid, touched, error } = meta;
|
||||
const isTextarea = type === 'textarea';
|
||||
const isTextarea = input.type === 'textarea';
|
||||
|
||||
const errorText = customErrorText || error;
|
||||
|
||||
|
|
@ -43,6 +42,8 @@ class FieldTextInputComponent extends Component {
|
|||
|
||||
const fieldMeta = { touched: hasError, error: errorText };
|
||||
|
||||
// Textarea doesn't need type.
|
||||
const { type, ...inputWithoutType } = input;
|
||||
// Uncontrolled input uses defaultValue instead of value.
|
||||
const { value: defaultValue, ...inputWithoutValue } = input;
|
||||
// Use inputRef if it is passed as prop.
|
||||
|
|
@ -57,7 +58,15 @@ class FieldTextInputComponent extends Component {
|
|||
});
|
||||
const maxLength = CONTENT_MAX_LENGTH;
|
||||
const inputProps = isTextarea
|
||||
? { className: inputClasses, id, rows: 1, maxLength, ...refMaybe, ...input, ...rest }
|
||||
? {
|
||||
className: inputClasses,
|
||||
id,
|
||||
rows: 1,
|
||||
maxLength,
|
||||
...refMaybe,
|
||||
...inputWithoutType,
|
||||
...rest,
|
||||
}
|
||||
: isUncontrolled
|
||||
? {
|
||||
className: inputClasses,
|
||||
|
|
@ -109,9 +118,6 @@ FieldTextInputComponent.propTypes = {
|
|||
id: string,
|
||||
label: string,
|
||||
|
||||
// Either 'textarea' or something that is passed to the input element
|
||||
type: string.isRequired,
|
||||
|
||||
// Uncontrolled input uses defaultValue prop, but doesn't pass value from form to the field.
|
||||
// https://reactjs.org/docs/uncontrolled-components.html#default-values
|
||||
isUncontrolled: bool,
|
||||
|
|
@ -121,6 +127,8 @@ FieldTextInputComponent.propTypes = {
|
|||
// Generated by final-form's Field component
|
||||
input: shape({
|
||||
onChange: func.isRequired,
|
||||
// Either 'textarea' or something that is passed to the input element
|
||||
type: string.isRequired,
|
||||
}).isRequired,
|
||||
meta: object.isRequired,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { propTypes } from '../../util/types';
|
|||
import { Button } from '../../components';
|
||||
import LocationAutocompleteInput from './LocationAutocompleteInput';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const Form = props => {
|
||||
return (
|
||||
<FinalForm
|
||||
|
|
@ -12,7 +14,7 @@ const Form = props => {
|
|||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<label htmlFor="location">Select location:</label>
|
||||
<Field name="location" format={null} component={LocationAutocompleteInput} />
|
||||
<Field name="location" format={identity} component={LocationAutocompleteInput} />
|
||||
<Button type="submit" style={{ marginTop: '24px' }} disabled={pristine}>
|
||||
Submit
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -244,7 +244,6 @@ class TopbarComponent extends Component {
|
|||
>
|
||||
<div className={css.searchContainer}>
|
||||
<TopbarSearchForm
|
||||
form="TopbarSearchForm"
|
||||
onSubmit={this.handleSubmit}
|
||||
initialValues={initialSearchFormValues}
|
||||
isMobile
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ const TopbarDesktop = props => {
|
|||
<TopbarSearchForm
|
||||
className={css.searchLink}
|
||||
desktopInputRoot={css.topbarSearchWithLeftPadding}
|
||||
form="TopbarSearchFormDesktop"
|
||||
onSubmit={onSearchSubmit}
|
||||
initialValues={initialSearchFormValues}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ export class TransactionPanelComponent extends Component {
|
|||
/>
|
||||
{showSendMessageForm ? (
|
||||
<SendMessageForm
|
||||
form={this.sendMessageFormName}
|
||||
formId={this.sendMessageFormName}
|
||||
rootClassName={css.sendMessageForm}
|
||||
messagePlaceholder={sendMessagePlaceholder}
|
||||
inProgress={sendMessageInProgress}
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -1266,7 +1266,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -2023,7 +2023,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -2780,7 +2780,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -3547,7 +3547,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -4309,7 +4309,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -5064,7 +5064,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -5821,7 +5821,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -6578,7 +6578,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -7335,7 +7335,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -8092,7 +8092,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -8849,7 +8849,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -9606,7 +9606,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
@ -10361,7 +10361,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
|||
totalMessagePages={1}
|
||||
/>
|
||||
<SendMessageForm
|
||||
form="TransactionPanel.SendMessageForm"
|
||||
formId="TransactionPanel.SendMessageForm"
|
||||
inProgress={false}
|
||||
messagePlaceholder="TransactionPanel.sendMessagePlaceholder"
|
||||
onBlur={[Function]}
|
||||
|
|
|
|||
|
|
@ -208,8 +208,15 @@ export default function reducer(state = initialState, action = {}) {
|
|||
};
|
||||
case PUBLISH_LISTING_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
redirectToListing: true,
|
||||
publishingListing: null,
|
||||
createListingDraftError: null,
|
||||
updateListingError: null,
|
||||
showListingsError: null,
|
||||
uploadImageError: null,
|
||||
createListingDraftInProgress: false,
|
||||
updateInProgress: false,
|
||||
};
|
||||
case PUBLISH_LISTING_ERROR: {
|
||||
// eslint-disable-next-line no-console
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import EstimatedBreakdownMaybe from './EstimatedBreakdownMaybe';
|
|||
|
||||
import css from './BookingDatesForm.css';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
export class BookingDatesFormComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -77,7 +79,7 @@ export class BookingDatesFormComponent extends Component {
|
|||
const {
|
||||
endDatePlaceholder,
|
||||
startDatePlaceholder,
|
||||
form,
|
||||
formId,
|
||||
handleSubmit,
|
||||
intl,
|
||||
isOwnListing,
|
||||
|
|
@ -159,15 +161,15 @@ export class BookingDatesFormComponent extends Component {
|
|||
className={css.bookingDates}
|
||||
name="bookingDates"
|
||||
unitType={unitType}
|
||||
startDateId={`${form}.bookingStartDate`}
|
||||
startDateId={`${formId}.bookingStartDate`}
|
||||
startDateLabel={bookingStartLabel}
|
||||
startDatePlaceholderText={startDatePlaceholderText}
|
||||
endDateId={`${form}.bookingEndDate`}
|
||||
endDateId={`${formId}.bookingEndDate`}
|
||||
endDateLabel={bookingEndLabel}
|
||||
endDatePlaceholderText={endDatePlaceholderText}
|
||||
focusedInput={this.state.focusedInput}
|
||||
onFocusedInputChange={this.onFocusedInputChange}
|
||||
format={null}
|
||||
format={identity}
|
||||
timeSlots={timeSlots}
|
||||
useMobileMargins
|
||||
validate={composeValidators(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import { Form, LocationAutocompleteInputField, Button, FieldTextInput } from '..
|
|||
|
||||
import css from './EditListingLocationForm.css';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
export const EditListingLocationFormComponent = props => (
|
||||
<FinalForm
|
||||
{...props}
|
||||
|
|
@ -88,7 +90,7 @@ export const EditListingLocationFormComponent = props => (
|
|||
label={titleRequiredMessage}
|
||||
placeholder={addressPlaceholderMessage}
|
||||
useDefaultPredictions={false}
|
||||
format={null}
|
||||
format={identity}
|
||||
valueFromForm={values.location}
|
||||
validate={composeValidators(
|
||||
autocompleteSearchRequired(addressRequiredMessage),
|
||||
|
|
|
|||
|
|
@ -159,8 +159,8 @@ export class EditListingPhotosFormComponent extends Component {
|
|||
disabled={imageUploadRequested}
|
||||
>
|
||||
{fieldprops => {
|
||||
const { accept, input, label, type, disabled } = fieldprops;
|
||||
const { name } = input;
|
||||
const { accept, input, label, disabled } = fieldprops;
|
||||
const { name, type } = input;
|
||||
const onChange = e => {
|
||||
const file = e.target.files[0];
|
||||
form.change(`addImage`, file);
|
||||
|
|
@ -185,10 +185,10 @@ export class EditListingPhotosFormComponent extends Component {
|
|||
|
||||
<Field
|
||||
component={props => {
|
||||
const { input, type, meta } = props;
|
||||
const { input, meta } = props;
|
||||
return (
|
||||
<div className={css.imageRequiredWrapper}>
|
||||
<input {...input} type={type} />
|
||||
<input {...input} />
|
||||
<ValidationError fieldMeta={meta} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
|||
import FilterForm from './FilterForm';
|
||||
import { FieldTextInput } from '../../components';
|
||||
|
||||
const field = (
|
||||
const field = formId => (
|
||||
<FieldTextInput
|
||||
id="field"
|
||||
id={`${formId}.field`}
|
||||
name="field"
|
||||
type="textarea"
|
||||
label="Field label"
|
||||
|
|
@ -29,7 +29,7 @@ export const FilterFormExample = {
|
|||
console.log('onClear called');
|
||||
},
|
||||
label: 'Example label',
|
||||
children: field,
|
||||
children: field('FilterFormExample'),
|
||||
},
|
||||
group: 'forms',
|
||||
};
|
||||
|
|
@ -45,7 +45,7 @@ export const FilterFormExampleLiveEdit = {
|
|||
console.log(values);
|
||||
},
|
||||
label: 'Example label',
|
||||
children: field,
|
||||
children: field('FilterFormExampleLiveEdit'),
|
||||
},
|
||||
group: 'forms',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { Form, LocationAutocompleteInput } from '../../components';
|
|||
|
||||
import css from './LocationSearchForm.css';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const LocationSearchFormComponent = props => {
|
||||
const handleChange = location => {
|
||||
if (location.selectedPlace) {
|
||||
|
|
@ -32,7 +34,7 @@ const LocationSearchFormComponent = props => {
|
|||
<Form className={classes} onSubmit={preventFormSubmit}>
|
||||
<Field
|
||||
name="location"
|
||||
format={null}
|
||||
format={identity}
|
||||
render={({ input, meta }) => {
|
||||
const { onChange, ...restInput } = input;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import css from './PayoutDetailsForm.css';
|
|||
|
||||
const MIN_STRIPE_ACCOUNT_AGE = 18;
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
const PayoutDetailsPersonalDetails = props => {
|
||||
const {
|
||||
intl,
|
||||
|
|
@ -246,7 +248,7 @@ const PayoutDetailsPersonalDetails = props => {
|
|||
label={birthdayLabel}
|
||||
labelForMonth={birthdayLabelMonth}
|
||||
labelForYear={birthdayLabelYear}
|
||||
format={null}
|
||||
format={identity}
|
||||
valueFromForm={values.birthDate}
|
||||
validate={validators.composeValidators(birthdayRequired, birthdayMinAge)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -198,16 +198,8 @@ class ProfileSettingsFormComponent extends Component {
|
|||
disabled={uploadInProgress}
|
||||
>
|
||||
{fieldProps => {
|
||||
const {
|
||||
accept,
|
||||
id,
|
||||
input,
|
||||
label,
|
||||
type,
|
||||
disabled,
|
||||
uploadImageError,
|
||||
} = fieldProps;
|
||||
const { name } = input;
|
||||
const { accept, id, input, label, disabled, uploadImageError } = fieldProps;
|
||||
const { name, type } = input;
|
||||
const onChange = e => {
|
||||
const file = e.target.files[0];
|
||||
form.change(`profileImage`, file);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import SendMessageForm from './SendMessageForm';
|
|||
export const Empty = {
|
||||
component: SendMessageForm,
|
||||
props: {
|
||||
formId: 'SendMessageForm.Empty.Form',
|
||||
messagePlaceholder: 'Send message to Juho…',
|
||||
onChange: values => {
|
||||
console.log('values changed to:', values);
|
||||
|
|
@ -23,6 +24,7 @@ export const Empty = {
|
|||
export const InProgress = {
|
||||
component: SendMessageForm,
|
||||
props: {
|
||||
formId: 'SendMessageForm.InProgress.Form',
|
||||
messagePlaceholder: 'Send message to Juho…',
|
||||
inProgress: true,
|
||||
onSubmit: values => {
|
||||
|
|
@ -35,6 +37,7 @@ export const InProgress = {
|
|||
export const Error = {
|
||||
component: SendMessageForm,
|
||||
props: {
|
||||
formId: 'SendMessageForm.Error.Form',
|
||||
messagePlaceholder: 'Send message to Juho…',
|
||||
sendMessageError: { type: 'error', name: 'ExampleError' },
|
||||
onSubmit: values => {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class SendMessageFormComponent extends Component {
|
|||
sendMessageError,
|
||||
invalid,
|
||||
form,
|
||||
formId,
|
||||
} = formRenderProps;
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
|
@ -76,7 +77,7 @@ class SendMessageFormComponent extends Component {
|
|||
<FieldTextInput
|
||||
inputRootClass={css.textarea}
|
||||
type="textarea"
|
||||
id="message"
|
||||
id={formId ? `${formId}.message` : 'message'}
|
||||
name="message"
|
||||
placeholder={messagePlaceholder}
|
||||
onFocus={this.handleFocus}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { Form, LocationAutocompleteInput } from '../../components';
|
|||
|
||||
import css from './TopbarSearchForm.css';
|
||||
|
||||
const identity = v => v;
|
||||
|
||||
class TopbarSearchFormComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -45,7 +47,7 @@ class TopbarSearchFormComponent extends Component {
|
|||
<Form className={classes} onSubmit={preventFormSubmit}>
|
||||
<Field
|
||||
name="location"
|
||||
format={null}
|
||||
format={identity}
|
||||
render={({ input, meta }) => {
|
||||
const { onChange, ...restInput } = input;
|
||||
|
||||
|
|
|
|||
49
yarn.lock
49
yarn.lock
|
|
@ -756,14 +756,14 @@
|
|||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-transform-typescript" "^7.3.2"
|
||||
|
||||
"@babel/runtime@7.5.5", "@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5":
|
||||
"@babel/runtime@7.5.5", "@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
|
||||
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1":
|
||||
"@babel/runtime@^7.1.2":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d"
|
||||
integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==
|
||||
|
|
@ -4497,15 +4497,15 @@ fill-range@^4.0.0:
|
|||
repeat-string "^1.6.1"
|
||||
to-regex-range "^2.1.0"
|
||||
|
||||
final-form-arrays@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/final-form-arrays/-/final-form-arrays-1.1.2.tgz#7e33eb2485419e6956310cec76a717167c88d85c"
|
||||
integrity sha512-Pmq3MXI9zbSsY7WZ2eodWQAHpsw2/i5YkagzcCgqzRcSSHB8BD3yWi7YPSGTPXuG0ixcQe9VAYpQ+UEWcqf4zg==
|
||||
final-form-arrays@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/final-form-arrays/-/final-form-arrays-3.0.1.tgz#862e5e946d391039ebcdfadbe55fc3a63849e559"
|
||||
integrity sha512-GKXecufCNCjDcz1+3peL21LuuTlApoxCcnpOnmfeJfC3xAlFKGdytYMfifP7W1IEWTGC8twTv3zItESkej8qpg==
|
||||
|
||||
final-form@^4.11.0:
|
||||
version "4.12.0"
|
||||
resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.12.0.tgz#1844e2a3bc9789d51115c76a94d0ea6a19e219c0"
|
||||
integrity sha512-z1fSzDNmIBlDjRMaluM3WgDbcwCFpPm7mvopplgXGMRS49MXR+1n//lteLwPURdGQNOZhWm3GwiEJanEHCItww==
|
||||
final-form@^4.18.5:
|
||||
version "4.18.5"
|
||||
resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.18.5.tgz#e359cfaf2892ef135d92fcf22e06b475dda3a885"
|
||||
integrity sha512-DH/I2W7fWxU8J8ZsbYJ5jLvUbhbatCvLhIKlsU17MvY6W3QnetPEyuX5mcxXgIGFNFKxfvqsG3pDy/1/VwOiTw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.3.1"
|
||||
|
||||
|
|
@ -9144,20 +9144,20 @@ react-fast-compare@^2.0.2:
|
|||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||
|
||||
react-final-form-arrays@^2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-final-form-arrays/-/react-final-form-arrays-2.0.3.tgz#938bd0d62741ab59c6a680968f79eac029e37333"
|
||||
integrity sha512-iHGGAbOVsTlp/lhE6EUsqzhjPZSvcExLWE91Qx0remHOJvQ2wkxHe8HTA9KBlId8YJ1fkz6g417GTq/1IFnL9w==
|
||||
react-final-form-arrays@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-final-form-arrays/-/react-final-form-arrays-3.1.1.tgz#39d23e7ede966e418cad209e8fde46da1d603e99"
|
||||
integrity sha512-e6S1x9597cvI4QPniOPmllXXandDAqCCuBo4AvXstZYgcV8whsqzk8aCrmQEy6eEfy2tEhvn6f4VI1GY+JBRsg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.3.4"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
"@babel/runtime" "^7.4.5"
|
||||
|
||||
react-final-form@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-4.1.0.tgz#4e1b513de164771b2b824f3fb9c0548014255971"
|
||||
integrity sha512-O8p1EPQ/PFWNcX3bYGsLzuo/KnGeNfGfFi2UAX8jXLXrGcGdTfZMnyo/DFHdEKA9aKso61d/PHekQ9sst0cOmw==
|
||||
react-final-form@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.3.0.tgz#b85ae123a3796b3e0c8f56033c8a5037f4497e76"
|
||||
integrity sha512-jijhXR1fFGUBQwNOSqF4MK8XJO7Ynl1p8vcFsnQS0INSkGI52+4IagjUgtHj3w8EviIHPFK/Eflji6FELUl07w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.3.4"
|
||||
"@babel/runtime" "^7.4.5"
|
||||
ts-essentials "^2.0.8"
|
||||
|
||||
react-google-maps@^9.4.5:
|
||||
version "9.4.5"
|
||||
|
|
@ -9207,7 +9207,7 @@ react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
|
||||
integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
|
||||
|
||||
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4:
|
||||
react-lifecycles-compat@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
|
@ -10872,6 +10872,11 @@ tryer@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
||||
|
||||
ts-essentials@^2.0.8:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745"
|
||||
integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==
|
||||
|
||||
ts-pnp@1.1.2, ts-pnp@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue