git.iko.soy/rowtype-yoga/purescript-react-virtuoso
on main help sign in
Merge pull request #1 from rowtype-yoga/develop

Develop

commitb0297c06073c45845f2e5e93ed4c7b4b8576431d authorMark Eibes <mark.eibes@gmail.com> dateTue 1 Nov 2022, 20:47 (4 years ago) parent5be142ccc216f7
6 files changed+152−40
.vscode/settings.json+3 LICENCE+9 packages.dhall+2−2 spago.dhall+6 src/React/Virtuoso.js+7−1 src/React/Virtuoso.purs+125−37
.vscode/settings.jsonnew file+3
@@ -0,0 +1,3 @@
1+{
2+ "editor.formatOnSave": true
3+}
LICENCEnew file+9
@@ -0,0 +1,9 @@
1+Copyright 2022 Mark Eibes
2+
3+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8+
9+
packages.dhall+2−2
@@ -99,7 +99,7 @@ in upstream
9999-------------------------------
100100-}
101101let upstream =
102− https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220615/packages.dhall
103− sha256:6b62a899c22125a2735a7c354bbb66a2fe24ff45cec0a8b8b890769a01a99210
102+ https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221031/packages.dhall
103+ sha256:c785240aefe3d5a219843cde92fbfca404323090801e74ff7605e2618d8d14b8
104104
105105in upstream
spago.dhall+6
@@ -11,12 +11,18 @@ When creating a new Spago project, you can use
1111to generate this file without the comments in this block.
1212-}
1313{ name = "react-virtuoso"
14+, license = "MIT"
15+, repository = "https://github.com/rowtype-yoga/purescript-react-virtuoso.git"
1416, dependencies =
1517 [ "effect"
1618 , "functions"
19+ , "maybe"
1720 , "prelude"
1821 , "react-basic"
1922 , "react-basic-dom"
23+ , "react-basic-hooks"
24+ , "unsafe-coerce"
25+ , "web-html"
2026 ]
2127, packages = ./packages.dhall
2228, sources = [ "src/**/*.purs" ]
src/React/Virtuoso.js+7−1
@@ -1,2 +1,8 @@
1−import {Virtuoso} from "react-virtuoso"
1+import { Virtuoso } from "react-virtuoso"
22export const virtuosoImpl = Virtuoso;
3+
4+export const scrollerRefToWindowImpl = just => nothing => ref => () =>
5+ (ref instanceof Window) ? just(ref) : nothing
6+
7+export const scrollerRefToHTMLElementImpl = just => nothing => ref => () =>
8+ (ref instanceof HTMLElement) ? just(ref) : nothing
src/React/Virtuoso.purs+125−37
@@ -1,45 +1,133 @@
1−module React.Virtuoso (virtuosoImpl, virtuosoWithData, virtuosoWithCount) where
1+module React.Virtuoso
2+ ( Components
3+ , FollowOutput
4+ , ListRange
5+ , ScrollSeekConfiguration
6+ , ScrollerRef
7+ , VirtuosoInstance
8+ , components
9+ , followOutputAuto
10+ , followOutputFalse
11+ , followOutputSmooth
12+ , followOutputTrue
13+ , scrollToIndex
14+ , scrollerRefToHTMLElement
15+ , scrollerRefToWindow
16+ , virtuoso
17+ , virtuosoImpl
18+ ) where
219
3−import Data.Function.Uncurried (Fn2)
20+import Data.Function.Uncurried (Fn2, Fn3)
21+import Data.Maybe (Maybe(..))
422import Data.Unit (Unit)
5−import Effect.Uncurried (EffectFn1)
23+import Effect (Effect)
24+import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2)
625import Prim.Row (class Union)
726import React.Basic (JSX, ReactComponent)
27+import React.Basic.Hooks (ReactChildren)
28+import React.Basic as React
829import React.Basic.DOM (CSS)
30+import Unsafe.Coerce (unsafeCoerce)
31+import Web.HTML (HTMLElement, Window)
932
1033foreign import virtuosoImpl ∷ ∀ p. ReactComponent p
1134
12−type VirtuosoPropsWithTotalCount
13− = ( style ∷ CSS
14− , totalCount ∷ Int
15− , itemContent ∷ Int → JSX
16− , useWindowScroll ∷ Boolean
17− )
18−
19−type VirtuosoPropsWithData a
20− = ( style ∷ CSS
21− , data ∷ Array a
22− , itemContent ∷ Fn2 Int a JSX
23− , useWindowScroll ∷ Boolean
24− , endReached ∷ EffectFn1 Int Unit
25− )
26−
27−virtuosoWithCount ∷
28− ∀ p p_.
29− Union p p_ VirtuosoPropsWithTotalCount ⇒
30− ReactComponent
31− { totalCount ∷ Int
32− , itemContent ∷ Int → JSX
33− | p
34− }
35−virtuosoWithCount = virtuosoImpl
36−
37−virtuosoWithData ∷
38− ∀ item p p_.
39− Union p p_ (VirtuosoPropsWithData item) ⇒
40− ReactComponent
41− { data ∷ Array item
42− , itemContent ∷ Fn2 Int item JSX
43− | p
44− }
45−virtuosoWithData = virtuosoImpl
35+foreign import data VirtuosoInstance :: Type
36+
37+scrollToIndex :: { smooth :: Boolean } -> Int -> VirtuosoInstance -> Effect Unit
38+scrollToIndex options idx inst =
39+ runEffectFn2 (unsafeCoerce inst).scrollToIndex idx options
40+
41+type VirtuosoProps ctx item =
42+ ( style ∷ CSS
43+ , data ∷ Array item
44+ , endReached ∷ EffectFn1 Int Unit
45+ , initialTopMostItemIndex :: Int
46+ , alignToBottom :: Boolean
47+ , atBottomStateChange :: EffectFn1 Boolean Unit
48+ , atBottomThreshold :: Int
49+ , atTopStateChange :: EffectFn1 Boolean Unit
50+ , atTopThreshold :: Int
51+ , components :: Components ctx
52+ -- , computeItemKey
53+ , context :: ctx
54+ , customScrollParent :: HTMLElement
55+ , defaultItemHeight :: Number
56+ , endReached :: EffectFn1 Int Unit
57+ , firstItemIndex :: Int
58+ , fixedItemHeight :: Number
59+ , followOutput :: FollowOutput
60+ , headerFooterTag :: String
61+ , increaseViewportBy :: { bottom :: Number, top :: Number }
62+ , initialItemCount :: Int
63+ , initialScrollTop :: Number
64+ -- , initialTopMostItemIndex::
65+ , isScrolling :: EffectFn1 Boolean Unit
66+ , itemContent ∷ Fn3 Int item ctx JSX
67+ , itemSize ∷ EffectFn2 HTMLElement String Number
68+ , itemsRendered :: EffectFn1 (Array { data :: item }) Unit
69+ , overscan :: { main :: Number, reverse :: Number }
70+ , rangeChanged :: EffectFn1 ListRange Unit
71+ , scrollSeekConfiguration :: ScrollSeekConfiguration
72+ , scrollerRef :: EffectFn1 ScrollerRef Unit
73+ , startReached :: EffectFn1 Int Unit
74+ , topItemCount :: Int
75+ , totalCount :: Int
76+ , totalListHeightChanged :: EffectFn1 Number Unit
77+ , useWindowScroll ∷ Boolean
78+ )
79+
80+foreign import data Components :: Type -> Type
81+
82+type AllComponents ctx =
83+ ( "EmptyPlaceholder" :: ReactComponent { context :: ctx }
84+ , "Footer" :: ReactComponent { context :: ctx }
85+ , "Group" :: ReactComponent { style :: CSS, children :: ReactChildren JSX, context :: ctx }
86+ , "Header" :: ReactComponent { context :: ctx }
87+ , "Item" :: ReactComponent { context :: ctx }
88+ )
89+
90+components :: forall ctx r r_. Union r r_ (AllComponents ctx) => { | r } -> Components ctx
91+components = unsafeCoerce
92+
93+type ScrollSeekConfiguration =
94+ { change :: EffectFn2 Number ListRange Unit
95+ , enter :: EffectFn2 Number ListRange Boolean
96+ , exit :: EffectFn2 Number ListRange Boolean
97+ }
98+
99+foreign import data ScrollerRef :: Type
100+foreign import scrollerRefToWindowImpl :: forall a. (a -> Maybe a) -> (Maybe a) -> ScrollerRef -> Effect (Maybe Window)
101+
102+scrollerRefToWindow ∷ ScrollerRef → Effect (Maybe Window)
103+scrollerRefToWindow = scrollerRefToWindowImpl Just Nothing
104+
105+foreign import scrollerRefToHTMLElementImpl :: forall a. (a -> Maybe a) -> (Maybe a) -> ScrollerRef -> Effect (Maybe HTMLElement)
106+
107+scrollerRefToHTMLElement ∷ ScrollerRef → Effect (Maybe Window)
108+scrollerRefToHTMLElement = scrollerRefToWindowImpl Just Nothing
109+
110+type ListRange = { startIndex :: Int, endIndex :: Int }
111+
112+foreign import data FollowOutput :: Type
113+
114+followOutputTrue :: FollowOutput
115+followOutputTrue = unsafeCoerce true
116+
117+followOutputFalse :: FollowOutput
118+followOutputFalse = unsafeCoerce false
119+
120+followOutputSmooth :: FollowOutput
121+followOutputSmooth = unsafeCoerce "smooth"
122+
123+followOutputAuto :: FollowOutput
124+followOutputAuto = unsafeCoerce "auto"
125+
126+virtuoso
127+ ∷ ∀ item ctx p p_
128+ . Union p p_ (VirtuosoProps ctx item)
129+ ⇒ ReactComponent
130+ { data ∷ Array item
131+ | p
132+ }
133+virtuoso = virtuosoImpl