build icon indicating copy to clipboard operation
build copied to clipboard

Inputs API draft

Open erquhart opened this issue 5 years ago • 7 comments

Overview

inputs is a property that can be defined in a plugin's manifest.yml file. An "input" is an expected value that can be provided to the plugin at runtime. Here's an example input definition:

inputs:
  - name: phone
    label: Twilio Phone Number
    required: true
    pattern: /^([0-9\(\)\/\+ \-]*)$/
    sensitive: true

Not all inputs are required. An input definition can be used to validate user input, as well as configure the UI that might be presented for the user to provide their input. For example, a "select" type input might result in an HTML <select> element for the user to select a value. Note that inputs might come from anywhere (Eg., another plugin, CLI, etc.), so a UI may not always be involved.

Why this is important

This API is meant to drive a dynamic UI in the Netlify dashboard, completely configured through a plugin's manifest.yml. It is similar in concept to the editor pane in Netlify CMS, except:

  • we're only configuring a form
  • nothing is previewed
  • only simple values are handled (no crazy markdown widgets)

Default input properties

These properties are available to all inputs, regardless of type.

key required default description
name yes name for internal reference purposes
label yes proper display name for UI
type "string" UI input type (see Available types below)
description Longer description
required false Set field as required
default Default value used if none supplied
repeat false Whether the field can be repeated - produces an array of values if true
repeat_min Minimum repeat count (if repeat is true)
repeat_max Maximum repeat count (if repeat is true)

Here's an example use case for the repeat property, where a plugin accepts a list of email addresses. The user could add as many email addresses as necessary since repeat is set to true.

inputs:
  - name: emails
    label: Email Addresses
    required: true
    repeat: true
    repeat_min: 1

Available types

A list of types that we should allow, and type-specific properties that should be accepted for each.

string

Accepts a string value.

key required default description
pattern Regular expression that this string should match.
sensitive false Whether to mask the value to prevent it from being displayed in logs, CLI, or API.

number

Accepts a numeric value.

key required default description
min Minimum acceptable value.
max Maximum acceptable value.

boolean

Accepts a boolean value. No type-specific properties.

text

Longer string value. No type-specific properties.

select

Accepts one or more values from a predefined list.

key required default description
options yes List of values that can be selected.
multiple false Allow multiple values to be selected

object

Accepts a map of inputs.

key required default description
inputs yes Map of input definitions

Here's an example input configuration that accepts an array of address objects.

inputs:
  - name: addresses
    label: Addresses
    type: object
    required: true
    repeat: true
    repeat_min: 1
    inputs:
      - name: street_address
        label: Street Address
        required: true
      - name: city
        label: City
        required: true
      - name: state
        label: State
        required: true

erquhart avatar Mar 25 '20 22:03 erquhart

This looks all good :+1: with the two following suggestions.

I think the multiple property and the repeat property could be merged into one. For example, if type: select and repeat: true, then this is a multiple select, otherwise it is a single select.

When it comes to the object type, I think users might be able to emulate it by instead namespacing the inputs name:

inputs:
  - name: address.street
    label: Street Address
    required: true
  - name: address.city
    label: City
    required: true
  - name: address.state
    label: State
    required: true

Unlike the type: object, that would not work with repeat, i.e. plugins would not be able to ask users for an array of objects. But I think array of objects are a rather advanced form of configuration, which we might want to implement later or when users are asking for it?

ehmicky avatar Mar 30 '20 12:03 ehmicky

I think the multiple property and the repeat property could be merged into one.

multiple is specific to the select field only, it allows it to be a multi-select field. repeat allows any field to be completely duplicated, and the output becomes an array of values.

When it comes to the object type, I think users might be able to emulate it by instead namespacing the inputs name

Yeah it's a good shorthand but doesn't work for repeating.

But I think array of objects are a rather advanced form of configuration, which we might want to implement later or when users are asking for it?

Agreed, not all of this API is likely to make it into v1, but we should be forward looking in the things that are implemented.

erquhart avatar Mar 30 '20 22:03 erquhart

What I meant about multiple and repeat: repeat would have the generic meaning you're describing above. But when used inside a select field, it would have the additional meaning of making it a multi-select field. Conceptually single-select field are scalar while multiple-select field are arrays. This could also allow re-using things like repeat_min and repeat_max to validate the number of choices in a multi-select field.

About the object type, we actually already have some plugins that seem to use it, like the Cypress plugin. If plugin authors are naturally using objects to namespace options, it seems like a good idea to support it, and the above approach works :+1:

ehmicky avatar Mar 31 '20 11:03 ehmicky

Thanks @erquhart !!

FE perspective about repeat vs multiple: We have some selects on the app that allow picking from the existing options and/or creating new options. I'm not sure if it's something that plugin creators will need, but if so, in the future we may need to add repeat or something similar to indicate that the new options can be created, apart from the select being multiple or not.

Another approach would be to have a format property (or similar) instead of the select type. It will add more flexibility, and also could allow design and/or plugin authors to decide how to show a collection of options in the UI: radio buttons, checkboxes, buttons, a select... but it will be more complex to implement.

  - name: email 
    type: string
    format: collection
      creatable: true # I stole the name from react-select :p
  - name: email 
    type: string
    format: collection
      creatable: false 
      options:
         - [email protected]
         - [email protected]

A final note: inputs of type select don't indicate the type of the options, will they be strings?

nasivuela avatar Apr 24 '20 16:04 nasivuela

multiple: true: select field can accept multiple values, outputs an array creatable: true: select field can accept custom values in addition to items from options

I think we're all on the same page with those two.

I'll try to do a better job of describing repeatable (formerly repeat, repeatable makes more sense and aligns with creatable):

repeatable: true: entire field can be duplicated

If the field is a select with multiple: true, and already outputs an array, the output will be an array of arrays.

@nasivuela we shouldn't need a format key - type defines the UI, so type: string is a standard text input and select is a dropdown.

erquhart avatar Apr 28 '20 01:04 erquhart

HTML will always output a string regardless of the input type. If the type is number or boolean, should FE parse the output accordingly? For the rest of primitives (options of select and properties of object), the output will be of string type.

If type defines the UI, wouldn't make more sense text instead of string and textarea instead of text?

nasivuela avatar Apr 28 '20 09:04 nasivuela

Just to confirm, FE is expecting to get this data from API not from the manifest.yml

nasivuela avatar Apr 28 '20 17:04 nasivuela

This issue has been automatically marked as stale because it has not had activity in 1 year. It will be closed in 14 days if no further activity occurs. Thanks!

github-actions[bot] avatar Oct 11 '22 14:10 github-actions[bot]

This issue was closed because it had no activity for over 1 year.

github-actions[bot] avatar Oct 25 '22 14:10 github-actions[bot]