Filter scroll events.

This commit is contained in:
Søren Debois 2016-03-30 21:19:06 +02:00
parent 6f5cf34c67
commit ea55905016
3 changed files with 68 additions and 19 deletions

View file

@ -13,7 +13,6 @@ import Material.Layout as Layout exposing (defaultLayoutModel)
import Material exposing (lift, lift') import Material exposing (lift, lift')
import Material.Style as Style import Material.Style as Style
import Material.Icon as Icon
import Material import Material
import Demo.Buttons import Demo.Buttons
@ -25,8 +24,6 @@ import Demo.Badges
-- MODEL -- MODEL
x = 0 + "foo"
layoutModel : Layout.Model layoutModel : Layout.Model
layoutModel = layoutModel =
@ -196,7 +193,7 @@ init = (model, Effects.none)
inputs : List (Signal.Signal Action) inputs : List (Signal.Signal Action)
inputs = inputs =
[ Layout.setupSizeChangeSignal LayoutAction [ Layout.setupSignals LayoutAction
] ]

View file

@ -3,6 +3,8 @@ module Demo.Grid where
import Material.Grid exposing (..) import Material.Grid exposing (..)
import Material.Style exposing (Style, css) import Material.Style exposing (Style, css)
import Markdown
import Html exposing (..) import Html exposing (..)
-- Cell styling -- Cell styling
@ -50,3 +52,36 @@ view =
] ]
intro : Html
intro = """
From the
[Material Design Lite documentation](http://www.getmdl.io/components/#layout-section/grid):
> The Material Design Lite (MDL) grid component is a simplified method for laying
> out content for multiple screen sizes. It reduces the usual coding burden
> required to correctly display blocks of content in a variety of display
> conditions.
>
> The MDL grid is defined and enclosed by a container element. A grid has 12
> columns in the desktop screen size, 8 in the tablet size, and 4 in the phone
> size, each size having predefined margins and gutters. Cells are laid out
> sequentially in a row, in the order they are defined, with some exceptions:
>
> - If a cell doesn't fit in the row in one of the screen sizes, it flows
> into the following line.
> - If a cell has a specified column size equal to or larger than the number
> of columns for the current screen size, it takes up the entirety of its
> row.
#### See also
- [Demo source code](https://github.com/debois/elm-mdl/blob/master/examples/Demo/Grid.elm)
- [elm-mdl package documentation](http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Grid)
- [Material Design Specification](https://www.google.com/design/spec/layout/responsive-ui.html#responsive-ui-grid)
- [Material Design Lite documentation](http://www.getmdl.io/components/#layout-section/grid)
#### Demo
""" |> Markdown.toHtml

View file

@ -1,5 +1,5 @@
module Material.Layout module Material.Layout
( setupSizeChangeSignal ( setupSignals
, Mode(..), Model, defaultLayoutModel, initState , Mode(..), Model, defaultLayoutModel, initState
, Action(SwitchTab, ToggleDrawer), update , Action(SwitchTab, ToggleDrawer), update
, row, spacer, title, navigation, link , row, spacer, title, navigation, link
@ -39,7 +39,7 @@ module Material.Layout
@docs row, spacer, title, navigation, link @docs row, spacer, title, navigation, link
# Setup # Setup
@docs setupSizeChangeSignal @docs setupSignals
-} -}
@ -63,21 +63,38 @@ import DOM
-- SETUP -- SETUP
{-| Setup signal for registering changes in display size. Use with StartApp scrollMailbox : Signal.Mailbox Float
like so, supposing you have a `LayoutAction` encapsulating actions of the scrollMailbox = Signal.mailbox 0.0
{-| Setup various signals layout needs (viewport size changes, scrolling). Use
with StartApp like so, supposing you have a `LayoutAction` encapsulating
actions of the
layout: layout:
inputs : List (Signal.Signal Action) inputs : List (Signal.Signal Action)
inputs = inputs =
[ Layout.setupSizeChangeSignal LayoutAction [ Layout.setupSignals LayoutAction
] ]
-} -}
setupSizeChangeSignal : (Action -> a) -> Signal a setupSignals : (Action -> a) -> Signal a
setupSizeChangeSignal f = setupSignals f =
Window.width {- NB! mergeMany propagates only the first provided signal if more than one
signal changes value at the same time. We are processing two signals: (1)
viewport size changes and (2) scrolling of main contents. It /appears/
that these cannot happen at the same time, so the following should be
safe.
-}
Signal.mergeMany
[ Window.width
|> Signal.map ((>) 1024) |> Signal.map ((>) 1024)
|> Signal.dropRepeats |> Signal.dropRepeats
|> Signal.map (SmallScreen >> f) |> Signal.map (SmallScreen >> f)
, scrollMailbox.signal
|> Signal.map ((<) 0.0)
|> Signal.dropRepeats
|> Signal.map (ScrollContents >> f)
]
-- MODEL -- MODEL
@ -172,7 +189,7 @@ type Action
-- Private -- Private
| SmallScreen Bool -- True means small screen | SmallScreen Bool -- True means small screen
| ScrollTab Float | ScrollTab Float
| ScrollContents Float | ScrollContents Bool -- True means strictly positive scrollTop
| Ripple Int Ripple.Action | Ripple Int Ripple.Action
| Click | Click
| TransitionEnd | TransitionEnd
@ -214,12 +231,12 @@ update action model =
(model, Effects.none) -- TODO (model, Effects.none) -- TODO
ScrollContents scrollTop -> ScrollContents isScrolled ->
let let
headerVisible = state.isSmallScreen || model.fixedHeader headerVisible = state.isSmallScreen || model.fixedHeader
state' = state' =
{ state { state
| isCompact = scrollTop > 0 | isCompact = isScrolled
, isAnimating = headerVisible , isAnimating = headerVisible
} }
in in
@ -505,7 +522,7 @@ view addr model { drawer, header, tabs, main } =
( class "mdl-layout__content" ( class "mdl-layout__content"
:: ( :: (
if isWaterfall model.mode then if isWaterfall model.mode then
[ on "scroll" (DOM.target DOM.scrollTop) (ScrollContents >> Signal.message addr) ] [ on "scroll" (DOM.target DOM.scrollTop) (Signal.message scrollMailbox.address) ]
else else
[] []
) )