Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(2.0) Proposal: API changes #264

Open
1 task
kettanaito opened this issue Aug 3, 2018 · 12 comments
Open
1 task

(2.0) Proposal: API changes #264

kettanaito opened this issue Aug 3, 2018 · 12 comments
Labels
breaking-change Change leading to major release. enhancement Enhances existing functionality.
Milestone

Comments

@kettanaito
Copy link
Owner

kettanaito commented Aug 3, 2018

This is the summary ticket of the API changes to be introduced in the next major version 2.0.

Roadmap

  • Write migration guidelines
@kettanaito kettanaito added enhancement Enhances existing functionality. breaking-change Change leading to major release. labels Aug 3, 2018
@kettanaito kettanaito added this to the 2.0 milestone Aug 3, 2018
Repository owner locked and limited conversation to collaborators Aug 3, 2018
@kettanaito
Copy link
Owner Author

kettanaito commented Aug 3, 2018

Rename

Current: <Condition />
Proposed: <Only />

Motivation

To make the usage more intuitive and have better readability of the component.

Usage

import { Only } from 'react-advanced-form'

<Only when={({ fields }) => fields.firstName.valid}>
  {/* Conditional content */}
</Only>

Advantages

  • Enhanced semantic readability
  • Shorter, arguably more intuitive

Disadvantages

  • Perhaps too contextless. Namespace may overlap with another things named Only.

@kettanaito
Copy link
Owner Author

kettanaito commented Aug 3, 2018

Rename

export default createField({
-  enforceProps: () => ({
+  withProps: () => ({
    propName: 'foo'
  }), 
})

Motivation

To be shorted and more intuitive.

Functionality of the property remains as-is.

@kettanaito
Copy link
Owner Author

kettanaito commented Aug 3, 2018

Rename

export default createField({
-  mapPropsToField: () => ({
+  getInitialState: () => ({
    checked: true,
  })
})

getInitialState better represents what this function returns—initial state of a field. This aligns great with the upcoming namespace change of fieldProps to fieldState.

@kettanaito
Copy link
Owner Author

Deprecate

Deprecate calling Form internal methods (i.e. updateFields) directly. The functions form exposes explicitly to the interface remain as-is.

@kettanaito kettanaito self-assigned this Aug 6, 2018
@kettanaito
Copy link
Owner Author

kettanaito commented Aug 6, 2018

Deprecate

I propose to remove fields reference in the arguments object whenever there is a Reactive prop subscription possible (using dedicated function).

Motivation

Referencing fields is confusing and pointless, since by referencing a field your validator becomes reactive (should react to the referenced field's updates). There is an explicit function to reference fields in validators—get.

This is already partially implemented, and needs to be reviewed prior to taking.

@kettanaito
Copy link
Owner Author

kettanaito commented Aug 6, 2018

Rename

I propose to rename the get function from field validator functions.
To: observeField

observeField
subscribe
subscribeToField
observeFieldProp
getFieldProp

Motivation

I want for this getter function to be more evident of what it does. The name should reflect that it references a field's props and subscribes to its changes.

@kettanaito
Copy link
Owner Author

kettanaito commented Aug 21, 2018

Deprecate / Refine

  • Deprecate fieldProps everywhere in the exposed API
  • Adopt fieldState instead of it
- anyCallback = ({ fieldProps }) => {}
+ anyCallback = ({ fieldState }) => {}

Motivation

I feel at the moment these two terms are somehow interchangeable throughout the API. That is definitely not okay, as they need to be:

a) whether merged, representing a field's record in the form's state
b) clearly distinguished and explained what is the difference

@kettanaito
Copy link
Owner Author

kettanaito commented Aug 28, 2018

Feature

Introduce a flag to represent the entire form's validity state (valid/invalid).

Motivation

This has been often requested, and is currently missing. It is worth a try of thinking this feature through.

Specification

We can take a similar approach to Formik, introducing a form's prop which assumes the initial validity of the respective form. That is for the interface purpose alone, as that flag cannot technically control the actual validity.

This may be the case, it just needs a clean API.

Materials

@kettanaito kettanaito removed their assignment Aug 31, 2018
@kettanaito
Copy link
Owner Author

Change

Simplify Field.props.handleFieldChange method to accept a single argument—nextValue.

Motivation

Right now the handler for manual field change update exposed from RAF for controlled fields has the same interface as the respective internal handler. While this is consistent from the API point of view, it makes to sense for the end-developer to provide such arguments as for example prevValue. This would result into ambiguous behavior, and thus shouldn't even be possible.

Specification

type HandleFieldChange = (nextValue: any) => void

Caveats

  • What about the event reference?

@kettanaito
Copy link
Owner Author

kettanaito commented Sep 27, 2018

Deprecate

Need to consider the deprecation of submit callbacks:

  • onSubmitStart
  • onSubmitted
  • onSubmitFailed
  • onSubmitEnd

Motivation

Submit callbacks are shorthands that can be handled using plain Promise chaining. It may be over-engineering at some point, thus it is worthy to consider removing them.

@kettanaito
Copy link
Owner Author

kettanaito commented Oct 12, 2018

(?) Refine

Support a function as a value for createField.initialValue option.

Motivation

Having initialValue option as a function based on props and fieldRecord will allow to have initial value composed in more complex scenarios. Consider:

export default createField({
  initialValue: ({ props }) => {
    const [day, month, year] = props.date.split('-')
    return { day, month, year }
  }
})(BirthDate)

Having initialValue accepting only a function may also be a viable option.

Questionable

Using createField.options.mapValue is much more reliable, than initialValue alone. Also, they serve quite different purposes.

@kettanaito kettanaito changed the title API changes (2.0) Proposal: API changes Oct 23, 2018
@kettanaito
Copy link
Owner Author

kettanaito commented Feb 18, 2019

(?) createField.mapState

Add the mapState method to the createField options.

Motivation

mapState method would map over field state upon each field update and affect the next field state. This is helpful when you want to affect your field state by external operations (i.e. async fetching of a validation schema).

Example

const ConnectedInput = connect((state) => ({
  schema: state.schema,
}))(Input)

export default createField({
  mapState: ({ props, fieldState }) => ({
    required: props.schema[props.name].isRequired,
  }),
})(ConnectedInput)

In this example the fieldState.required value is updated depending on the Object from the Redux store.

Specification

  • mapState is called during the applyStatePatch handler function
  • mapState is called after the componentDidUpdate of the wrapped Field component (to update the field state after props change)
  • mapState must return the overridden portion of the next field state

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
breaking-change Change leading to major release. enhancement Enhances existing functionality.
Projects
None yet
Development

No branches or pull requests

1 participant