git.iko.soy/rowtype-yoga/purescript-react-virtuoso
on main help sign in
Merge pull request #1 from rowtype-yoga/develop
b0297c0Mark Eibes
.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
99-------------------------------
99-------------------------------
100-}
100-}
101let upstream =
101let upstream =
102− https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220615/packages.dhall
102+ https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221031/packages.dhall
103− sha256:6b62a899c22125a2735a7c354bbb66a2fe24ff45cec0a8b8b890769a01a99210
103+ sha256:c785240aefe3d5a219843cde92fbfca404323090801e74ff7605e2618d8d14b8
104
104
105in upstream
105in upstream
spago.dhall+6
@@ -11,12 +11,18 @@ When creating a new Spago project, you can use
11to generate this file without the comments in this block.
11to generate this file without the comments in this block.
12-}
12-}
13{ name = "react-virtuoso"
13{ name = "react-virtuoso"
14+, license = "MIT"
15+, repository = "https://github.com/rowtype-yoga/purescript-react-virtuoso.git"
14, dependencies =
16, dependencies =
15 [ "effect"
17 [ "effect"
16 , "functions"
18 , "functions"
19+ , "maybe"
17 , "prelude"
20 , "prelude"
18 , "react-basic"
21 , "react-basic"
19 , "react-basic-dom"
22 , "react-basic-dom"
23+ , "react-basic-hooks"
24+ , "unsafe-coerce"
25+ , "web-html"
20 ]
26 ]
21, packages = ./packages.dhall
27, packages = ./packages.dhall
22, sources = [ "src/**/*.purs" ]
28, 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"
2export const virtuosoImpl = Virtuoso;
2export 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
2
19
3−import Data.Function.Uncurried (Fn2)
20+import Data.Function.Uncurried (Fn2, Fn3)
21+import Data.Maybe (Maybe(..))
4import Data.Unit (Unit)
22import Data.Unit (Unit)
5−import Effect.Uncurried (EffectFn1)
23+import Effect (Effect)
24+import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2)
6import Prim.Row (class Union)
25import Prim.Row (class Union)
7import React.Basic (JSX, ReactComponent)
26import React.Basic (JSX, ReactComponent)
27+import React.Basic.Hooks (ReactChildren)
28+import React.Basic as React
8import React.Basic.DOM (CSS)
29import React.Basic.DOM (CSS)
30+import Unsafe.Coerce (unsafeCoerce)
31+import Web.HTML (HTMLElement, Window)
9
32
10foreign import virtuosoImpl ∷ ∀ p. ReactComponent p
33foreign import virtuosoImpl ∷ ∀ p. ReactComponent p
11
34
12−type VirtuosoPropsWithTotalCount
35+foreign import data VirtuosoInstance :: Type
13− = ( style ∷ CSS
36+
14− , totalCount ∷ Int
37+scrollToIndex :: { smooth :: Boolean } -> Int -> VirtuosoInstance -> Effect Unit
15− , itemContent ∷ Int → JSX
38+scrollToIndex options idx inst =
16− , useWindowScroll ∷ Boolean
39+ runEffectFn2 (unsafeCoerce inst).scrollToIndex idx options
17− )
40+
18−
41+type VirtuosoProps ctx item =
19−type VirtuosoPropsWithData a
20− = ( style ∷ CSS
42+ ( style ∷ CSS
21− , data ∷ Array a
43+ , data ∷ Array item
22− , itemContent ∷ Fn2 Int a JSX
44+ , endReached ∷ EffectFn1 Int Unit
23− , useWindowScroll ∷ Boolean
45+ , initialTopMostItemIndex :: Int
46+ , alignToBottom :: Boolean
24− , endReached ∷ EffectFn1 Int Unit
47+ , atBottomStateChange :: EffectFn1 Boolean Unit
25− )
48+ , atBottomThreshold :: Int
26−
49+ , atTopStateChange :: EffectFn1 Boolean Unit
27−virtuosoWithCount ∷
50+ , atTopThreshold :: Int
28− ∀ p p_.
51+ , components :: Components ctx
29− Union p p_ VirtuosoPropsWithTotalCount ⇒
52+ -- , computeItemKey
30− ReactComponent
53+ , context :: ctx
31− { totalCount ∷ Int
54+ , customScrollParent :: HTMLElement
32− , itemContent ∷ Int → JSX
55+ , defaultItemHeight :: Number
33− | p
56+ , endReached :: EffectFn1 Int Unit
34− }
57+ , firstItemIndex :: Int
35−virtuosoWithCount = virtuosoImpl
58+ , fixedItemHeight :: Number
36−
59+ , followOutput :: FollowOutput
37−virtuosoWithData ∷
60+ , headerFooterTag :: String
38− ∀ item p p_.
61+ , increaseViewportBy :: { bottom :: Number, top :: Number }
39− Union p p_ (VirtuosoPropsWithData item) ⇒
62+ , initialItemCount :: Int
40− ReactComponent
63+ , initialScrollTop :: Number
41− { data ∷ Array item
64+ -- , initialTopMostItemIndex::
42− , itemContent ∷ Fn2 Int item JSX
65+ , isScrolling :: EffectFn1 Boolean Unit
43− | p
66+ , itemContent ∷ Fn3 Int item ctx JSX
44− }
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+ }
45−virtuosoWithData = virtuosoImpl
133+virtuoso = virtuosoImpl