Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dwayne/elm-rater
A reusable rater for Elm.
https://github.com/dwayne/elm-rater
elm rater star-rating
Last synced: 2 months ago
JSON representation
A reusable rater for Elm.
- Host: GitHub
- URL: https://github.com/dwayne/elm-rater
- Owner: dwayne
- License: mit
- Created: 2019-10-04T19:22:07.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-12-10T09:45:14.000Z (about 4 years ago)
- Last Synced: 2024-08-02T01:25:59.740Z (5 months ago)
- Topics: elm, rater, star-rating
- Language: Elm
- Homepage: https://dwayne.github.io/elm-rater/
- Size: 299 KB
- Stars: 13
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Elm Rater - [Live Demo](https://dwayne.github.io/elm-rater/)
A reusable rater for Elm.
[![A screenshot of example raters](/screenshot.png)](https://dwayne.github.io/elm-rater/)
## Usage
```elm
import Rater
import Rater.Rating as Rating exposing (Rating)
```### Read Only and Disabled
```elm
type alias Model =
{ rating : Rating }init =
{ rating = Rating.outOf5 3 }view { rating } =
div []
[ Rater.viewReadOnly rating
, Rater.viewDisabled rating
]
```### Simple
Supports:
- click to change
```elm
type alias Model =
{ rating : Rating }init =
{ rating = Rating.outOf5 3 }type Msg
= ChangedRating Ratingupdate msg model =
case msg of
ChangedRating newRating ->
{ model | rating = newRating }view { rating } =
div []
[ Rater.viewSimple ChangedRating rating ]
```### Clearable
Supports:
- click to change
- click to clear```elm
type alias Model =
{ rating : Rating }init =
{ rating = Rating.outOf5 3 }type Msg
= ChangedRating Rating
| ClearedRatingupdate msg model =
case msg of
ChangedRating newRating ->
{ model | rating = newRating }ClearedRating ->
{ model | rating = Rating.zero model.rating }view { rating } =
div []
[ Rater.viewClearable ChangedRating ClearedRating rating ]
```### Hoverable
Supports:
- click to change
- click to clear
- mouse over
- mouse out```elm
type alias Model =
{ rating : Rating
, rater : Rater.State
, transientValue : Maybe Int
}init =
{ rating = Rating.outOf5 3
, rater = Rater.init
, transientValue = Nothing
}type Msg
= ChangedRating Rating
| ClearedRating
| HoveredOverRater Rater.State Int
| LeftRater Rater.Stateupdate msg model =
case msg of
ChangedRating newRating ->
{ model | rating = newRating }ClearedRating ->
{ model | rating = Rating.zero model.rating }HoveredOverRater state newTransientValue ->
{ model | rater = state, transientValue = Just newTransientValue }LeftRater state ->
{ model | rater = state, transientValue = Nothing }view { rating, rater } =
div []
[ Rater.viewHoverable
-- options
{ onChange = ChangedRating
, onClear = Just ClearedRating
, onHover = HoveredOverRater
, onLeave = LeftRater
}
-- view state
rater
-- data
rating
, case transientValue of
Nothing ->
text "Hover over the rater to see this value change."Just value ->
text <| String.fromInt value
]
```### Custom
Customize the presets using one of the functions:
- `viewCustomReadOnly`
- `viewCustomDisabled`
- `viewCustomSimple`
- `viewCustomClearable`
- `viewCustomHoverable`For e.g. suppose you wanted these features for your rater:
- click to change
- no click to clear
- mouse over
- mouse out
- hearts instead of starsThen, you could use `viewCustomHoverable`.
```elm
type alias Model =
{ rating : Rating
, rater : Rater.State
}init =
{ rating = Rating.outOf5 3
, rater = Rater.init
}type Msg
= ChangedRating Rating
| HoveredOverRater Rater.State Int
| LeftRater Rater.Stateupdate msg model =
case msg of
ChangedRating newRating ->
{ model | rating = newRating }HoveredOverRater state _ ->
{ model | rater = state }LeftRater state ->
{ model | rater = state }view { rating, rater } =
div []
[ Rater.viewCustomHoverable
-- options
{ orientation = Rater.horizontal
, symbols =
Rater.sameSymbols <|
\value ->
span
[ class "elm-rater__heart"
, title <| String.fromInt value
]
[ text "\u{2764}" ]
, onChange = ChangedRating
, onClear = Nothing
, onHover = HoveredOverRater
, onLeave = LeftRater
}
-- view state
rater
-- data
rating
]
```### Very Custom
For unadulterated customization check out the `Rater.customConfig` and
`Rater.view` functions.## API Design Principles
These are some of the design principles I tried to put into practice.
### Single source of truth
The `Rater.Rating` type is a data structure that represents a rating. You pass
it to the various view functions provided by this library in order for it to be
presented on the page. However, **you maintain ownership of the value**.*Check out the **You own the rating** example from the [demo](https://dwayne.github.io/elm-rater/).*
### Simple by default
It's designed to have a **smooth learning curve**. You can start by using the
simple functions and as your needs get more demanding you can switch to using
the more complex functions.### Separate view state from the data
When you need support for hovering you will need to start using view state. The
view state, of type `Rater.State`, is a value that gets passed around in order
to keep track of what your mouse is currently over.The view state is kept completely separate from the data.
Why?
Because the view state is only necessary to make the view work when hovering is
enabled. It's not needed otherwise. If you choose to present the rating
differently then you might not need view state or you may need a different type
of view state. In any case, **view state** is
**state you keep that is highly specific to the way you choose to present your data**.
It must **never mix with your data**.### No custom `Msg` type
The views return `Html msg` and there is no need for an update function. The way
you end up using the library is similar to how you'd use `Html.input`. You
provide `msg` builders that wrap the values that need to be communicated.```elm
Rater.viewCustomClearable
: { orientation : ...
, symbols : ...
, onChange : Rating -> msg
, onClear : msg
}
-> Rating
-> Html msgRater.viewCustomClearable
-- options
{ orientation = ...
, symbols = ...
, onChange = ChangedRating
, onClear = ClearedRating
}
-- data
ratingChangedRating : Rating -> Msg
ClearedRating : Msg
```### BEM
Use [BEM](https://dev.to/dwayne/my-notes-on-bem-4dni) to give the CSS a solid
structure.Well structured HTML and CSS combined with Elm leads to bliss.
## Credits
Even though
[evancz/elm-sortable-table](https://github.com/evancz/elm-sortable-table)
is **DEPRECATED** it still has tremendous value for learning how to write
reusable views.