Skip to content

Commit

Permalink
Parameterize the type of the draggable element's key.
Browse files Browse the repository at this point in the history
  • Loading branch information
crazymykl committed Feb 9, 2017
1 parent 4f95d15 commit 078c555
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 83 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ import Draggable
#### 2. Define your model
Include:
- The element's position.
- The internal `Drag` state. Note that, for simplicity, the model entry holding this state **must** be called `drag`, since the update function below follows this naming convention. A future update could allow using custom field names.
- The internal `Drag` state. Note that, for simplicity, the model entry holding this state **must** be called `drag`, since the update function below follows this naming convention. A future update could allow using custom field names. Please note that for the sake of example, we are specifying `String` as the type to tag draggable elements with. If you only have one such element, `()` might be a better type.
```elm
type alias Model =
{ position : ( Int, Int )
, drag : Draggable.State
, drag : Draggable.State String
}
```

Expand All @@ -57,13 +57,13 @@ initModel =
```elm
type Msg
= OnDragBy Draggable.Delta
| DragMsg Draggable.Msg
| DragMsg (Draggable.Msg String)
```

#### 5. Setup the config used when updating the `Drag` state
For the simplest case, you only have to provide a handler for `onDragBy`:
```elm
dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config String Msg
dragConfig =
Draggable.basicConfig OnDragBy
```
Expand Down Expand Up @@ -94,7 +94,7 @@ subscriptions { drag } =
```

#### 8. Triggering drag
Finally, inside your `view` function, you must somehow make the element draggable. You do that by adding a trigger for the `mousedown` event. You must also specify a `String` `key` for that element. This is useful when there are multiple drag targets in the same view.
Finally, inside your `view` function, you must somehow make the element draggable. You do that by adding a trigger for the `mousedown` event. You must also specify a `key` for that element. This is useful when there are multiple drag targets in the same view.

Of course, you'll also have to style your DOM element such that it reflects its moving position (with `top: x; left: y` or [`transform: translate`](http://www.w3schools.com/css/css3_2dtransforms.asp))
```elm
Expand Down Expand Up @@ -128,7 +128,7 @@ All of these events are optional, and can be provided to `Draggable.customConfig
import Draggable
import Draggable.Events exposing (onClick, onDragBy, onDragEnd, onDragStart, onMouseDown)

dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config String Msg
dragConfig =
Draggable.customConfig
[ onDragStart OnDragStart
Expand Down
8 changes: 4 additions & 4 deletions examples/BasicExample.elm
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ type alias Position =

type alias Model =
{ xy : Position
, drag : Draggable.State
, drag : Draggable.State ()
}


type Msg
= OnDragBy Draggable.Delta
| DragMsg Draggable.Msg
| DragMsg (Draggable.Msg ())


main : Program Never Model Msg
Expand All @@ -39,7 +39,7 @@ init =
)


dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config () Msg
dragConfig =
Draggable.basicConfig OnDragBy

Expand Down Expand Up @@ -77,7 +77,7 @@ view { xy } =
in
Html.div
[ A.style style
, Draggable.mouseTrigger "" DragMsg
, Draggable.mouseTrigger () DragMsg
]
[ Html.text "Drag me" ]

Expand Down
6 changes: 3 additions & 3 deletions examples/ConstraintsExample.elm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type alias Position =

type alias Model =
{ position : Position
, drag : Draggable.State
, drag : Draggable.State String
, dragHorizontally : Bool
, dragVertically : Bool
, isDragging : Bool
Expand All @@ -36,7 +36,7 @@ type alias Model =

type Msg
= NoOp
| DragMsg Draggable.Msg
| DragMsg (Draggable.Msg String)
| OnDragBy Draggable.Delta
| SetDragHorizontally Bool
| SetDragVertically Bool
Expand All @@ -55,7 +55,7 @@ init =
)


dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config String Msg
dragConfig =
Draggable.customConfig
[ onDragBy (OnDragBy)
Expand Down
6 changes: 3 additions & 3 deletions examples/CustomEventsExample.elm
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type alias Model =
, clicksCount : Int
, isDragging : Bool
, isClicked : Bool
, drag : Draggable.State
, drag : Draggable.State String
}


Expand All @@ -28,7 +28,7 @@ type Msg
| OnDragEnd
| CountClick
| SetClicked Bool
| DragMsg Draggable.Msg
| DragMsg (Draggable.Msg String)


main : Program Never Model Msg
Expand All @@ -53,7 +53,7 @@ init =
)


dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config String Msg
dragConfig =
Draggable.customConfig
[ onDragStart (\_ -> OnDragStart)
Expand Down
6 changes: 3 additions & 3 deletions examples/MultipleTargetsExample.elm
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ toggleBoxClicked id group =

type alias Model =
{ boxGroup : BoxGroup
, drag : Draggable.State
, drag : Draggable.State Id
}


type Msg
= DragMsg Draggable.Msg
= DragMsg (Draggable.Msg Id)
| OnDragBy Vec2
| StartDragging String
| ToggleBoxClicked String
Expand All @@ -150,7 +150,7 @@ init =
)


dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config Id Msg
dragConfig =
Draggable.customConfig
[ onDragBy (Vector2.fromTuple >> OnDragBy)
Expand Down
8 changes: 4 additions & 4 deletions examples/PanAndZoomExample.elm
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ type alias Model =
{ zoom : Float
, center : Vec2
, size : Size Float
, drag : Draggable.State
, drag : Draggable.State ()
}


type Msg
= DragMsg Draggable.Msg
= DragMsg (Draggable.Msg ())
| OnDragBy Vec2
| Zoom Float

Expand All @@ -51,7 +51,7 @@ init =
)


dragConfig : Draggable.Config Msg
dragConfig : Draggable.Config () Msg
dragConfig =
Draggable.basicConfig (OnDragBy << Vector2.fromTuple)

Expand Down Expand Up @@ -107,7 +107,7 @@ view { center, size, zoom } =
[ num Attr.width size.width
, num Attr.height size.height
, handleZoom Zoom
, Draggable.mouseTrigger "" DragMsg
, Draggable.mouseTrigger () DragMsg
]
[ background
, Svg.g
Expand Down
38 changes: 19 additions & 19 deletions src/Draggable.elm
Original file line number Diff line number Diff line change
Expand Up @@ -53,36 +53,36 @@ type alias Delta =

{-| Drag state to be included in model.
-}
type State
= State Internal.State
type State a
= State (Internal.State a)


{-| A message type for updating the internal drag state.
-}
type Msg
= Msg Internal.Msg
type Msg a
= Msg (Internal.Msg a)


{-| An event declaration for the draggable config
-}
type alias Event msg =
Internal.Event msg
type alias Event a msg =
Internal.Event a msg


{-| Initial drag state
-}
init : State
init : State a
init =
State Internal.NotDragging


{-| Handle update messages for the draggable model. It assumes that the drag state will be stored under the key `drag`.
-}
update :
Config msg
-> Msg
-> { m | drag : State }
-> ( { m | drag : State }, Cmd msg )
Config a msg
-> Msg a
-> { m | drag : State a }
-> ( { m | drag : State a }, Cmd msg )
update config msg model =
let
( dragState, dragCmd ) =
Expand All @@ -91,7 +91,7 @@ update config msg model =
{ model | drag = dragState } ! [ dragCmd ]


updateDraggable : Config msg -> Msg -> State -> ( State, Cmd msg )
updateDraggable : Config a msg -> Msg a -> State a -> ( State a, Cmd msg )
updateDraggable (Config config) (Msg msg) (State drag) =
let
( newDrag, newMsgMaybe ) =
Expand All @@ -102,7 +102,7 @@ updateDraggable (Config config) (Msg msg) (State drag) =

{-| Handle mouse subscriptions used for dragging
-}
subscriptions : (Msg -> msg) -> State -> Sub msg
subscriptions : (Msg a -> msg) -> State a -> Sub msg
subscriptions envelope (State drag) =
case drag of
Internal.NotDragging ->
Expand All @@ -114,11 +114,11 @@ subscriptions envelope (State drag) =
|> Sub.map (envelope << Msg)


{-| DOM event handler to start dragging on mouse down. It requires a `String` key for the element, in order to provide support for multiple drag targets sharing the same drag state. Of course, if only one element is draggable, it can have any value, including `""`.
{-| DOM event handler to start dragging on mouse down. It requires a key for the element, in order to provide support for multiple drag targets sharing the same drag state. Of course, if only one element is draggable, it can have any value, including `()`.
div [ mouseTrigger "element-id" DragMsg ] [ text "Drag me" ]
-}
mouseTrigger : String -> (Msg -> msg) -> VirtualDom.Property msg
mouseTrigger : a -> (Msg a -> msg) -> VirtualDom.Property msg
mouseTrigger key envelope =
let
ignoreDefaults =
Expand Down Expand Up @@ -153,15 +153,15 @@ whenLeftMouseButtonPressed decoder =

{-| Configuration of a draggable model.
-}
type Config msg
= Config (Internal.Config msg)
type Config a msg
= Config (Internal.Config a msg)


{-| Basic config
config = basicConfig OnDragBy
-}
basicConfig : (Delta -> msg) -> Config msg
basicConfig : (Delta -> msg) -> Config a msg
basicConfig onDragByListener =
let
defaultConfig =
Expand All @@ -178,6 +178,6 @@ basicConfig onDragByListener =
, onDragEnd OnDragEnd
]
-}
customConfig : List (Event msg) -> Config msg
customConfig : List (Event a msg) -> Config a msg
customConfig events =
Config <| List.foldl (<|) Internal.defaultConfig events
20 changes: 6 additions & 14 deletions src/Draggable/Events.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,27 @@ module Draggable.Events
, onDragEnd
, onClick
, onMouseDown
, Key
)

{-| Listeners for the various events involved in dragging (`onDragBy`, `onDragStart`, etc.). Also handles `click` events when the mouse was not moved.
@docs onDragStart, onDragEnd, onDragBy
@docs onClick, onMouseDown
@docs Key
-}

import Internal exposing (Config, Delta)
import Draggable exposing (Event)


{-| Type representing a key used for targeting draggable elements.
-}
type alias Key =
String


{-| Register a `DragStart` event listener. It will not trigger if the mouse has not moved while it was pressed. It receives the element key.
-}
onDragStart : (Key -> msg) -> Event msg
onDragStart : (a -> msg) -> Event a msg
onDragStart toMsg config =
{ config | onDragStart = Just << toMsg }


{-| Register a `DragEnd` event listener. It will not trigger if the mouse has not moved while it was pressed.
-}
onDragEnd : msg -> Event msg
onDragEnd : msg -> Event a msg
onDragEnd toMsg config =
{ config | onDragEnd = Just toMsg }

Expand All @@ -44,20 +36,20 @@ onDragEnd toMsg config =
OnDragBy (dx, dy) ->
{ model | position = { x = position.x + dx, y = position.y + dy } }
-}
onDragBy : (Delta -> msg) -> Event msg
onDragBy : (Delta -> msg) -> Event a msg
onDragBy toMsg config =
{ config | onDragBy = Just << toMsg }


{-| Register a `Click` event listener. It will trigger if the mouse is pressed and immediately release, without any move. It receives the element key.
-}
onClick : (Key -> msg) -> Event msg
onClick : (a -> msg) -> Event a msg
onClick toMsg config =
{ config | onClick = Just << toMsg }


{-| Register a `MouseDown` event listener. It will trigger whenever the mouse is pressed and will indicate the target element by the given `String` key.
{-| Register a `MouseDown` event listener. It will trigger whenever the mouse is pressed and will indicate the target element by the given key.
-}
onMouseDown : (Key -> msg) -> Event msg
onMouseDown : (a -> msg) -> Event a msg
onMouseDown toMsg config =
{ config | onMouseDown = Just << toMsg }
Loading

0 comments on commit 078c555

Please sign in to comment.