[
    {
        "name": "Form.View",
        "comment": " This module provides helpers to render a [`Form`](Form#Form).\n\nIf you just want to quickly render a [`Form`](Form#Form) as HTML, take a look at\n[`asHtml`](#asHtml). If you need more control, use [`custom`](#custom).\n\n**Note:** If you are implementing your own custom fields using [`Form.Base`](Form-Base) then\nyou cannot use this module. You should use [`Form.Base.fill`](Form-Base#fill) to write your\nown renderer. Take a look at [the source code of this module][source] for inspiration.\n\n[source]: https://github.com/hecrj/composable-form/blob/1.0.0/src/Form/View.elm\n\n\n# Model\n\n@docs Model, State, idle\n\n\n# Configuration\n\n@docs ViewConfig, Validation\n\n\n# Built-in HTML renderer\n\n@docs asHtml\n\n\n# Custom renderer\n\n@docs custom, CustomConfig, FormConfig, TextFieldConfig, NumberFieldConfig, RangeFieldConfig\n@docs CheckboxFieldConfig, RadioFieldConfig, SelectFieldConfig\n\n",
        "unions": [
            {
                "name": "State",
                "comment": " Represents the state of the form.\n\nYou can change it at will from your `update` function. For example, you can set the state to\n`Loading` if submitting the form fires a remote action, or you can set it to `Error` when\nsuch action fails.\n\n    update : Msg -> Model -> ( Model, Cmd Msg )\n    update msg model =\n        case msg of\n            FormChanged newModel ->\n                ( { newModel | state = FormView.Idle }, Cmd.none )\n\n            SignUp email password ->\n                ( { model | state = FormView.Loading }\n                , User.signUp email password\n                    |> Task.attempt SignupTried\n                )\n\n            SignupTried (Ok user) ->\n                ( model, Route.navigate (Route.Profile user.slug) )\n\n            SignupTried (Err error) ->\n                ( { model | state = FormView.Error error }, Cmd.none )\n\n",
                "args": [],
                "cases": [
                    [
                        "Idle",
                        []
                    ],
                    [
                        "Loading",
                        []
                    ],
                    [
                        "Error",
                        [
                            "String"
                        ]
                    ]
                ]
            },
            {
                "name": "Validation",
                "comment": " The validation strategy.\n\n  - `ValidateOnSubmit` will show field errors only when the user tries to submit an invalid form.\n  - `ValidateOnBlur` will show field errors as fields are blurred.\n\n",
                "args": [],
                "cases": [
                    [
                        "ValidateOnSubmit",
                        []
                    ],
                    [
                        "ValidateOnBlur",
                        []
                    ]
                ]
            }
        ],
        "aliases": [
            {
                "name": "CheckboxFieldConfig",
                "comment": " Describes how a checkbox field should be rendered.\n\nThis is basically a [`TextFieldConfig`](#TextFieldConfig), but its `attributes` are\n[`CheckboxField.Attributes`](Form-Base-CheckboxField#Attributes).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : Bool -> msg, onBlur : Maybe msg, disabled : Bool, value : Bool, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "CustomConfig",
                "comment": " The configuration needed to create a custom renderer.\n\nIt needs functions to render each of [the supported `Form` fields](Form#fields), a function to\nrender a [`group`](Form#group) of fields, and a function to wrap the fields together in a `form`.\n\n",
                "args": [
                    "msg",
                    "element"
                ],
                "type": "{ form : FormConfig msg element -> element, textField : TextFieldConfig msg -> element, emailField : TextFieldConfig msg -> element, passwordField : TextFieldConfig msg -> element, textareaField : TextFieldConfig msg -> element, searchField : TextFieldConfig msg -> element, numberField : NumberFieldConfig msg -> element, rangeField : RangeFieldConfig msg -> element, checkboxField : CheckboxFieldConfig msg -> element, radioField : RadioFieldConfig msg -> element, selectField : SelectFieldConfig msg -> element, group : List element -> element }"
            },
            {
                "name": "FormConfig",
                "comment": " Describes how a form should be rendered.\n\n  - `onSubmit` contains the output of the form if there are no validation errors.\n  - `state` is the [`State`](#State) of the form.\n  - `action` is the main action of the form, you should probably render this in the submit button.\n  - `loading` is the loading message that should be shown when the form is loading.\n  - `fields` contains the already rendered fields.\n\n",
                "args": [
                    "msg",
                    "element"
                ],
                "type": "{ onSubmit : Maybe msg, state : State, action : String, loading : String, fields : List element }"
            },
            {
                "name": "Model",
                "comment": " This type gathers the values of the form, with some exposed state and internal view state that\ntracks which fields should show validation errors.\n",
                "args": [
                    "values"
                ],
                "type": "{ values : values, state : State, errorTracking : ErrorTracking }"
            },
            {
                "name": "NumberFieldConfig",
                "comment": " Describes how a number field should be rendered.\n\n  - `value` will be `Nothing` if the field is blank or `Just` a `Float`.\n  - `attributes` are [`NumberField.Attributes`](Form-Base-NumberField#Attributes).\n\nThe other record fields are described in [`TextFieldConfig`](#TextFieldConfig).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : Float -> msg, onBlur : Maybe msg, disabled : Bool, value : Maybe Float, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "RadioFieldConfig",
                "comment": " Describes how a radio field should be rendered.\n\nThis is basically a [`TextFieldConfig`](#TextFieldConfig), but its `attributes` are\n[`RadioField.Attributes`](Form-Base-RadioField#Attributes).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : String -> msg, onBlur : Maybe msg, disabled : Bool, value : String, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "RangeFieldConfig",
                "comment": " Describes how a range field should be rendered.\n\n  - `value` will be `Nothing` if the field is blank or `Just` a `Float`.\n  - `attributes` are [`RangeField.Attributes`](Form-Base-RangeField#Attributes).\n\nThe other record fields are described in [`TextFieldConfig`](#TextFieldConfig).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : Float -> msg, onBlur : Maybe msg, disabled : Bool, value : Maybe Float, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "SelectFieldConfig",
                "comment": " Describes how a select field should be rendered.\n\nThis is basically a [`TextFieldConfig`](#TextFieldConfig), but its `attributes` are\n[`SelectField.Attributes`](Form-Base-SelectField#Attributes).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : String -> msg, onBlur : Maybe msg, disabled : Bool, value : String, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "TextFieldConfig",
                "comment": " Describes how a text field should be rendered.\n\n  - `onChange` takes a new value for the field and returns the `msg` that should be produced.\n  - `onBlur` might contain a `msg` that should be produced when the field is blurred.\n  - `disabled` tells you whether the field should be disabled or not. It is `True` when the form is\n    loading.\n  - `value` contains the current value of the field.\n  - `error` might contain a field [`Error`](Form-Error#Error).\n  - `showError` tells you if you should show the `error` for this particular field. Its value\n    depends on the [validation strategy](#Validation).\n  - `attributes` are [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "args": [
                    "msg"
                ],
                "type": "{ onChange : String -> msg, onBlur : Maybe msg, disabled : Bool, value : String, error : Maybe Error, showError : Bool, attributes : Attributes }"
            },
            {
                "name": "ViewConfig",
                "comment": " This allows you to configure the renderer behavior.\n\n  - `onChange` specifies the message that should be produced when the `Model` changes.\n  - `action` is the text of the submit button when the form is not loading.\n  - `loading` is the text of the submit button when the form is loading.\n  - `validation` lets you choose the validation strategy.\n\n",
                "args": [
                    "values",
                    "msg"
                ],
                "type": "{ onChange : Model values -> msg, action : String, loading : String, validation : Validation }"
            }
        ],
        "values": [
            {
                "name": "asHtml",
                "comment": " Render a form as HTML!\n\nYou could use it like this:\n\n    FormView.asHtml\n        { onChange = FormChanged\n        , action = \"Log in\"\n        , loading = \"Logging in...\"\n        , validation = FormView.ValidateOnSubmit\n        }\n        loginForm\n        model\n\nAnd here is an example of the produced HTML:\n\n```html\n<form class=\"elm-form\">\n   <div class=\"elm-form-field\">\n       <label>E-Mail</label>\n       <input type=\"email\" value=\"some@value.com\" placeholder=\"Type your e-mail...\">\n   </div>\n   <div class=\"elm-form-field elm-form-field-error\">\n       <label>Password</label>\n       <input type=\"password\" value=\"\" placeholder=\"Type your password...\">\n       <div class=\"elm-form-error\">This field is required</div>\n   </div>\n   <button type=\"submit\">Log in</button>\n</form>\n```\n\nYou can use the different CSS classes to style your forms as you please.\n\nIf you need more control over the produced HTML, use [`custom`](#custom).\n\n",
                "type": "ViewConfig values msg -> Form values msg -> Model values -> Html msg"
            },
            {
                "name": "custom",
                "comment": " Create a custom renderer.\n\nYou need to provide a set of functions to render each field, and a function to\nput them all together in a form, see [`CustomConfig`](#CustomConfig).\n\nThis function can be used to create form renderers that are compatible with `style-elements`,\n`elm-mdl`, `elm-css`, etc. You could even use it to transform forms into a `String` or `Json.Value`!\n\nOnce you provide a [`CustomConfig`](#CustomConfig) this function returns a renderer that supports\na [`ViewConfig`](#ViewConfig). In fact, [`asHtml`](#asHtml) is implemented using this function!\n\n    asHtml : ViewConfig values msg -> Form values msg -> Model values -> Html msg\n    asHtml =\n        custom\n            { form = form\n            , textField = inputField \"text\"\n            , emailField = inputField \"email\"\n            , passwordField = inputField \"password\"\n            , searchField = inputField \"search\"\n            , textareaField = textareaField\n            , numberField = numberField\n            , rangeField = rangeField\n            , checkboxField = checkboxField\n            , radioField = radioField\n            , selectField = selectField\n            , group = group\n            }\n\n",
                "type": "CustomConfig msg element -> ViewConfig values msg -> Form values msg -> Model values -> element"
            },
            {
                "name": "idle",
                "comment": " Create a `Model` representing an idle form.\n\nYou just need to provide the initial `values` of the form.\n\n",
                "type": "values -> Model values"
            }
        ],
        "binops": []
    },
    {
        "name": "Form",
        "comment": " Build [composable forms](#Form) comprised of [fields](#fields).\n\n\n# Definition\n\n@docs Form\n\n\n# Fields\n\n@docs textField, emailField, passwordField, textareaField, numberField, rangeField, checkboxField\n@docs radioField, selectField\n\n\n# Composition\n\nAll the functions in [the previous section](#fields) produce a `Form` with a **single**\nfield. You might then be wondering: \"How do I create a `Form` with multiple fields?!\"\nWell, as the name of this package says: `Form` is composable! This section explains how you\ncan combine different forms into bigger and more complex ones.\n\n@docs succeed, append, optional, group, andThen, meta\n\n\n# Output\n\nThis section describes how to fill a `Form` with its `values` and obtain its\ndifferent fields and its `output`. This is mostly used to build custom form renderers.\n\nIf you just want to render a simple form as `Html`, check [`Form.View`](Form-View) first as it\nmight suit your needs.\n\n@docs Field, TextType, fill\n\n",
        "unions": [
            {
                "name": "Field",
                "comment": " Represents a form field.\n\nIf you are building your own form renderer you will probably need to pattern match this type,\nusing the result of [`fill`](#fill).\n\n",
                "args": [
                    "values"
                ],
                "cases": [
                    [
                        "Text",
                        [
                            "TextType",
                            "TextField values"
                        ]
                    ],
                    [
                        "Number",
                        [
                            "NumberField values"
                        ]
                    ],
                    [
                        "Range",
                        [
                            "RangeField values"
                        ]
                    ],
                    [
                        "Checkbox",
                        [
                            "CheckboxField values"
                        ]
                    ],
                    [
                        "Radio",
                        [
                            "RadioField values"
                        ]
                    ],
                    [
                        "Select",
                        [
                            "SelectField values"
                        ]
                    ],
                    [
                        "Group",
                        [
                            "List ( Field values, Maybe Error )"
                        ]
                    ]
                ]
            },
            {
                "name": "TextType",
                "comment": " Represents a type of text field\n",
                "args": [],
                "cases": [
                    [
                        "TextRaw",
                        []
                    ],
                    [
                        "TextEmail",
                        []
                    ],
                    [
                        "TextPassword",
                        []
                    ],
                    [
                        "TextArea",
                        []
                    ],
                    [
                        "TextSearch",
                        []
                    ]
                ]
            }
        ],
        "aliases": [
            {
                "name": "Form",
                "comment": " A `Form` collects and validates user input using fields. When a form is filled with `values`,\nit produces some `output` if validation succeeds.\n\nFor example, a `Form String EmailAddress` is a form that is filled with a `String` and produces\nan `EmailAddress` when valid. This form could very well be an [`emailField`](#emailField)!\n\n",
                "args": [
                    "values",
                    "output"
                ],
                "type": "Form values output (Field values)"
            }
        ],
        "values": [
            {
                "name": "andThen",
                "comment": " Fill a form `andThen` fill another one.\n\nThis is useful to build dynamic forms. For instance, you could use the output of a `selectField`\nto choose between different forms, like this:\n\n    type Msg\n        = CreatePost Post.Body\n        | CreateQuestion Question.Title Question.Body\n\n    type ContentType\n        = Post\n        | Question\n\n    type alias Values =\n        { type_ : Value String\n        , title : Value String\n        , body : Value String\n        }\n\n    contentForm : Form Values Msg\n    contentForm =\n        Form.selectField\n            { parser =\n                \\value ->\n                    case value of\n                        \"post\" ->\n                            Ok Post\n\n                        \"question\" ->\n                            Ok Question\n\n                        _ ->\n                            Err \"invalid content type\"\n            , value = .type_\n            , update = \\newValue values -> { values | type_ = newValue }\n            , attributes =\n                { label = \"Which type of content do you want to create?\"\n                , placeholder = \"Choose a type of content\"\n                , options = [ ( \"post\", \"Post\" ), ( \"question\", \"Question\" ) ]\n                }\n            }\n            |> Form.andThen\n                (\\contentType ->\n                    case contentType of\n                        Post ->\n                            let\n                                bodyField =\n                                    Form.textareaField\n                                        { -- ...\n                                        }\n                            in\n                            Form.succeed CreatePost\n                                |> Form.append bodyField\n\n                        Question ->\n                            let\n                                titleField =\n                                    Form.textField\n                                        { -- ...\n                                        }\n\n                                bodyField =\n                                    Form.textareaField\n                                        { -- ...\n                                        }\n                            in\n                            Form.succeed CreateQuestion\n                                |> Form.append titleField\n                                |> Form.append bodyField\n                )\n\n",
                "type": "(a -> Form values b) -> Form values a -> Form values b"
            },
            {
                "name": "append",
                "comment": " Append a form to another one while **capturing** the `output` of the first one.\n\nFor instance, we could build a signup form:\n\n    signupEmailField : Form { r | email : Value String } EmailAddress\n    signupEmailField =\n        Form.emailField\n            { -- ...\n            }\n\n    signupPasswordField : Form { r | password : Value String } Password\n    signupPasswordField =\n        Form.passwordField\n            { -- ...\n            }\n\n    signupForm :\n        Form\n            { email : Value String\n            , password : Value String\n            }\n            ( EmailAddress, Password )\n    signupForm =\n        Form.succeed (,)\n            |> Form.append signupEmailField\n            |> Form.append signupPasswordField\n\nIn this pipeline, `append` is being used to feed the `(,)` function and combine two forms\ninto a bigger form that outputs `( EmailAddress, Password )` when submitted.\n\n**Note:** You can use [`succeed`](#succeed) smartly to **skip** some values.\nThis is useful when you want to append some fields in your form to perform validation, but\nyou do not care about the `output` they produce. An example of this is a \"repeat password\" field:\n\n    passwordForm :\n        Form\n            { password : Value String\n            , repeatPassword : Value String\n            }\n            Password\n    passwordForm =\n        Form.succeed (\\password repeatedPassword -> password)\n            |> Form.append passwordField\n            |> Form.append repeatPasswordField\n\n",
                "type": "Form values a -> Form values (a -> b) -> Form values b"
            },
            {
                "name": "checkboxField",
                "comment": " Create a form that contains a single checkbox field.\n\nIt has a very similar configuration to [`textField`](#textField), the only differences are:\n\n  - Its value is a `Bool` instead of `String`.\n  - Its attributes are [`CheckboxField.Attributes`](Form-Base-CheckboxField#Attributes)\n    instead of [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "type": "{ parser : Bool -> Result String output, value : values -> Value Bool, update : Value Bool -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "emailField",
                "comment": " Create a form that contains a single email field.\n\nIt has the same configuration options as [`textField`](#textField).\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "fill",
                "comment": " Fill a form with some `values`.\n\nIt returns:\n\n  - a list of the fields of the form, alongside their errors\n  - the result of the filled form, which can either be:\n      - a non-empty list of validation errors\n      - the correct `output`\n  - whether the form is empty or not\n\n",
                "type": "Form values output -> values -> { fields : List ( Field values, Maybe Error ), result : Result ( Error, List Error ) output, isEmpty : Bool }"
            },
            {
                "name": "group",
                "comment": " Wraps a form in a group.\n\nUsing this function does not affect the behavior of the form in any way. However, groups of fields\nmight be rendered differently. For instance, [`Form.View`](Form-View) renders groups of\nfields horizontally.\n\n",
                "type": "Form values output -> Form values output"
            },
            {
                "name": "meta",
                "comment": " Build a form that depends on its own `values`.\n\nThis is useful when you need some fields to perform validation based on\nthe values of other fields. An example of this is a \"repeat password\" field:\n\n    repeatPasswordField :\n        Form\n            { r\n                | password : Value String\n                , repeatPassword : Value String\n            }\n            ()\n    repeatPasswordField =\n        Form.meta\n            (\\values ->\n                Form.passwordField\n                    { parser =\n                        \\value ->\n                            if Just value == Value.raw values.password then\n                                Ok ()\n                            else\n                                Err \"the passwords do not match\"\n                    , value = .repeatPassword\n                    , update =\n                        \\newValue values ->\n                            { values | repeatPassword = newValue }\n                    , attributes =\n                        { label = \"Repeat password\"\n                        , placeholder = \"Type your password again...\"\n                        }\n                    }\n            )\n\n",
                "type": "(values -> Form values output) -> Form values output"
            },
            {
                "name": "numberField",
                "comment": " Create a form that contains a single number field.\n\nIt has a very similar configuration to [`textField`](#textField), the only difference is:\n\n  - Its attributes are [`NumberField.Attributes`](Form-Base-NumberField#Attributes)\n    instead of [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "type": "{ parser : Float -> Result String output, value : values -> Value Float, update : Value Float -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "optional",
                "comment": " Make a form optional. An optional form succeeds when:\n\n  - All of its fields are **empty**, producing `Nothing`\n  - All of its fields are **correct**, producing `Just` the `output`\n\nLet's say we want to optionally ask for a website name and address:\n\n    websiteForm =\n        Form.optional\n            (Form.succeed InvoiceAddress\n                |> Form.append websiteNameField\n                |> Form.append websiteAddressField\n            )\n\nThis `websiteForm` will only be valid if **both** fields are blank, or **both** fields\nare filled correctly.\n\n",
                "type": "Form values output -> Form values (Maybe output)"
            },
            {
                "name": "passwordField",
                "comment": " Create a form that contains a single password field.\n\nIt has the same configuration options as [`textField`](#textField).\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "radioField",
                "comment": " Create a form that contains a single fieldset of radio fields.\n\nIt has a very similar configuration to [`textField`](#textField), the only difference is:\n\n  - Its attributes are [`RadioField.Attributes`](Form-Base-RadioField#Attributes)\n    instead of [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "rangeField",
                "comment": " Create a form that contains a single range field.\n\nIt has a very similar configuration to [`textField`](#textField), the only difference is:\n\n  - Its attributes are [`RangeField.Attributes`](Form-Base-RangeField#Attributes)\n    instead of [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "type": "{ parser : Float -> Result String output, value : values -> Value Float, update : Value Float -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "selectField",
                "comment": " Create a form that contains a single select field.\n\nIt has a very similar configuration to [`textField`](#textField), the only difference is:\n\n  - Its attributes are [`SelectField.Attributes`](Form-Base-SelectField#Attributes)\n    instead of [`TextField.Attributes`](Form-Base-TextField#Attributes).\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "succeed",
                "comment": " Create an **empty** form that always succeeds when filled, returning the given `output`.\n\nIt might seem pointless on its own, but it becomes useful when used in combination with other\nfunctions. The docs for [`append`](#append) have some great examples.\n\n",
                "type": "output -> Form values output"
            },
            {
                "name": "textField",
                "comment": " Create a form that contains a single text field.\n\nIt requires some configuration:\n\n  - `parser` specifies how to validate the field. It needs a function that processes the value of\n    the field and produces a `Result` of either:\n      - a `String` describing an error\n      - a correct `output`\n  - `value` describes how to obtain the field [`Value`](Form-Value) from the form `values`\n  - `update` describes how the current form `values` should be updated with a new field\n    [`Value`](Form-Value)\n  - `attributes` let you define the specific attributes of the field (`label` and `placeholder`\n    in this case, see [`TextField.Attributes`](Form-Base-TextField#Attributes))\n\nIt might seem like a lot of configuration, but don't be scared! In practice, it isn't!\nFor instance, you could use this function to build a `nameField` that only succeeds when the\ninputted name has at least 2 characters, like this:\n\n    nameField : Form { r | name : Value String } String\n    nameField =\n        Form.textField\n            { parser =\n                \\name ->\n                    if String.length name < 2 then\n                        Err \"the name must have at least 2 characters\"\n                    else\n                        Ok name\n            , value = .name\n            , update =\n                \\newValue values ->\n                    { values | name = newValue }\n            , attributes =\n                { label = \"Name\"\n                , placeholder = \"Type your name...\"\n                }\n            }\n\nAs you can see:\n\n  - a `parser` is just a simple validation function\n  - you can define `value` using [record accessors](http://elm-lang.org/docs/records#access)\n  - the `update` function updates the `values` of the form with the `newValue`\n  - `attributes` are most of the time a simple record\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            },
            {
                "name": "textareaField",
                "comment": " Create a form that contains a single textarea field.\n\nIt has the same configuration options as [`textField`](#textField).\n\n",
                "type": "{ parser : String -> Result String output, value : values -> Value String, update : Value String -> values -> values, attributes : Attributes } -> Form values output"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.RadioField",
        "comment": " This module contains a reusable `RadioField` type.\n\n\n# Definition\n\n@docs RadioField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a RadioField.\n\nYou need to provide these to:\n\n  - [`Form.radioField`][radioField]\n\n[radioField]: Form#radioField\n\n",
                "args": [],
                "type": "{ label : String, options : List ( String, String ) }"
            },
            {
                "name": "RadioField",
                "comment": " Represents a radio field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes String values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `RadioField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(RadioField values -> field) -> FieldConfig Attributes String values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.RangeField",
        "comment": " This module contains a reusable `RangeField` type.\n\n\n# Definition\n\n@docs RangeField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a RangeField.\n\nYou need to provide these to:\n\n  - [`Form.rangeField`][rangeField]\n\n[rangeField]: Form#rangeField\n\n",
                "args": [],
                "type": "{ label : String, step : Float, min : Maybe Float, max : Maybe Float }"
            },
            {
                "name": "RangeField",
                "comment": " Represents a range field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes Float values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `RangeField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(RangeField values -> field) -> FieldConfig Attributes Float values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.TextField",
        "comment": " This module contains a reusable `TextField` type.\n\n\n# Definition\n\n@docs TextField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a TextField.\n\nYou need to provide these to:\n\n  - [`Form.textField`][textField]\n  - [`Form.emailField`][emailField]\n  - [`Form.passwordField`][passwordField]\n  - [`Form.textareaField`][textareaField]\n\n[textField]: Form#textField\n[emailField]: Form#emailField\n[passwordField]: Form#passwordField\n[textareaField]: Form#textareaField\n\n",
                "args": [],
                "type": "{ label : String, placeholder : String }"
            },
            {
                "name": "TextField",
                "comment": " Represents a text field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes String values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `TextField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(TextField values -> field) -> FieldConfig Attributes String values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.NumberField",
        "comment": " This module contains a reusable `NumberField` type.\n\n\n# Definition\n\n@docs NumberField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a NumberField.\n\nYou need to provide these to:\n\n  - [`Form.numberField`][numberField]\n\n[numberField]: Form#numberField\n\n",
                "args": [],
                "type": "{ label : String, placeholder : String, step : Float, min : Maybe Float, max : Maybe Float }"
            },
            {
                "name": "NumberField",
                "comment": " Represents a number field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes Float values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `NumberField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(NumberField values -> field) -> FieldConfig Attributes Float values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.SelectField",
        "comment": " This module contains a reusable `SelectField` type.\n\n\n# Definition\n\n@docs SelectField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a SelectField.\n\nYou need to provide these to:\n\n  - [`Form.selectField`][selectField]\n\n[selectField]: Form#selectField\n\n",
                "args": [],
                "type": "{ label : String, placeholder : String, options : List ( String, String ) }"
            },
            {
                "name": "SelectField",
                "comment": " Represents a select field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes String values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `SelectField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(SelectField values -> field) -> FieldConfig Attributes String values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base.CheckboxField",
        "comment": " This module contains a reusable `CheckboxField` type.\n\n\n# Definition\n\n@docs CheckboxField, Attributes\n\n\n# Helpers\n\n@docs form\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Attributes",
                "comment": " The attributes of a CheckboxField.\n\nYou need to provide these to:\n\n  - [`Form.checkboxField`][checkboxField]\n\n[checkboxField]: Form#checkboxField\n\n",
                "args": [],
                "type": "{ label : String }"
            },
            {
                "name": "CheckboxField",
                "comment": " Represents a checkbox field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n",
                "args": [
                    "values"
                ],
                "type": "Field Attributes Bool values"
            }
        ],
        "values": [
            {
                "name": "form",
                "comment": " Builds a [`Form`](Form-Base#Form) with a single `CheckboxField`.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "(CheckboxField values -> field) -> FieldConfig Attributes Bool values output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Base",
        "comment": " Build composable forms with your own custom fields.\n\nThis is the **base** of the `composable-form` package. It implements a composable [`Form`](#Form)\ntype that is not tied to any particular `field`.\n\nIn order to understand this module, you should be familar with [the basic `Form module`](Form)\nfirst.\n\n\n# Definition\n\n@docs Form\n\n\n# Custom fields\n\nSay you need to use a type of field that is not implemented in the [the basic `Form module`](Form).\nThe recommended way of doing this is to copy [the source code of the basic `Form` module][form-source]\ninto your own `MyProject.Form` module, and then use [`field`](#field) and [`custom`](#custom) to\ndefine new types of fields.\n\n[form-source]: https://github.com/hecrj/composable-form/tree/master/src/Form.elm\n\nWhile copy-pasting code might sound like a bad idea, keep in mind that\n[the basic `Form module`](Form) does not contain much code at all! It is just a bunch of one-liners\nthat delegate to this base module. It is the perfect template to build your own form.\n\nIf that still does not convince you, you could start your own `MyProject.Form` module like this:\n\n    import Form.Base as Base\n\n    type alias Form values output =\n        Base.Form values output (Field values)\n\n    type Field values\n        = None\n\n    succeed : output -> Form values output\n    succeed =\n        Base.succeed\n\n\n    -- Other useful operations you will probably want to use,\n    -- like append, andThen...\n\nNotice that we could avoid redefining `succeed`, `append`, and others, but that would force us to\nimport `Form.Base` every time we needed to use those operations with our brand new form.\n\n@docs field, FieldConfig, custom, FilledField\n\n\n# Composition\n\n@docs succeed, append, andThen, optional, meta\n\n\n# Output\n\n@docs FilledForm, fill\n\n",
        "unions": [
            {
                "name": "Form",
                "comment": " A [`Form`](Form#Form) that can contain any type of `field`.\n",
                "args": [
                    "values",
                    "output",
                    "field"
                ],
                "cases": []
            }
        ],
        "aliases": [
            {
                "name": "FieldConfig",
                "comment": " Most form fields require configuration! `FieldConfig` allows you to specify how a\nconcrete field is validated and updated, alongside its attributes:\n\n  - `parser` must be a function that validates the `input` of the field and produces a `Result`\n    of either:\n      - the correct `output`\n      - a `String` describing a problem\n  - `value` defines how the [`Value`](Form.Value) of the field is obtained from the form `values`\n  - `update` defines how the current form `values` should be updated with a new field\n    [`Value`](Form.Value)\n  - `attributes` represent the attributes of the field\n\n",
                "args": [
                    "attrs",
                    "input",
                    "values",
                    "output"
                ],
                "type": "{ parser : input -> Result String output, value : values -> Value input, update : Value input -> values -> values, attributes : attrs }"
            },
            {
                "name": "FilledField",
                "comment": " Represents a field on a form that has been filled with values.\n\nIt contains:\n\n  - a field\n  - the result of the field\n  - whether the field is empty or not\n\n",
                "args": [
                    "output",
                    "field"
                ],
                "type": "{ field : field, result : Result ( Error, List Error ) output, isEmpty : Bool }"
            },
            {
                "name": "FilledForm",
                "comment": " Represents a filled form.\n\nYou can obtain this by using [`fill`](#fill).\n\n",
                "args": [
                    "field",
                    "output"
                ],
                "type": "{ fields : List ( field, Maybe Error ), result : Result ( Error, List Error ) output, isEmpty : Bool }"
            }
        ],
        "values": [
            {
                "name": "andThen",
                "comment": " Like [`Form.andThen`](Form#andThen) but not tied to a particular type of `field`.\n",
                "type": "(a -> Form values b field) -> Form values a field -> Form values b field"
            },
            {
                "name": "append",
                "comment": " Like [`Form.append`](Form#append) but not tied to a particular type of `field`.\n",
                "type": "Form values a field -> Form values (a -> b) field -> Form values b field"
            },
            {
                "name": "custom",
                "comment": " Create a custom field with total freedom.\n\nYou only need to provide a function that given some `values` produces a [`FilledField`](#FilledField).\n\nYou can check the [custom fields example][custom-fields] for some inspiration.\n\n[custom-fields]: https://hecrj.github.io/composable-form/#/custom-fields\n\n",
                "type": "(values -> FilledField output field) -> Form values output field"
            },
            {
                "name": "field",
                "comment": " Create functions that build forms that contain a single field with an API that is similar to\n[the basic `Form` module](Form).\n\nThis function is meant to be partially applied, providing only the two first parameters to\nobtain a function that expects the configuration for a particular type of field. See\n[`FieldConfig`](#FieldConfig).\n\nFor this, you only need to provide:\n\n  - A function that given the `input` of the field tells whether it is empty or not.\n  - A function that maps a generic [`Field`](Field#Field) to your own specific `field` type.\n\nFor example, [`Form.textField`](Form#textField) could be implemented like this:\n\n    textField :\n        { parser : String -> Result String output\n        , value : values -> Value String\n        , update : Value String -> values -> values\n        , attributes : TextField.Attributes\n        }\n        -> Form values output\n    textField =\n        Base.field { isEmpty = String.isEmpty } (Text TextRaw)\n\nNotice how the configuration record in `textField` is a [`FieldConfig`](#FieldConfig).\n\n**Note:** You can use [`TextField.form`](Form-Base-TextField#form),\n[`SelectField.form`](Form-Base-SelectField#form), and others to build fields that are already\npresent in [`Form`](Form).\n\n",
                "type": "{ isEmpty : input -> Bool } -> (Field attributes input values -> field) -> FieldConfig attributes input values output -> Form values output field"
            },
            {
                "name": "fill",
                "comment": " Like [`Form.fill`](Form#fill) but not tied to a particular type of `field`.\n",
                "type": "Form values output field -> values -> FilledForm field output"
            },
            {
                "name": "meta",
                "comment": " Like [`Form.meta`](Form#meta) but not tied to a particular type of `field`.\n",
                "type": "(values -> Form values output field) -> Form values output field"
            },
            {
                "name": "optional",
                "comment": " Like [`Form.optional`](Form#optional) but not tied to a particular type of `field`.\n",
                "type": "Form values output field -> Form values (Maybe output) field"
            },
            {
                "name": "succeed",
                "comment": " Like [`Form.succeed`](Form#succeed) but not tied to a particular type of `field`.\n",
                "type": "output -> Form values output field"
            }
        ],
        "binops": []
    },
    {
        "name": "Form.Field",
        "comment": " This module contains a type that represents a generic form field.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields or writing your own form renderer.\n\n@docs Field\n\n",
        "unions": [],
        "aliases": [
            {
                "name": "Field",
                "comment": " Represents a form field.\n\nIt contains:\n\n  - the current `value` of the field\n  - an `update` function that takes a new **field** value and returns updated\n    **form** values\n  - the `attributes` of the field\n\nThese record fields are normally used in renderers to set up the `value` and `onInput`\nattributes. For example, you could render a `TextField` like this:\n\n    view : (values -> msg) -> Form values output -> values -> Html output\n    view onChange form values =\n        let\n            { fields, result } =\n                Form.fill form values\n\n            fieldsHtml =\n                List.map (viewField onChange) fields\n\n            -- ...\n        in\n        Html.form\n            [-- ...\n            ]\n            [ Html.div [] fieldsHtml\n            , submitButton\n            ]\n\n    viewField : (values -> msg) -> ( Form.Field values, Maybe Error ) -> Html msg\n    viewField onChange ( field, maybeError ) =\n        case field of\n            Form.Text TextField.Raw { value, update, attributes } ->\n                Html.input\n                    [ Attributes.type_ \"text\"\n                    , Attributes.value\n                        (value\n                            |> Value.raw\n                            |> Maybe.withDefault \"\"\n                        )\n                    , Attributes.onInput (update >> onChange)\n                    , Attributes.placeholder attributes.placeholder\n                    ]\n                    []\n\n            _ ->\n                -- ...\n\n",
                "args": [
                    "attributes",
                    "value",
                    "values"
                ],
                "type": "{ value : Value value, update : value -> values, attributes : attributes }"
            }
        ],
        "values": [],
        "binops": []
    },
    {
        "name": "Form.Error",
        "comment": " This module contains a form [`Error`](#Error) type.\n\n**Note:** You should not need to care about this unless you are writing your own form renderer.\n\n@docs Error\n\n",
        "unions": [
            {
                "name": "Error",
                "comment": " Represents a form error.\n\nIt can either be:\n\n  - `RequiredFieldIsEmpty`, meaning that a required field is empty.\n  - `ValidationFailed`, meaning the field validation has failed. This type of error contains a\n    `String` describing the validation error.\n\nThese type of errors are returned alongside each field in the [`Form.fill`](Form#fill) and\n[`Form.Base.fill`](Form-Base#fill) functions.\n\nYou can easily write a simple function that turns this type into a `String`:\n\n    errorToString : Error -> String\n    errorToString error =\n        case error of\n            Error.RequiredFieldIsEmpty ->\n                \"this field is required\"\n\n            Error.ValidationFailed errorDescription ->\n                errorDescription\n\n",
                "args": [],
                "cases": [
                    [
                        "RequiredFieldIsEmpty",
                        []
                    ],
                    [
                        "ValidationFailed",
                        [
                            "String"
                        ]
                    ]
                ]
            }
        ],
        "aliases": [],
        "values": [],
        "binops": []
    },
    {
        "name": "Form.Value",
        "comment": " This module contains a value type for your form fields.\n\n\n# Definition\n\n@docs Value\n\n\n# Constructors\n\n@docs blank, filled\n\n\n# Queries\n\n@docs raw\n\n\n# Updates\n\n@docs update\n\n\n# Comparisons\n\n@docs newest\n\n",
        "unions": [
            {
                "name": "Value",
                "comment": " Represents a form field value.\n",
                "args": [
                    "a"
                ],
                "cases": []
            }
        ],
        "aliases": [],
        "values": [
            {
                "name": "blank",
                "comment": " A blank value.\n\nUse this to initialize the values of your empty fields:\n\n    values : SignupValues\n    values =\n        { email = Value.blank\n        , password = Value.blank\n        , rememberMe = Value.blank\n        }\n\n",
                "type": "Value a"
            },
            {
                "name": "filled",
                "comment": " Build an already filled value.\n\nUse this when you are using forms to edit existing values:\n\n    values : Profile -> ProfileValues\n    values profile =\n        { firstName = Value.filled profile.firstName\n        , lastName = Value.filled profile.lastName\n        }\n\n",
                "type": "a -> Value a"
            },
            {
                "name": "newest",
                "comment": " Select the newest value out of two sets of values.\n\nThis is necessary to fix an issue with autocompletion. When a form is autocompleted, many events\ncan get triggered before the view can be rerendered, causing the first autocompleted values to be\nlost.\n\n`newest` allows to fix this:\n\n    update : Msg -> Model -> Model\n    update msg values =\n        FormChanged newForm ->\n            { form |\n                values =\n                    { email = Value.newest .email form.values newForm.values\n                    , password = Value.newest .password form.values newForm.values\n                    }\n            }\n\n**Note:** This issue _seems_ fixed in Elm 0.19, thus this function will be removed soon.\n\n",
                "type": "(values -> Value a) -> values -> values -> Value a"
            },
            {
                "name": "raw",
                "comment": " Obtain the data inside a [`Value`](#Value).\n\nIf the value is blank, it returns `Nothing`, else it returns `Just` the value.\n\n**Note:** You should only be using this in [`meta` forms](Form#meta) or your own custom renderer.\n\n",
                "type": "Value a -> Maybe a"
            },
            {
                "name": "update",
                "comment": " Update a value with new data.\n\n**Note:** You should not need to care about this unless you are creating your own\ncustom fields.\n\n",
                "type": "a -> Value a -> Value a"
            }
        ],
        "binops": []
    }
]