[{"name":"Knob","comment":" Let's get started creating a control panel full of “knobs” to interactively tweak values in our application.\n\nWhen creating a knob, two considerations are important.\nThe first is the type of the value you need to control.\nThis package currently provides knobs for numbers, booleans, enumerated choices (custom types or anything like that)\nand colors out of the box, and there is a way to either transform one into another type ([`map`](#map)),\nor to create an entirely new knob ([`custom`](#custom)).\n\nThe second important consideration is the interface you want to provide to manipulate that value,\ni.e. the control itself. Many knobs offer different controls for the same type,\nparticularly number-related ones, so pick the one that best suits your needs!\n\n@docs Knob\n\n\n# Creating knobs for base values\n\nFirst up, within our app's `init` let's create a `Knob` and put it in the model.\nThe following are the functions you can use to create basic knobs that map to a single value.\n\n@docs float, floatConstrained, floatSlider\n@docs int, intConstrained, intSlider\n@docs boolCheckbox\n@docs select, Color, colorPicker\n\n\n# Displaying\n\nThe next step is to actually display our knob in the page.\n\n@docs view, styles\n\n\n# Retrieving the value\n\nOf course, our knobs are of no use to us if we can't read the value entered by the user.\n\n@docs value\n\n\n# Composing knobs\n\nMost of the time you'll want to control multiple values.\nFor that purpose we're going to “stack” our knobs together.\n\n@docs compose, stack\n\n\n# Organization\n\nWe could have a bunch of similar knobs in our panel and not know what each of them does,\nso let's make sure we do!\n\n@docs label, stackLabel\n\n\n# Transformation\n\n@docs map\n\n\n# Custom knobs\n\n@docs custom\n\n","unions":[{"name":"Knob","comment":" Represents one user-interactive control mapped to one value of type `a`,\nwhich this package refers to as a “knob”.\nThis is the base type used to create your knobs control panel!\nNormally you'll have a single one of these stored in your model,\nbut that one knob can actually represent a group of [`compose`](#compose)d knobs.\n","args":["a"],"cases":[]}],"aliases":[{"name":"Color","comment":" Represents an RGB color value. Each channel value is a `Float` between 0 and 1.\nThis is the type that the [`colorPicker`](#colorPicker) knob uses.\n","args":[],"type":"{ red : Basics.Float, green : Basics.Float, blue : Basics.Float }"}],"values":[{"name":"boolCheckbox","comment":" Creates a checkbox representing a boolean value.\n`initial` determines whether it will be initially checked or not.\n","type":"Basics.Bool -> Knob.Knob Basics.Bool"},{"name":"colorPicker","comment":" Creates a color picker input.\nColors are represented using a type alias `Color`,\nwhich is easily [`map`](#map)pable into other color formats for your convenience.\nBelow is an example mapping it into [avh4/elm-color](/packages/avh4/elm-color/1.0.0/) format.\n\n    -- We set magenta as the initial color.\n    Knob.colorPicker { red = 1, green = 0, blue = 1 }\n        -- We map it into avh4/elm-color format.\n        |> Knob.map (c -> Color.rgb c.red c.green c.blue)\n\n","type":"Knob.Color -> Knob.Knob Knob.Color"},{"name":"compose","comment":" Creates a knob that joins multiple knobs to build up a record\n(or actually any data structure you want, depending on the `constructor` argument you pass it!)\n\nPipe ([`|>`](/packages/elm/core/1.0.5/Basics#%7C%3E)) the knobs into it\nusing [`stack`](Knob#stack) or [`stackLabel`](Knob#stackLabel) in order to provide the arguments.\n\n    type alias Controls =\n        { someNumber : Float\n        , anInteger : Int\n        }\n\n    aKnob =\n        Knob.compose Controls\n            -- This knob will map to `someNumber`:\n            |> Knob.stack (Knob.float { step = 1, initial = 0 })\n            -- This one will map to `anInteger`:\n            |> Knob.stack (Knob.int { step = 1, initial = 0 })\n\nHere's how you use it to build up a different data structure, in this case a tuple.\nNotice that the number of arguments in the function matches the number of “stacks”.\n\n    anotherKnob =\n        Knob.compose (\\theFloat theInt -> ( theFloat, theInt ))\n            |> Knob.stack (Knob.float { step = 1, initial = 0 })\n            |> Knob.stack (Knob.int { step = 1, initial = 0 })\n\n","type":"(a -> b) -> Knob.Knob (a -> b)"},{"name":"custom","comment":" Creates a knob for any type, using a custom HTML view that you supply.\nYou can use this function if there is some kind of knob you need\nthat is not available in this package, and can't be created by using [`map`](#map)\nover a predefined knob.\n\nKnobs are comprised of a `value` of the appropriate type,\nand a `view` which listens to user input\n(typically the `Html.Events.onInput` event)\nand emits the updated knob, instead of a regular message like is normally done.\nIn this sense, knobs are recursive, as their view needs to construct a new knob,\ntypically by calling the very same constructor function that created it in the first place.\n\nHere's how the `boolCheckbox` knob would be created using `custom`:\n\n    ourBoolKnob : Bool -> Knob Bool\n    ourBoolKnob initial =\n        let\n            view : () -> Html (Knob Bool)\n            view () =\n                Html.input\n                    [ Html.Attributes.type_ \"checkbox\"\n                    , Html.Attributes.checked initial\n                    , Html.Events.onChecked ourBoolKnob\n                    ]\n                    []\n        in\n        Knob.custom\n            { value = initial\n            , view = view\n            }\n\nNotice how `view` is a thunk—that is, a function that takes `()` (a placeholder value)\nand returns the view.\nThe view is just some HTML that emits knobs instead of messages.\nTake a look at the line with `Html.Events.onChecked` and make note of what we're doing:\nWe're directly passing in `ourBoolKnob` because it's a function that takes\nthe new \"checked\" value and with it constructs the knob anew.\nThis is how we're transforming the contained value when the user clicks.\n\nA thing to keep in mind: For cases in which you're taking unconstrained user input,\nsuch as a text field, you can wind up making it so that the user cannot input freely.\nThis occurs if you're parsing the input into a different type in a lossy manner.\n\nLet's imagine we want to display a text field to map a `String` to a `Vegetable` type.\nIn the naïve case, our knob's signature could look like this, taking `Vegetable`\nto set the initial value:\n\n    vegetableKnob : Vegetable -> Knob Vegetable\n\nIt would convert the initial value to a `String`, and set that as the text field's text.\nThen, upon user input, we'd parse the input `String` into our type,\nand use that to construct the updated knob.\n\nThe problem with this situation is that if the conversion from `String` to `Vegetable`\nand then back into `String` is lossy (i.e., the result is not the same as what the user typed,)\nthen the user won't be able to type some things, as they'll be changing every time\nthey hit a key.\n\n    vegetableFromString : String -> Vegetable\n    vegetableFromString text =\n        case text of\n            \"carrot\" ->\n                Carrot\n\n            _ ->\n                Tomato\n\nIf we're using the function above to parse user input into `Vegetable`,\nthe user may want to type \"carrot\" and start typing \"c\",\nbut as it's not yet a valid value, it will be parsed as `Tomato`\nand the text field's text will be reset to whatever the string value for `Tomato` is.\n\nIn order to prevent this behavior, set the unparsed input text as the text field's `value` property,\nand set the parsed result as the knob's `value`.\nThis means that your knob will need to take a `String` as its initial value.\n\n    vegetableKnob : String -> Knob Vegetable\n    vegetableKnob initial =\n        Knob.custom\n            { value = vegetableFromString initial -- Parse here!\n            , view =\n                \\() ->\n                    Html.input\n                        [ Html.Attributes.type_ \"text\"\n                        , Html.Attributes.value initial -- No parsing\n                        , Html.Events.onInput vegetableKnob\n                        ]\n                        []\n            }\n\n","type":"{ value : a, view : () -> Html.Html (Knob.Knob a) } -> Knob.Knob a"},{"name":"float","comment":" Creates an input field knob for manually entering any floating point number.\nThe `step` argument specifies the amount the number will increase or decrease\nwhen pressing the up and down keys.\n`initial` is just the value it takes on first load.\n","type":"{ step : Basics.Float, initial : Basics.Float } -> Knob.Knob Basics.Float"},{"name":"floatConstrained","comment":" Creates an input field knob for manually entering numbers within a specific range,\nwhere `range = ( min, max )`.\nThe `step` argument specifies the amount the number will increase or decrease\nwhen pressing the up and down keys.\n`initial` is just the value it takes on first load.\n","type":"{ range : ( Basics.Float, Basics.Float ), step : Basics.Float, initial : Basics.Float } -> Knob.Knob Basics.Float"},{"name":"floatSlider","comment":" Creates a slider knob useful for quickly tweaking numbers when precision is not needed.\nRequires a `range = ( min, max )` to set the boundaries of the slider control.\n`initial` is just the value it takes on first load.\n\nThe `step` argument indicates the granularity of the values the slider will allow,\nso a step of `1` will produce a slider that jumps between values like `1`, `2`, `3` as you slide it to the right,\nwhereas a step of `0.1` will produce one that allows setting values like `1.1` or `2.5`.\n\n","type":"{ range : ( Basics.Float, Basics.Float ), step : Basics.Float, initial : Basics.Float } -> Knob.Knob Basics.Float"},{"name":"int","comment":" Creates an input field knob for manually entering any integer.\nThe `step` argument specifies the amount the number will increase or decrease\nwhen pressing the up and down keys.\n`initial` is just the value it takes on first load.\n","type":"{ step : Basics.Int, initial : Basics.Int } -> Knob.Knob Basics.Int"},{"name":"intConstrained","comment":" Creates an input field knob for manually entering integers within a specific range.\nThe `step` argument specifies the amount the number will increase or decrease\nwhen pressing the up and down keys.\n`initial` is just the value it takes on first load.\n","type":"{ range : ( Basics.Int, Basics.Int ), step : Basics.Int, initial : Basics.Int } -> Knob.Knob Basics.Int"},{"name":"intSlider","comment":" Creates a slider knob useful for quickly tweaking integers when precision is not needed.\nRequires a `range = ( min, max )` to set the boundaries of the slider control.\n`initial` is just the value it takes on first load.\n\nThe `step` argument indicates the granularity of the values the slider will allow,\nso a step of `1` will produce a slider that will set on any integer value as you slide it to the right,\nwhereas a step of `10` will produce one that makes bigger jumps between `10`, `20`, `30`, etc.\n\n","type":"{ range : ( Basics.Int, Basics.Int ), step : Basics.Int, initial : Basics.Int } -> Knob.Knob Basics.Int"},{"name":"label","comment":" Attaches a text description next to a knob, as a way to identify what the control is for.\n\nThe following example will produce a [`float`](Knob#float) knob described as “x position”.\n\n    Knob.label \"x position\"\n        (Knob.float { step = 1, initial = 0 })\n\n","type":"String.String -> Knob.Knob a -> Knob.Knob a"},{"name":"map","comment":" Analogous to `List.map` or other data structures' `map` function,\nyou can use this function to convert the value produced by a Knob.\n\nThe following example converts a knob that produces an `Int` (i.e. a `Knob Int`)\ninto one that produces a `String` (i.e. a `Knob String`.) This is achieved\nbecause `String.fromInt` is a function with the type `Int -> String`.\n\n    Knob.int { step = 1, initial = 0 }\n        |> Knob.map String.fromInt\n\n","type":"(a -> b) -> Knob.Knob a -> Knob.Knob b"},{"name":"select","comment":" Creates a dropdown select input for a custom type or any arbitrary value you wish.\nYou'll need to provide a list of `String`s that represent each selectable option.\nYou'll also need a `fromString` function that maps these strings to your type,\nand the reverse `toString` which converts a value of your type to one of the option strings.\n\nHere's a simple example mapping \"yes\" and \"no\" options to `Bool` values:\n\n    Knob.select\n        { options = [ \"yes\", \"no\" ]\n        , toString =\n            \\bool ->\n                case bool of\n                    True ->\n                        \"yes\"\n\n                    False ->\n                        \"no\"\n        , fromString = \\string -> string == \"yes\"\n        , initial = False\n        }\n\n","type":"{ options : List.List String.String, toString : a -> String.String, fromString : String.String -> a, initial : a } -> Knob.Knob a"},{"name":"stack","comment":" Adds a knob into a [`compose`](Knob#compose) knob.\nSee the documentation for that for an example.\n\nThis function is called “stack” because the order you compose your knobs does matter,\nas they will be displayed one on top of the other!\n\n","type":"Knob.Knob a -> Knob.Knob (a -> b) -> Knob.Knob b"},{"name":"stackLabel","comment":" Convenience function that unifies the functionality of [`stack`](Knob#stack) and [`label`](Knob#label).\n\nThe two examples below produce the same identical result:\n\n    -- This:\n    Knob.stackLabel \"Some label\" someKnob\n\n    -- is the same as:\n    Knob.stack (Knob.label \"Some label\" someKnob)\n\n","type":"String.String -> Knob.Knob a -> Knob.Knob (a -> b) -> Knob.Knob b"},{"name":"styles","comment":" Default styles for the knobs, provided as a `<style>` tag.\nPut this as a child somewhere in your view in order to use them.\n\nYou could choose not to use these default styles and instead provide your own.\nI recommend you check the DOM output in your browser's inspector—the structure of the HTML produced is pretty simple!\n\n","type":"Html.Html msg"},{"name":"value","comment":" Extract the current value out of a knob.\nUse it in your view to affect what you display.\n\n    Knob.int { step = 1, initial = 5 }\n        |> Knob.value -- Gets `5`.\n\n","type":"Knob.Knob a -> a"},{"name":"view","comment":" Converts a knob into HTML to put in your view.\nYou should display a single [`Knob`](Knob#Knob) value at any which time,\nso if you need multiple knobs, make sure you [`compose`](Knob#compose) them into a single value!\n\nKnobs keep track of their state once they're put in the view,\nbut for that you need to wire them up with a message,\nwhich is the first argument that this function takes.\n\nThis function produces plain HTML with no styles, so make sure you also include [`styles`](Knob#styles)\nin your page to make it display properly, or provide your own custom styles.\n\n    -- Prepare a message for your knob:\n    type Msg =\n        KnobUpdated (Knob YourType)\n\n    -- Put this as an HTML node within your view:\n    Knob.view KnobUpdated yourKnob\n\nCheck [the documentation's readme](/packages/agj/elm-knobs/1.1.0/)\nfor a full demonstration on how to wire things up.\n\n","type":"(Knob.Knob a -> msg) -> Knob.Knob a -> Html.Html msg"}],"binops":[]}]