https://github.com/etaque/elm-dialog
Modals for Elm
https://github.com/etaque/elm-dialog
Last synced: 5 months ago
JSON representation
Modals for Elm
- Host: GitHub
- URL: https://github.com/etaque/elm-dialog
- Owner: etaque
- Created: 2016-01-09T22:58:37.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2018-02-08T15:41:31.000Z (over 8 years ago)
- Last Synced: 2025-10-20T15:02:02.990Z (9 months ago)
- Language: JavaScript
- Homepage:
- Size: 128 KB
- Stars: 13
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Elm Dialog
**Deprecated**. There are better ways of showing dialog modals than the 0.16 version of this package. Rewrite in progress on [0.17](https://github.com/etaque/elm-dialog/tree/0.17) branch for a nicer, TEA-compliant version. Or just use [krisajenkins/elm-dialog](http://package.elm-lang.org/packages/krisajenkins/elm-dialog/latest), that's good stuff.
elm package install etaque/elm-dialog
A modal component for [Elm](http://elm-lang.org/). Not named `elm-modal` because it would be type-error-prone with the `model` we have everywhere in our apps!
## Features
* Optimised for the simple cases, easy to use
* Plug it once, use it from anywhere in your app (by sending a message),
* Simple view/style provided ([screenshot](https://raw.githubusercontent.com/etaque/elm-dialog/master/screenshot.png)) but can work with any css framework,
* Animation-ready: built on top of [elm-transit](http://package.elm-lang.org/packages/etaque/elm-transit/latest), so you can add open/close effects and wait until animation is ended before seing your actions triggered.
## How does it work?
It assumes that you can only have one instance at a time of an open modal, so the state can be global in the Elm way: declared once, usable from anywhere.
To avoid boilerplate in update delegation, an `Address` is exposed so this global state (ie dialog content, visibility) can be updated from anywhere in you views and updates.
A minor drawback is that the dialog content is stored as `Html` in the state, so can't be automaticaly rerendered from you app model if you need so: you have to send a task to update the dialog content.
## Usage
Don't forged to `import Dialog` in every impacted module. See [example/](./example/) for a fully working usage example.
### Model
Add the dialog instance to your model:
```elm
type alias Model = WithDialog { ... }
-- or without record extension:
type alias Model =
{ dialog : Dialog
, ...
}
```
See `getContent`, `getOptions`, `getTransition`, `isOpen` and `isVisible` for model querying. Initialize it with `dialog = Dialog.initial`.
Add a type case for the dialog actions:
```elm
type Action
= NoOp
| ...
| DialogAction Dialog.Action
```
### Update
* Add the case match for the dialog actions. If you've chosen the record extension, then you can use the `wrappedUpdate`, otherwise you should use the regular `update` function.
```elm
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
DialogAction dialogAction ->
Dialog.wrappedUpdate DialogAction dialogAction model
```
* Plug dialog signal as input into your app. With StartApp, that would be:
```elm
StartApp.Start
{ ...
, inputs = [ Signal.map DialogAction Dialog.actions ]
}
```
### View
This package provides a simple theme under `Dialog.Simple`, [here](./example/styles/simple.css)
is a default stylesheet (you can roll out your own theme if you need it).
* Plug `Simple.view` at the bottom of your top-level view. It's only a shell, hidden by default.
It will be in charge of showing up the dialog content and backdrop according to state.
```elm
view : Address Action -> Model -> Html
view addr model =
div
[ ]
[ ... -- your app view
, Dialog.Simple.view model.dialog
]
```
* Open the dialog with `openOnClick` (or `openWithOptionsOnClick` if you need more control):
```elm
-- Somewhere in your views, where you need to open a dialog
somePartOfYourView addr =
button
[ Dialog.openOnClick (dialog addr) ]
[ text "..." ]
dialog : Address Action -> Dialog.Options -> List Html
dialog addr options =
[ Dialog.header options "Are you sure?"
, Dialog.body
[ p [] [ text "Please give it a second thought." ] ]
, Dialog.footer
[ a
[ class "btn btn-default"
, Dialog.onClickHide
]
[ text "You make me doubt" ]
, a
[ class "btn btn-primary"
, Dialog.onClickHideThenSend addr SomeAction
]
[ text "FFS, go on!" ]
]
]
```
Here we're using:
* `header` as the title decorator, taking `options` as parameter: if `options.onClose` is non empty, it will display a close button
* `body` for the message of the modal
* `footer` for the actions.
Options are:
* `duration` for the fade animation, in ms
* `onClose` for the task to run when closing the modal. Set to `Nothing` to prevent closing.
### Actions
The package provide two levels to control dialog:
* The basis is `address : Address Dialog.Action` in combination with those action builders:
* `open`, `openWithOptions` to open the modal with the provided content,
* `updateContent` to update content without touching opened state
* `close`, `closeThenSend`, `closeThenDo` to close the modal and send a message/run a task.
That makes it controllable from everywhere in your app, not only views.
* Some `onClick` shortcuts are available for the views, they produce an HTML attribute:
* `openOnClick` and `openWithOptionsOnClick`
* `closeOnClick` and `closeThenSendOnClick`
## Credits
* [tg-modal](https://github.com/thorgate/tg-modal) for the simple stylesheet