📜 Items rolled up on both sides of a focus
→ good fit for dynamic choice selection: tabs, playlist, timeline...
Scroll can even focus a gap
Down or Up
from every item
Not what you were looking for? Check out alternatives
Position in a Scroll relative to its focus
import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, filled, fillMap, fillMapFlat)
import Stack exposing (topDown)
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.to (Scroll.AtSide Up 2)
|> fillMap Scroll.focusItem
--> filled 3
--: Emptiable (Stacked number_) PossiblyThe Location directly
Down|Up the focus
import Emptiable exposing (Emptiable, filled, fillMap)
import Stack exposing (onTopLay, topDown)
import Scroll exposing (Scroll, FocusGap)
import Linear exposing (Direction(..))
Scroll.only "hello"
|> Scroll.sideAlter Up
(\_ -> topDown "scrollable" [ "world" ])
|> Scroll.toEnd Up
|> Scroll.to (Down |> Scroll.nearest)
|> fillMap Scroll.focusItem
--> filled "scrollable"
--: Emptiable (Scroll String FocusGap Never) Possibly
Scroll.empty
|> Scroll.sideAlter Down
(\_ -> topDown "world" [ "scrollable" ])
|> Scroll.to (Down |> Scroll.nearest)
--> Scroll.only "world"
--> |> Scroll.sideAlter Down
--> (\_ -> Stack.only "scrollable")
--> |> filled
--: Emptiable (Scroll String FocusGap Never) Possibly
Scroll.empty
|> Scroll.sideAlter Up
(onTopLay "foo")
|> Scroll.to (Up |> Scroll.nearest)
--> filled (Scroll.only "foo")
--: Emptiable (Scroll String FocusGap Never) Possibly
nearest =
\side ->
Scroll.AtSide side 0An empty Scroll on a gap
with nothing before and after it.
It's the loneliest of all Scrolls
<>import Emptiable
Scroll.empty |> Scroll.toStack
--> Emptiable.emptyA Scroll with a single focussed item in it,
nothing Down and Up it
🍊 -> <🍊>import Stack
Scroll.only "wat" |> Scroll.focusItem
--> "wat"
Scroll.only "wat" |> Scroll.toStack
--> Stack.only "wat"The focused item
🍍 🍓 <🍊> 🍉 🍇 -> 🍊import Stack exposing (topDown)
import Linear exposing (Direction(..))
Scroll.only "hi there" |> Scroll.focusItem
--> "hi there"
Scroll.only 1
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3, 4 ])
|> Scroll.toEnd Up
|> Scroll.focusItem
--> 4The focused item or gap
🍍 🍓 <🍊> 🍉 🍇 -> 🍊
🍍 🍓 <> 🍉 🍇 -> _import Emptiable exposing (filled, fill)
Scroll.empty |> Scroll.focus
--> Emptiable.empty
Scroll.only "hi there" |> Scroll.focus |> fill
--> "hi there"focusItem is short for focus |> fill
The Stack to one side of the focus
Down
🍍←🍓) <🍊> 🍉 🍇Up
🍍 🍓 <🍊> (🍉→🍇import Emptiable exposing (Emptiable, fillMapFlat)
import Stack exposing (Stacked, topDown)
import Linear exposing (Direction(..))
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.to (Up |> Scroll.nearest)
|> fillMapFlat (Scroll.to (Up |> Scroll.nearest))
|> fillMapFlat (Scroll.side Down)
--> topDown 1 [ 0 ]
--: Emptiable (Stacked number_) Possibly
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.to (Up |> Scroll.nearest)
|> fillMapFlat (Scroll.side Up)
--> topDown 2 [ 3 ]
--: Emptiable (Stacked number_) PossiblyCounting all contained items
import Stack exposing (topDown)
import Linear exposing (Direction(..))
Scroll.only 0
|> Scroll.sideAlter Down
(\_ -> topDown -1 [ -2 ])
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.length
--> 6
Scroll.empty
|> Scroll.sideAlter Down
(\_ -> topDown -1 [ -2 ])
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.length
--> 5O(n) like Scroll.length
Try to move the focus to the item at a given Scroll.Location
Scroll.to (Down |> Scroll.nearest)🍊 <🍉> 🍇 -> <🍊> 🍉 🍇import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, filled, fillMap)
import Scroll exposing (Scroll, FocusGap)
Scroll.empty |> Scroll.to (Down |> Scroll.nearest)
--> Emptiable.empty
Scroll.only "hello"
|> Scroll.sideAlter Up
(\_ -> topDown "scrollable" [ "world" ])
|> Scroll.toEnd Up
|> Scroll.to (Down |> Scroll.nearest)
|> fillMap Scroll.focusItem
--> filled "scrollable"
--: Emptiable (Scroll String FocusGap Never) PossiblyThis also works from within gaps:
🍊 🍉 <> 🍇 -> 🍊 <🍉> 🍇import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, filled)
import Stack exposing (onTopLay)
import Scroll exposing (Scroll, FocusGap)
Scroll.empty
|> Scroll.sideAlter Down
(onTopLay "foo")
|> Scroll.to (Down |> Scroll.nearest)
--> filled (Scroll.only "foo")
--: Emptiable (Scroll String FocusGap Never) PossiblyScroll.to (Up |> Scroll.nearest)<🍊> 🍉 🍇 -> 🍊 <🍉> 🍇import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, filled, fillMap)
import Scroll exposing (Scroll, FocusGap)
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.to (Up |> Scroll.nearest)
|> fillMap Scroll.focusItem
--> filled 1
--: Emptiable number_ PossiblyThis also works from within gaps:
🍊 <> 🍉 🍇 -> 🍊 <🍉> 🍇import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, filled)
import Stack exposing (onTopLay)
import Scroll exposing (Scroll, FocusGap)
Scroll.empty
|> Scroll.sideAlter Up
(\_ -> Stack.only "foo")
|> Scroll.to (Up |> Scroll.nearest)
--> filled (Scroll.only "foo")
--: Emptiable (Scroll String FocusGap Never) PossiblyIf there is no next item, the result is empty
import Linear exposing (Direction(..))
import Emptiable
import Stack exposing (topDown)
Scroll.empty |> Scroll.to (Up |> Scroll.nearest)
--> Emptiable.empty
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.toEnd Up
|> Scroll.to (Up |> Scroll.nearest)
--> Emptiable.emptyScroll.to Locationimport Element as Ui
import Element.Input as UIn
import Emptiable exposing (fillMap)
import RecordWithoutConstructorFunction exposing (RecordWithoutConstructorFunction)
import Scroll exposing (FocusGap, Scroll)
import Stack
type alias Model =
RecordWithoutConstructorFunction
{ numbers : Scroll Int FocusGap Never
}
type Event
= NumberClicked Scroll.Location
update : Event -> Model -> ( Model, Cmd Event )
update event model =
case event of
NumberClicked location ->
( { model
| numbers =
model.numbers
|> Scroll.to location
|> Emptiable.fillElseOnEmpty (\_ -> model.numbers)
|> Scroll.focusAlter (fillMap (\n -> n + 1))
}
, Cmd.none
)
interface : Model -> Ui.Element Event
interface =
\{ numbers } ->
numbers
|> Scroll.map numberInterface
|> Scroll.toList
|> Ui.column []
numberInterface :
Scroll.Location
-> Int
-> Ui.Element Event
numberInterface location =
\number ->
UIn.button []
{ onPress = NumberClicked location |> Just
, label =
number
|> String.fromInt
|> Ui.text
}The same functionality is often provided as duplicate : Scroll item ... -> Scroll (Scroll item) ...
List.NonEmpty.Zipper.duplicateSelectList.selectedMapZipper.duplicateReference.List.unwrapSaving a Scroll with every item becomes expensive for long Scrolls, though!
Move the focus to the gap directly Down|Up.
Feel free to plug that gap right up!
Scroll.toGap Down🍍 <🍊> 🍉 -> 🍍 <> 🍊 🍉import Linear exposing (Direction(..))
import Emptiable exposing (filled)
import Stack exposing (topDown)
Scroll.only "world"
|> Scroll.toGap Down
|> Scroll.focusAlter (\_ -> "hello" |> filled)
|> Scroll.toStack
--> topDown "hello" [ "world" ]Scroll.toGap Up🍍 <🍊> 🍉 -> 🍍 🍊 <> 🍉import Linear exposing (Direction(..))
import Emptiable exposing (filled)
import Stack exposing (topDown)
Scroll.only "hello"
|> Scroll.sideAlter Up
(\_ -> Stack.only "world")
|> Scroll.toGap Up
|> Scroll.focusAlter (\_ -> filled "scrollable")
|> Scroll.toStack
--> topDown "hello" [ "scrollable", "world" ]Focus the furthest item Down/Up the focus
Down
🍍 🍓 <🍊> 🍉 -> <🍍> 🍓 🍊 🍉Up
🍓 <🍊> 🍉 🍇 -> 🍓 🍊 🍉 <🍇>import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable)
import Stack exposing (Stacked, topDown)
Scroll.only 1
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3, 4 ])
|> Scroll.sideAlter Down
(\_ -> topDown 4 [ 3, 2 ])
|> Scroll.toEnd Down
|> Scroll.focusItem
--> 2
Scroll.only 1
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3, 4 ])
|> Scroll.toEnd Up
|> Scroll.focusItem
--> 4
Scroll.only 1
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3, 4 ])
|> Scroll.toEnd Up
|> Scroll.side Down
--> topDown 3 [ 2, 1 ]
--: Emptiable (Stacked number_) PossiblyFocus the gap beyond the furthest item Down|Up.
Remember that gaps surround everything!
Down
🍍 🍓 <🍊> 🍉 -> <> 🍍 🍓 🍊 🍉Up
🍓 <🍊> 🍉 -> 🍓 🍊 🍉 <>import Linear exposing (Direction(..))
import Emptiable exposing (filled)
import Stack exposing (topDown)
Scroll.only 1
-- <1>
|> Scroll.sideAlter Up
(\_ -> topDown 3 [ 4 ])
-- <1> 3 4
|> Scroll.toGap Up
-- 1 <> 3 4
|> Scroll.focusAlter (\_ -> filled 2)
-- 1 <2> 3 4
|> Scroll.toEndGap Down
-- <> 1 2 3 4
|> Scroll.focusAlter (\_ -> filled 0)
-- <0> 1 2 3 4
|> Scroll.toStack
--> topDown 0 [ 1, 2, 3, 4 ]
Scroll.only 1
-- <1>
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3 ])
-- <1> 2 3
|> Scroll.toEndGap Up
-- 1 2 3 <>
|> Scroll.focusAlter (\_ -> filled 4)
-- 1 2 3 <4>
|> Scroll.toStack
--> topDown 1 [ 2, 3, 4 ]Move the focus to the nearest item Down|Up that matches a predicate.
If no such item was found return with Emptiable.empty
import Linear exposing (Direction(..))
import Emptiable exposing (filled, fillMap)
import Stack exposing (topDown)
import Linear exposing (Direction(..))
Scroll.only 4
|> Scroll.sideAlter Down
(\_ -> topDown 2 [ -1, 0, 3 ])
|> Scroll.toWhere ( Down, \_ item -> item < 0 )
|> Emptiable.fillMap Scroll.focusItem
--> filled -1
Scroll.only 4
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ -1, 0, 3 ])
|> Scroll.toWhere ( Up, \_ item -> item < 0 )
|> fillMap focusItem
--> filled -1
Scroll.only -4
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ -1, 0, 3 ])
|> Scroll.toWhere ( Up, \_ item -> item < 0 )
|> fillMap focusItem
--> filled -4Try to move the focus to the nearest item
Down|Up
Down
🍊 🍉 <🍓> 🍇 -> 🍊 <🍓> 🍉 🍇
🍊 🍉 <> 🍇 -> 🍊 <> 🍉 🍇Up
🍊 <🍓> 🍉 🍇 -> 🍊 🍉 <🍓> 🍇
🍊 <> 🍉 🍇 -> 🍊 🍉 <> 🍇import Linear exposing (Direction(..))
import Emptiable exposing (Emptiable, fillMapFlat)
import Scroll exposing (Scroll, FocusGap)
Scroll.only 0
|> Scroll.sideAlter Down
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.focusDrag Down
|> fillMapFlat Scroll.toStack
--> topDown 3 [ 2, 0, 1 ]
--: Emptiable (Stacked number_) Possibly
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.focusDrag Up
|> fillMapFlat Scroll.toStack
--> topDown 1 [ 0, 2, 3 ]
--: Emptiable (Stacked number_) PossiblyIf there is no nearest item, the result is empty
import Linear exposing (Direction(..))
import Emptiable
import Stack exposing (topDown)
Scroll.only 0
|> Scroll.sideAlter Up
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.focusDrag Down
--> Emptiable.empty
Scroll.only 0
|> Scroll.sideAlter Down
(\_ -> topDown 1 [ 2, 3 ])
|> Scroll.focusDrag Up
--> Emptiable.emptyEmptiable.empty if the current focussed thing is a gap,
Emptiable.filled if it's an item
import Emptiable
import Stack exposing (topDown)
import Linear exposing (Direction(..))
Scroll.only 3
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 1 ])
|> Scroll.toGap Up
|> Scroll.focusItemTry
--> Emptiable.emptyChange every item based on its current value
import Linear exposing (Direction(..))
import Stack exposing (topDown)
Scroll.only "first"
|> Scroll.sideAlter Down
(\_ -> Stack.only "zeroth")
|> Scroll.sideAlter Up
(\_ -> topDown "second" [ "third" ])
|> Scroll.map (\_ -> String.toUpper)
|> Scroll.toStack
--> topDown "ZEROTH" [ "FIRST", "SECOND", "THIRD" ]focusSidesMap allows changing the individual parts separately
Change the focus,
the sides Down and Up
using different functions
import Linear exposing (Direction(..))
import Emptiable exposing (filled, fillMap)
import Stack exposing (topDown)
Scroll.only "first"
|> Scroll.sideAlter Up
(\_ -> Stack.only "second")
|> Scroll.toGap Up
|> Scroll.focusAlter (\_ -> filled "one-and-a-halfth")
|> Scroll.focusSidesMap
{ side =
\side ->
Stack.map
(\_ item ->
String.concat
[ side |> sideToString, ": ", item ]
)
, focus =
fillMap (\item -> "focused item: " ++ item)
}
|> Scroll.toStack
--→
topDown
"before: first"
[ "focused item: one-and-a-halfth"
, "after: second"
]
sideToString =
\side ->
case side of
Down ->
"before"
Up ->
"after"map transforms every item
Reduce in a direction
import Linear exposing (Direction(..))
import Stack exposing (topDown)
Scroll.only 'e'
|> Scroll.sideAlter Down
(\_ -> topDown 'v' [ 'i', 'l' ])
|> Scroll.foldFrom "" Down String.cons
--> "live"
Scroll.only 'e'
|> Scroll.sideAlter Down
(\_ -> topDown 'v' [ 'i', 'l' ])
|> Scroll.foldFrom "" Up String.cons
--> "evil"Roll out the Scroll to both ends into a Stack:
import Linear exposing (Direction(..))
import Emptiable exposing (filled)
import Stack exposing (topDown)
Scroll.empty
|> Scroll.toStack
--> Emptiable.empty
Scroll.only 123
|> Scroll.sideAlter Up
(\_ -> Stack.only 789)
|> Scroll.toGap Up
|> Scroll.focusAlter (\_-> filled 456)
|> Scroll.toStack
--> topDown 123 [ 456, 789 ]the type information gets carried over, so
Never Scroll.FocusGap -> Stacked Never
Possibly Scroll.FocusGap -> Stacked PossiblyConverts it to a List, rolled out to both ends:
import Linear exposing (Direction(..))
import Stack
Scroll.only 456
|> Scroll.sideAlter Down
(\_ -> Stack.only 123)
|> Scroll.sideAlter Up
(\_ -> Stack.only 789)
|> Scroll.toList
--> [ 123, 456, 789 ]Only use this if you need a list in the end.
Otherwise, use toStack to preserve some information about its length
Swap the stack on the side Down the focus
with the stack on the side Up
🍓 <🍊> 🍉 🍇 <-> 🍇 🍉 <🍊> 🍓import Linear exposing (Direction(..))
import Stack exposing (topDown)
Scroll.only 1
|> Scroll.sideAlter Up
(\_ -> topDown 2 [ 3, 4 ])
|> Scroll.sideAlter Down
(\_ -> topDown 4 [ 3, 2 ])In contrast to List or stack, this can be done in O(1) time
Alter the focus – item or gap – based on its current value
Scroll.focusAlter (\_ -> 🍊 |> filled)🍊 -> 🍓 <?> 🍉 -> 🍓 <🍊> 🍉import Linear exposing (Direction(..))
import Emptiable exposing (filled, fillMap)
import Stack exposing (topDown, onTopLay)
Scroll.empty
-- <>
|> Scroll.sideAlter Down
(onTopLay "🍓")
-- "🍓" <>
|> Scroll.sideAlter Up
(onTopLay "🍉")
-- "🍓" <> "🍉"
|> Scroll.focusAlter (\_ -> "🍊" |> filled)
-- "🍓" <"🍊"> "🍉"
|> Scroll.toStack
--> topDown "🍓" [ "🍊", "🍉" ]Scroll.focusAlter (\_ -> Emptiable.empty)🍓 <?> 🍉 -> 🍓 <> 🍉import Linear exposing (Direction(..))
import Emptiable exposing (filled, fillMap)
import Stack exposing (topDown)
Scroll.only "hello"
|> Scroll.sideAlter Up
(\_ -> topDown "scrollable" [ "world" ])
|> Scroll.to (Up |> Scroll.nearest)
|> fillMap (Scroll.focusAlter (\_ -> Emptiable.empty))
|> fillMap Scroll.toList
--> filled [ "hello", "world" ]Scroll.focusAlter (?🍒 -> ?🍊)(?🍒 -> ?🍊) -> 🍓 <?🍒> 🍉 -> 🍓 <?🍊> 🍉import Linear exposing (Direction(..))
import Emptiable exposing (filled, fillMap)
import Stack exposing (topDown, onTopLay)
Scroll.empty
-- <>
|> Scroll.sideAlter Down
(onTopLay "🍓")
-- "🍓" <>
|> Scroll.sideAlter Up
(onTopLay "🍉")
-- "🍓" <> "🍉"
|> Scroll.focusAlter
(\_ -> filled "🍊")
-- "🍓" <"🍊"> "🍉"
|> Scroll.toStack
--> topDown "🍓" [ "🍊", "🍉" ]
Scroll.only "first"
|> Scroll.sideAlter Down
(\_ -> Stack.only "zeroth")
|> Scroll.sideAlter Up
(\_ -> topDown "second" [ "third" ])
|> Scroll.focusAlter (fillMap String.toUpper)
|> Scroll.toStack
--> topDown "zeroth" [ "FIRST", "second", "third" ]Look Down|Up
the focus and operate directly an the Stack you see
sideAlter Linear.Direction (\_ -> 🍒🍋)Down
🍓 <🍊> 🍉
↓
🍋 🍒 <🍊> 🍉Up
🍍 🍓 <🍊> 🍉
↓
🍍 🍓 <🍊> 🍒 🍋import Linear exposing (Direction(..))
import Emptiable
import Stack exposing (topDown)
Scroll.only "selectoo"
|> Scroll.sideAlter Down
(\_ -> topDown "earlee" [ "agua", "enutai" ])
|> Scroll.sideAlter Up
(\_ -> topDown "orangloo" [ "iquipy", "oice" ])
|> Scroll.sideAlter Up
(\_ -> Emptiable.empty)
|> Scroll.toStack
--> topDown "enutai" [ "agua", "earlee", "selectoo" ]sideAlter Linear.Direction (Stack.map ...)import Linear exposing (Direction(..))
import Stack exposing (topDown)
Scroll.only "second"
|> Scroll.sideAlter Down
(\_ -> topDown "first" [ "zeroth" ])
|> Scroll.sideAlter Down
(Stack.map (\_ -> String.toUpper))
|> Scroll.toStack
--> topDown "ZEROTH" [ "FIRST", "second" ]
Scroll.only "zeroth"
|> Scroll.sideAlter Up
(\_ -> topDown "first" [ "second" ])
|> Scroll.sideAlter Up
(Stack.map (\_ -> String.toUpper))
|> Scroll.toStack
--> topDown "zeroth" [ "FIRST", "SECOND" ]Look to one side from the focus and slide items in directly at the nearest location
sideAlter Linear.Direction (Stack.onTopGlue/onTopStack 🍒🍋)Down
🍒🍋
🍍 🍓 \↓/ <🍊> 🍉Up
🍒🍋
🍓 <🍊> \↓/ 🍉 🍇import Linear exposing (Direction(..))
import Stack exposing (topDown)
Scroll.only 0
|> Scroll.sideAlter Down
(Stack.onTopGlue [ -4, -5 ])
|> Scroll.sideAlter Down
(Stack.onTopStack (topDown -1 [ -2, -3 ]))
|> Scroll.toStack
--> topDown -5 [ -4, -3, -2, -1, 0 ]
Scroll.only 0
|> Scroll.sideAlter Up
(Stack.onTopGlue [ 4, 5 ])
|> Scroll.sideAlter Up
(Stack.onTopStack (topDown 1 [ 2, 3 ]))
|> Scroll.toStack
--> topDown 0 [ 1, 2, 3, 4, 5 ]Scroll.sideAlter Linear.Direction (\side -> 🍒🍋 |> onTopStack side)Down
🍋🍒
\↓ 🍍 🍓 <🍊> 🍉Up
🍒🍋
🍓 <🍊> 🍉 🍇 ↓/import Linear exposing (Direction(..))
import Stack exposing (topDown, onTopStack)
Scroll.only 1
|> Scroll.sideAlter Up
(\after -> topDown 2 [ 3, 4 ] |> onTopStack after)
|> Scroll.toEnd Up
|> Scroll.sideAlter Down
(\before -> topDown 7 [ 6, 5 ] |> onTopStack before)
|> Scroll.toStack
--> topDown 5 [ 6, 7, 1, 2, 3, 4 ]
Scroll.only 123
|> Scroll.sideAlter Up
(\after -> Stack.only 456 |> onTopStack after)
|> Scroll.sideAlter Up
(\after -> topDown 789 [ 0 ] |> onTopStack after)
|> Scroll.toStack
--> topDown 123 [ 456, 789, 0 ]sideAlter Linear.Direction (Stack.onTopLay ...)Down
🍒
🍍 🍓 ↓ <🍊> 🍉Up 🍒
🍓 <🍊> ↓ 🍉 🍇import Linear exposing (Direction(..))
import Stack exposing (topDown, onTopLay)
Scroll.only 123
|> Scroll.sideAlter Down
(onTopLay 456)
|> Scroll.toStack
--> topDown 456 [ 123 ]
Scroll.only 123
|> Scroll.sideAlter Up
(\_ -> Stack.only 789)
|> Scroll.sideAlter Up
(onTopLay 456)
|> Scroll.toStack
--> topDown 123 [ 456, 789 ]Change the possiblyOrNever type
A Scroll ... FocusGap possiblyOrNever
can't be used as a Scroll ... Possibly?
import Possibly exposing (Possibly(..))
Scroll.focusGapAdapt (always Possible)A Scroll ... FocusGap Never
can't be unified with Scroll ... Possibly or FocusGap possiblyOrNever?
Scroll.focusGapAdapt neverPlease read more at Emptiable.emptyAdapt
map (Location -> ...), focusDrag, toNonEmptyList, sideAlter (so no squeezing in multiple items, ...)List.NonEmpty.Zipper
complete; cluttered (for example update & map); some unintuitive namesfocusWheremap (Location -> ...)map (Location -> ...), sideAlter (so no squeezing in multiple items, ...)focusDrag, map (Location -> ...), toNonEmptyListside, ...focusDrag, toNonEmptyList, sideAlter (so no squeezing in multiple items, ...)Reference.List
only overList, sides impossible to access & alter
📜 Items rolled up on both sides of a focus
→ good fit for dynamic choice selection: tabs, playlist, ...
Scrollcan even focus a gapDownandUpevery item:🍍 🍓 <🍊> 🍉 🍇:Scroll ... FocusGap Never🍍 🍓 <?> 🍉 🍇:Scroll ...PossiblyFocusGap<?>means both are possible:🍍 🍓 <> 🍉 🍇: a gap between items ... Heh.🍍 🍓 <🍊> 🍉 🍇in arguments
in types
where
RecordWithoutConstructorFunctionstops the compiler from creating a constructor function forModel