-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
**NB!** Most of the development of this module and its related usage has occurred in elm-mdl. Particularly debois/elm-mdl#179 Special thanks to @debois for contributing and helping with the development of this package
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
elm-stuff | ||
.*.sw? | ||
*~ | ||
elm.js | ||
index.html | ||
docs.json | ||
documentation.json | ||
.vscode/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Copyright (c) 2016, Ville Penttinen | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
* Neither the name of the elm-dispatch nor the | ||
names of its contributors may be used to endorse or promote products | ||
derived from this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | ||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# elm-dispatch | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
Makes it easier to dispatch multiple messages from a single `Html.Event`. | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
|
||
The library was developed for the purpose of allowing UI component libraries, such as [elm-mdl](http://package.elm-lang.org/packages/debois/elm-mdl/latest), to have stateful components that perform some internal actions on `Html.Events` such as `click`, `focus` and `blur` while still allowing users to have their own event handlers for those particular events as well. | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
|
||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
|
||
## Install | ||
|
||
```shell | ||
elm package install vipentti/elm-dispatch | ||
``` | ||
|
||
## Examples | ||
|
||
To see the library in action see [elm-mdl](http://package.elm-lang.org/packages/debois/elm-mdl/latest) specifically [Material.Options.Internal](https://github.com/debois/elm-mdl/blob/master/src/Material/Options/Internal.elm). | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
|
||
An example may also be found in `examples/` | ||
|
||
## Basic Usage | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
|
||
To add support for Dispatch: | ||
|
||
Add a dispatch message to your `Msg` | ||
```elm | ||
type Msg | ||
= ... | ||
| Dispatch (List Msg) | ||
... | ||
``` | ||
|
||
Add call to `Dispatch.forward` in update | ||
```elm | ||
update : Msg -> Model -> (Model, Cmd Msg) | ||
update msg model = | ||
case msg of | ||
... | ||
|
||
Dispatch messages -> | ||
model ! [ Dispatch.forward messages ] | ||
|
||
... | ||
``` | ||
|
||
Add a call to `Dispatch.on` on an element | ||
```elm | ||
view : Model -> Html Msg | ||
view model = | ||
let | ||
decoders = | ||
[ Json.Decode.succeed Click | ||
, Json.Decode.succeed PerformAnalytics | ||
, Json.Decode.map SomeMessage | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
(Json.at ["target", "offsetWidth"] Json.float) ] | ||
in | ||
Html.button | ||
[ Dispatch.on "click" Dispatch decoders ] | ||
[ text "Button" ] | ||
``` | ||
|
||
For more advanced use see `examples/`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"version": "1.0.0", | ||
"summary": "Allow for dispatching multiple messages from a single Html event", | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
"repository": "https://github.com/vipentti/elm-dispatch.git", | ||
"license": "BSD3", | ||
This comment has been minimized.
Sorry, something went wrong. |
||
"source-directories": [ | ||
"src", | ||
"examples" | ||
], | ||
"exposed-modules": [ | ||
"Dispatch" | ||
], | ||
"dependencies": { | ||
"elm-lang/core": "4.0.5 <= v < 5.0.0", | ||
"elm-lang/html": "1.1.0 <= v < 2.0.0" | ||
}, | ||
"elm-version": "0.17.1 <= v < 0.18.0" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
module FancyButton | ||
exposing | ||
( Msg | ||
, Model | ||
, Property | ||
, model | ||
, update | ||
, view | ||
, clickCount | ||
, any | ||
, on | ||
, on1 | ||
, onClick | ||
) | ||
|
||
import Html exposing (..) | ||
import Html.Attributes exposing (style) | ||
import Dispatch | ||
import Json.Decode as Json | ||
|
||
|
||
-- MODEL | ||
{-| Model is opaque as it contains internal state. | ||
-} | ||
type Model | ||
= Model | ||
{ focused : Bool | ||
, clickCount : Int | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
{-| Initialize the model | ||
-} | ||
model : Model | ||
model = | ||
Model | ||
{ focused = False | ||
, clickCount = 0 | ||
} | ||
|
||
|
||
{-| Utility function to access some internal state | ||
-} | ||
clickCount : Model -> Int | ||
clickCount (Model { clickCount }) = | ||
clickCount | ||
|
||
|
||
|
||
-- Properties | ||
|
||
{-| FancyButton only accepts specific | ||
types of properties | ||
-} | ||
type Property msg | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
= Decoder String (Json.Decoder msg) | ||
| Any (Html.Attribute msg) | ||
|
||
|
||
{-| Add an `Html.Event` handler | ||
-} | ||
on : String -> Json.Decoder msg -> Property msg | ||
This comment has been minimized.
Sorry, something went wrong. |
||
on = | ||
Decoder | ||
|
||
|
||
{-| Add an `Html.Event` handler. | ||
Equivalent to `FancyButton.on "event" (Json.succeed msg)` | ||
-} | ||
on1 : String -> msg -> Property msg | ||
on1 evt msg = | ||
on evt (Json.succeed msg) | ||
|
||
|
||
{-| Add an onClick handler. | ||
-} | ||
onClick : msg -> Property msg | ||
onClick msg = | ||
on1 "click" msg | ||
|
||
|
||
{-| Map from Html.Attribute to a FancyButton.Property | ||
-} | ||
any : Html.Attribute msg -> Property msg | ||
any = | ||
Any | ||
|
||
|
||
|
||
-- UPDATE | ||
|
||
|
||
type Msg msg | ||
= Click | ||
| Focus | ||
| Blur | ||
{- This message tells Dispatch how to | ||
convert a list of messages to a single message | ||
-} | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
| Dispatch (List msg) | ||
|
||
|
||
update : Msg msg -> Model -> ( Model, Cmd msg ) | ||
update msg (Model model) = | ||
case msg of | ||
{- Forward all the messages produced by handlers with multiple decoders | ||
attached to them | ||
-} | ||
Dispatch msg' -> | ||
Model model ! [ Dispatch.forward msg' ] | ||
|
||
Click -> | ||
Model { model | clickCount = model.clickCount + 1 } ! [] | ||
|
||
Focus -> | ||
Model { model | focused = True } ! [] | ||
|
||
Blur -> | ||
Model { model | focused = False } ! [] | ||
|
||
|
||
|
||
-- VIEW | ||
|
||
|
||
view : (Msg msg -> msg) -> Model -> List (Property msg) -> List (Html msg) -> Html msg | ||
view lift (Model model) props content = | ||
let | ||
{- We want to perform internal actions on these events | ||
This comment has been minimized.
Sorry, something went wrong. |
||
-} | ||
defaultListeners = | ||
[ on1 "mouseenter" (lift Focus) | ||
, on1 "mouseleave" (lift Blur) | ||
, on1 "click" (lift Click) | ||
] | ||
|
||
{- Setup the Dispatch configuration using user provided events as well as | ||
This comment has been minimized.
Sorry, something went wrong. |
||
our own internal events | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
-} | ||
config = | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
List.foldl | ||
(\prop acc -> | ||
case prop of | ||
Decoder evt d -> | ||
Dispatch.add evt Nothing d acc | ||
|
||
Any attribute -> | ||
acc | ||
) | ||
(Dispatch.setMsg (Dispatch >> lift) Dispatch.defaultConfig) | ||
(props ++ defaultListeners) | ||
|
||
{- Don't add listeners here, | ||
they are already added in the config | ||
-} | ||
attributes = | ||
List.map | ||
(\prop -> | ||
case prop of | ||
Decoder _ _ -> | ||
Nothing | ||
|
||
Any a -> | ||
Just a | ||
) | ||
props | ||
|> List.filterMap identity | ||
in | ||
button | ||
([ normal | ||
, if model.focused then | ||
focused | ||
else | ||
style [] | ||
] | ||
++ attributes | ||
++ (Dispatch.toAttributes config) | ||
) | ||
content | ||
|
||
|
||
|
||
-- STYLES | ||
|
||
|
||
normal : Attribute a | ||
normal = | ||
style | ||
[ ( "display", "inline-block" ) | ||
, ( "margin", "0 10px 0 0" ) | ||
, ( "padding", "15px 15px" ) | ||
, ( "font-size", "16px" ) | ||
, ( "line-height", "1.8" ) | ||
, ( "appearance", "none" ) | ||
, ( "box-shadow", "none" ) | ||
, ( "border-radius", "0" ) | ||
] | ||
|
||
|
||
focused : Attribute a | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
focused = | ||
style | ||
[ ( "background-color", "#b6d8e4" ) | ||
, ( "text-shadow", "-1px 1px #27496d" ) | ||
, ( "outline", "none" ) | ||
This comment has been minimized.
Sorry, something went wrong.
debois
Contributor
|
||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"version": "1.0.0", | ||
"summary": "elm-dispatch examples", | ||
"repository": "https://github.com/vipentti/elm-dispatch.git", | ||
"license": "BSD3", | ||
This comment has been minimized.
Sorry, something went wrong. |
||
"source-directories": [ | ||
".", | ||
"../src" | ||
], | ||
"exposed-modules": [], | ||
"dependencies": { | ||
"elm-lang/core": "4.0.5 <= v < 5.0.0", | ||
"elm-lang/html": "1.1.0 <= v < 2.0.0" | ||
}, | ||
"elm-version": "0.17.1 <= v < 0.18.0" | ||
} |
I can't find it again, but I'm pretty certain there was a guideline that packages should not begin with
elm-
. It's too late for elm-mdl, butdispatch
is pretty cool on its own?