A little autosuggest

This commit is contained in:
Mark Eibes 2020-12-24 23:34:49 +01:00
parent ceb1671f1f
commit 55a6f6fc66
7 changed files with 552 additions and 522 deletions

View File

@ -4,6 +4,7 @@ import Yoga.Prelude.View
import Data.String.NonEmpty (NonEmptyString)
import Data.String.NonEmpty as NonEmptyString
import Data.Symbol (SProxy(..))
import Effect.Uncurried (mkEffectFn1, runEffectFn1)
import Foreign.Object (Object)
import Foreign.Object as Object
import Framer.Motion as M
@ -16,6 +17,7 @@ import Yoga.Block.Atom.Input.Style as Style
import Yoga.Block.Atom.Input.Types (HTMLInput)
import Yoga.Block.Atom.Input.Types as HTMLInput
import Yoga.Block.Icon.SVG as SVGIcon
import Yoga.Block.Internal.OptionalProp (asMaybe)
type PropsF f
= ( leading ∷ f JSX
@ -132,6 +134,18 @@ rawComponent =
maybePlaceholder = do
given <- props.placeholder # cast # opToMaybe
if isJust maybeLabelText && hasFocus then Just given else Nothing
onBlur =
handler preventDefault
( const do
when hasFocus $ setHasFocus false
el <- getHTMLElementFromRef ref
let
inputEl = InputElement.fromHTMLElement =<< el
for_ inputEl \ie -> do
v <- InputElement.value ie
setHasValue (v /= "")
)
onFocus = handler preventDefault (const $ unless hasFocus $ setHasFocus true)
inputWrapper =
div
</* { className: "ry-input-wrapper"
@ -150,18 +164,8 @@ rawComponent =
)
{ className: "ry-input"
, css: Style.input props
, onFocus: handler preventDefault (const $ unless hasFocus $ setHasFocus true)
, onBlur:
handler preventDefault
( const do
when hasFocus $ setHasFocus false
el <- getHTMLElementFromRef ref
let
inputEl = InputElement.fromHTMLElement =<< el
for_ inputEl \ie -> do
v <- InputElement.value ie
setHasValue (v /= "")
)
, onFocus: composeHandler props.onFocus onFocus
, onBlur: composeHandler props.onBlur onBlur
, _aria:
if props.label # opToMaybe # isJust then
aria # Object.insert "labelledby" labelId

View File

@ -1,16 +0,0 @@
module Yoga.Block.Atom.Popover.Spec where
import Yoga.Prelude.Spec
import React.Basic.DOM as R
import Yoga.Block.Atom.Popover as Popover
spec ∷ Spec Unit
spec =
after_ cleanup do
describe "The popover" do
it "renders without errors" do
void
$ renderComponent Popover.component
{ target: R.text "Target"
, children: [ R.text "hi"]
}

View File

@ -4,15 +4,17 @@ import Prelude
import Data.Array as Array
import Data.Foldable (traverse_)
import Data.Maybe (Maybe(..))
import Data.Monoid (guard)
import Data.String as String
import Data.String.NonEmpty.Internal (nes)
import Data.Symbol (SProxy(..))
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Uncurried (mkEffectFn1)
import Effect.Unsafe (unsafePerformEffect)
import Framer.Motion (animateSharedLayout)
import Framer.Motion (animatePresence)
import Framer.Motion as Motion
import React.Basic (JSX, ReactComponent, element, fragment)
import React.Basic (JSX, ReactComponent, element, elementKeyed, fragment)
import React.Basic.DOM (CSS, css)
import React.Basic.DOM as R
import React.Basic.DOM.Events (targetValue)
@ -20,6 +22,8 @@ import React.Basic.Emotion as E
import React.Basic.Events (handler, handler_)
import React.Basic.Hooks (reactComponent)
import React.Basic.Hooks as React
import React.Basic.Popper.Types (nullRef)
import Unsafe.Coerce (unsafeCoerce)
import Yoga ((/>), (</), (</>))
import Yoga.Block.Atom.Input as Input
import Yoga.Block.Atom.Input.Placement.Types (Placement(..))
@ -45,44 +49,6 @@ default =
]
}
itemVariants ∷
{ hidden ∷ CSS
, visible ∷ CSS
}
itemVariants =
{ visible:
css
{ left: 0
}
, hidden:
css
{ left: -20
}
}
containerVariants ∷
{ hidden ∷ CSS
, visible ∷ CSS
}
containerVariants =
{ visible:
css
{ transition: { when: "beforeChildren" }
, staggerChildren: 0.3
, opacity: 0
}
, hidden:
css
{ transition: { when: "afterChildren" }
}
}
containerVariant ∷
{ hidden ∷ Motion.VariantLabel
, visible ∷ Motion.VariantLabel
}
containerVariant = Motion.makeVariantLabels containerVariants
popover ∷ Effect JSX
popover = do
autosuggest <- mkAutosuggest
@ -97,7 +63,9 @@ popover = do
mkAutosuggest ∷ Effect (ReactComponent {})
mkAutosuggest = do
motionStack <- Motion.custom Stack.component
motionPopover <- Motion.custom Popover.component
reactComponent "PopoverExample" \props -> React.do
referenceElement /\ setReferenceElement <- React.useState' nullRef
text /\ setText <- React.useState' ""
visible /\ setVisible <- React.useState' false
let
@ -105,150 +73,223 @@ popover = do
authors
# Array.filter (\a -> String.contains (String.Pattern (String.toLower text)) (String.toLower a))
let
target =
inputWrapper =
R.div'
</ { ref: unsafeCoerce (mkEffectFn1 setReferenceElement)
}
input =
Input.component
</> { type: HTMLInput.Text
, id: "author"
</> { id: "author"
, type: HTMLInput.Text
, label: nes (SProxy ∷ _ "Author")
, placeholder: "e.g. William Shakespeare"
, value: text
, style: css { width: "280px" }
, onChange: handler targetValue $ traverse_ setText
, onBlur: handler_ (setVisible false)
, onFocus: handler_ (setVisible true)
, trailing: R.text "▼"
, autoComplete: "off"
}
pop =
Popover.component
</ { target
, placement: Placement Placement.Bottom (Just Placement.Start)
}
pop children =
elementKeyed motionPopover
$ Motion.motion
{ initial: Motion.initial $ css { clipPath: "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)" }
, exit: Motion.exit $ css { clipPath: "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)" }
, animate: Motion.animate $ css { clipPath: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)" }
, transition:
Motion.transition
$ { type: "spring"
, stiffness: 200.0
, damping: 20.0
, mass: 0.7
}
}
{ placement: Placement Placement.Bottom (Just Placement.Start)
, referenceElement
, style:
css
{ boxShadow: "0px 9px 12px rgba(40,40,40,0.5)"
, background: "rgba(50,50,70, 0.7)"
, borderRadius: "9px"
, borderTop: "solid 1px rgba(80,80,100,1.0)"
, overflowY: "scroll"
, maxHeight: "400px"
, width: "300px"
}
, key: "popover"
, children
}
box =
Box.component
</ { style:
css
{ background: "rgba(128, 128, 128, 0.5)"
, borderRadius: "5px"
}
{}
}
stack =
motionStack
</ Motion.motion
{ variants: Motion.variants containerVariants
, animate: Motion.animate (if visible then containerVariant.visible else containerVariant.hidden)
, layout: Motion.layout true
}
</ Motion.motion {}
-- { variants: Motion.variants containerVariants
-- , animate: Motion.animate (if visible then containerVariant.visible else containerVariant.hidden)
-- , layout: Motion.layout true
-- }
{}
entry a =
Motion.div
</ { key: a
, layout: Motion.layout true
, variants: Motion.variants itemVariants
-- , layout: Motion.layout true
-- , variants: Motion.variants itemVariants
}
/> [ R.text a ]
pure
$ fragment
[ pop
[ box
[ animateSharedLayout </ {} /> [ stack (entry <$> matchingAuthors) ]
]
]
[ inputWrapper [ input ]
, animatePresence
</ {}
/> [ guard visible
$ pop
[ box
[ stack (entry <$> matchingAuthors)
]
]
]
]
where
itemVariants ∷
{ hidden ∷ CSS
, visible ∷ CSS
}
itemVariants =
{ visible:
css
{ left: 0
}
, hidden:
css
{ left: -20
}
}
authors =
[ "William Shakespeare"
, "Agatha Christie"
, "Barbara Cartland"
, "Danielle Steel"
, "Harold Robbins"
, "Georges Simenon"
, "Enid Blyton"
, "Sidney Sheldon"
, "J. K. Rowling"
, "Gilbert Patten"
, "Dr. Seuss"
, "Eiichiro Oda"
, "Leo Tolstoy"
, "Corín Tellado"
, "Jackie Collins"
, "Horatio Alger"
, "R. L. Stine"
, "Dean Koontz"
, "Nora Roberts"
, "Alexander Pushkin"
, "Stephen King"
, "Paulo Coelho"
, "Jeffrey Archer"
, "Louis L'Amour"
, "Jirō Akagawa"
, "René Goscinny"
, "Erle Stanley Gardner"
, "Edgar Wallace"
, "Jin Yong"
, "Janet Dailey"
, "Robert Ludlum"
, "Akira Toriyama"
, "Osamu Tezuka"
, "James Patterson"
, "Frédéric Dard"
, "Stan and Jan Berenstain"
, "Roald Dahl"
, "John Grisham"
, "Zane Grey"
, "Irving Wallace"
, "J. R. R. Tolkien"
, "Masashi Kishimoto"
, "Karl May"
, "Carter Brown"
, "Mickey Spillane"
, "C. S. Lewis"
, "Kyotaro Nishimura"
, "Mitsuru Adachi"
, "Rumiko Takahashi"
, "Gosho Aoyama"
, "Dan Brown"
, "Ann M. Martin"
, "Ryōtarō Shiba"
, "Arthur Hailey"
, "Gérard de Villiers"
, "Beatrix Potter"
, "Michael Crichton"
, "Richard Scarry"
, "Clive Cussler"
, "Alistair MacLean"
, "Ken Follett"
, "Astrid Lindgren"
, "Debbie Macomber"
, "EL James"
, "Tite Kubo"
, "Eiji Yoshikawa"
, "Catherine Cookson"
, "Stephenie Meyer"
, "Norman Bridwell"
, "David Baldacci"
, "Nicholas Sparks"
, "Hirohiko Araki"
, "Evan Hunter"
, "Andrew Neiderman"
, "Roger Hargreaves"
, "Anne Rice"
, "Robin Cook"
, "Wilbur Smith"
, "Erskine Caldwell"
, "Judith Krantz"
, "Eleanor Hibbert"
, "Lewis Carroll"
, "Denise Robins"
, "Cao Xueqin"
, "Ian Fleming"
, "Hermann Hesse"
, "Rex Stout"
, "Anne Golon"
, "Frank G. Slaughter"
, "Edgar Rice Burroughs"
, "John Creasey"
, "James A. Michener"
, "Yasuo Uchida"
, "Seiichi Morimura"
, "Mary Higgins Clark"
, "Penny Jordan"
, "Patricia Cornwell"
]
containerVariants ∷
{ hidden ∷ CSS
, visible ∷ CSS
}
containerVariants =
{ visible:
css
{ transition: { when: "beforeChildren" }
, staggerChildren: 0.3
, opacity: 1
}
, hidden:
css
{ transition: { when: "afterChildren" }
, opacity: 0
}
}
containerVariant ∷
{ hidden ∷ Motion.VariantLabel
, visible ∷ Motion.VariantLabel
}
containerVariant = Motion.makeVariantLabels containerVariants
authors =
[ "William Shakespeare"
, "Agatha Christie"
, "Barbara Cartland"
, "Danielle Steel"
, "Harold Robbins"
, "Georges Simenon"
, "Enid Blyton"
, "Sidney Sheldon"
, "J. K. Rowling"
, "Gilbert Patten"
, "Dr. Seuss"
, "Eiichiro Oda"
, "Leo Tolstoy"
, "Corín Tellado"
, "Jackie Collins"
, "Horatio Alger"
, "R. L. Stine"
, "Dean Koontz"
, "Nora Roberts"
, "Alexander Pushkin"
, "Stephen King"
, "Paulo Coelho"
, "Jeffrey Archer"
, "Louis L'Amour"
, "Jirō Akagawa"
, "René Goscinny"
, "Erle Stanley Gardner"
, "Edgar Wallace"
, "Jin Yong"
, "Janet Dailey"
, "Robert Ludlum"
, "Akira Toriyama"
, "Osamu Tezuka"
, "James Patterson"
, "Frédéric Dard"
, "Stan and Jan Berenstain"
, "Roald Dahl"
, "John Grisham"
, "Zane Grey"
, "Irving Wallace"
, "J. R. R. Tolkien"
, "Masashi Kishimoto"
, "Karl May"
, "Carter Brown"
, "Mickey Spillane"
, "C. S. Lewis"
, "Kyotaro Nishimura"
, "Mitsuru Adachi"
, "Rumiko Takahashi"
, "Gosho Aoyama"
, "Dan Brown"
, "Ann M. Martin"
, "Ryōtarō Shiba"
, "Arthur Hailey"
, "Gérard de Villiers"
, "Beatrix Potter"
, "Michael Crichton"
, "Richard Scarry"
, "Clive Cussler"
, "Alistair MacLean"
, "Ken Follett"
, "Astrid Lindgren"
, "Debbie Macomber"
, "EL James"
, "Tite Kubo"
, "Eiji Yoshikawa"
, "Catherine Cookson"
, "Stephenie Meyer"
, "Norman Bridwell"
, "David Baldacci"
, "Nicholas Sparks"
, "Hirohiko Araki"
, "Evan Hunter"
, "Andrew Neiderman"
, "Roger Hargreaves"
, "Anne Rice"
, "Robin Cook"
, "Wilbur Smith"
, "Erskine Caldwell"
, "Judith Krantz"
, "Eleanor Hibbert"
, "Lewis Carroll"
, "Denise Robins"
, "Cao Xueqin"
, "Ian Fleming"
, "Hermann Hesse"
, "Rex Stout"
, "Anne Golon"
, "Frank G. Slaughter"
, "Edgar Rice Burroughs"
, "John Creasey"
, "James A. Michener"
, "Yasuo Uchida"
, "Seiichi Morimura"
, "Mary Higgins Clark"
, "Penny Jordan"
, "Patricia Cornwell"
]

View File

@ -2,8 +2,6 @@ module Yoga.Block.Atom.Popover.View (component, MandatoryProps, Props, PropsF) w
import Yoga.Prelude.View
import Effect.Uncurried (mkEffectFn1)
import Framer.Motion as Motion
import React.Basic.DOM (css)
import React.Basic.Hooks as React
import React.Basic.Popper.Hook (usePopper)
import React.Basic.Popper.Types (modifierOffset, nullRef)
@ -15,12 +13,12 @@ import Yoga.Block.Atom.Popover.Style as Style
type PropsF f
= ( className ∷ f String
, placement ∷ f Placement
| Style.Props f (MandatoryProps ())
| Style.Props f (MandatoryProps DivProps)
)
type MandatoryProps r
= ( children ∷ Array JSX
, target ∷ JSX
, referenceElement ∷ NodeRef
| r
)
@ -38,10 +36,10 @@ rawComponent =
mkForwardRefComponent "Popover" do
\(props ∷ { | PropsOptional }) ref -> React.do
-- Hooks
referenceElement /\ setReferenceElement <- React.useState' nullRef
-- referenceElement /\ setReferenceElement <- React.useState' nullRef
popperElement /\ setPopperElement <- React.useState' nullRef
{ styles, attributes } <-
usePopper referenceElement popperElement
usePopper props.referenceElement popperElement
{ modifiers:
[ modifierOffset { x: 0.0, y: 0.0 }
]
@ -50,20 +48,15 @@ rawComponent =
-- Handlers
-- Elements
let
result =
fragment
$ [ refElem
, popperEl
[ content
props.children
]
]
result = popperEl [ content ]
content =
div
</* { className: "popper-element-content"
, css: Style.content
, key: "container"
}
emotionDiv
ref
props
{ className: "popper-element-content"
, css: Style.content
, children: props.children
}
popperEl =
div
</* { className: "popper-element"
@ -72,10 +65,4 @@ rawComponent =
, style: styles.popper
, _data: attributes.popper
}
refElem =
Motion.div
</ { ref: unsafeCoerce (mkEffectFn1 setReferenceElement)
, style: css { display: "inline-block" }
}
/> [ props.target ]
pure result

View File

@ -48,7 +48,7 @@ import Web.DOM (Node)
import Web.HTML.HTMLElement (DOMRect, HTMLElement, getBoundingClientRect)
import Web.HTML.HTMLElement as HTMLElement
import Yoga.Block.Internal.CSS (_0)
import Yoga.Block.Internal.OptionalProp (Id, OptionalProp(..), appendIfDefined, getOr, getOrFlipped, ifTrue, isTruthy, maybeToOp, opToMaybe, setOrDelete, unsafeUnMaybe, unsafeUnOptional, (<>?), (?||))
import Yoga.Block.Internal.OptionalProp (Id, OptionalProp(..), appendIfDefined, getOr, getOrFlipped, ifTrue, isTruthy, maybeToOp, opToMaybe, setOrDelete, unsafeUnMaybe, unsafeUnOptional, (<>?), (?||), asOptional, composeHandler)
foreign import mkForwardRefComponent ∷
∀ inputProps props a hooks.
@ -64,8 +64,8 @@ foreign import mkForwardRefComponentEffect ∷
foreign import createRef ∷ ∀ a. Effect (Ref a)
type NodeRef =
Ref (Nullable Node)
type NodeRef
= Ref (Nullable Node)
getBoundingBoxFromRef ∷ Ref (Nullable Node) -> Effect (Maybe DOMRect)
getBoundingBoxFromRef itemRef = do
@ -81,8 +81,8 @@ getHTMLElementFromRef itemRef =
forwardedRefAsMaybe ∷ ∀ a. Ref a -> Maybe (Ref a)
forwardedRefAsMaybe r = safelyWrapped # uorToMaybe >>= Nullable.toMaybe
where
safelyWrapped ∷ UndefinedOr (Nullable (Ref a))
safelyWrapped = unsafeCoerce r
safelyWrapped ∷ UndefinedOr (Nullable (Ref a))
safelyWrapped = unsafeCoerce r
foreign import unsafeUnionDroppingUndefined ∷ ∀ r1 r2 r3. Record r1 -> Record r2 -> Record r3
@ -134,7 +134,7 @@ pickDefined ∷
{ ref ∷ Ref (Nullable Node) | b }
pickDefined ref = runFn3 pickDefinedFn ref ks
where
ks = Array.fromFoldable $ keys (RProxy ∷ RProxy b)
ks = Array.fromFoldable $ keys (RProxy ∷ RProxy b)
emotionInput_ ∷
∀ props props_.
@ -182,300 +182,300 @@ dangerous = unsafePerformEffect <<< unsafeCreateDOMComponent
-- type DivProps =
-- Props_div
type DivProps =
DivPropsF Id ()
type DivProps
= DivPropsF Id ()
type DivPropsF f more =
( _aria ∷ f (Object String)
, _data ∷ f (Object String)
, about ∷ f String
, acceptCharset ∷ f String
, accessKey ∷ f String
, allowFullScreen ∷ f Boolean
, autoFocus ∷ f Boolean
, autoPlay ∷ f Boolean
, capture ∷ f Boolean
, cellPadding ∷ f String
, cellSpacing ∷ f String
, charSet ∷ f String
, children ∷ f (Array JSX)
, classID ∷ f String
, colSpan ∷ f Int
, contentEditable ∷ f Boolean
, contextMenu ∷ f String
, crossOrigin ∷ f String
, dangerouslySetInnerHTML ∷ f { __html ∷ f String }
, datatype ∷ f String
, dateTime ∷ f String
, dir ∷ f String
, draggable ∷ f Boolean
, encType ∷ f String
, formAction ∷ f String
, formEncType ∷ f String
, formMethod ∷ f String
, formNoValidate ∷ f Boolean
, formTarget ∷ f String
, frameBorder ∷ f String
, hidden ∷ f Boolean
, hrefLang ∷ f String
, htmlFor ∷ f String
, httpEquiv ∷ f String
, icon ∷ f String
, id ∷ f String
, inlist ∷ f String
, inputMode ∷ f String
, is ∷ f String
, itemID ∷ f String
, itemProp ∷ f String
, itemRef ∷ f String
, itemScope ∷ f Boolean
, itemType ∷ f String
, keyParams ∷ f String
, keyType ∷ f String
, lang ∷ f String
, marginHeight ∷ f String
, marginWidth ∷ f String
, maxLength ∷ f Int
, mediaGroup ∷ f String
, minLength ∷ f Int
, noValidate ∷ f Boolean
, onAnimationEnd ∷ f EventHandler
, onAnimationIteration ∷ f EventHandler
, onAnimationStart ∷ f EventHandler
, onBlur ∷ f EventHandler
, onClick ∷ f EventHandler
, onCompositionEnd ∷ f EventHandler
, onCompositionStart ∷ f EventHandler
, onCompositionUpdate ∷ f EventHandler
, onContextMenu ∷ f EventHandler
, onCopy ∷ f EventHandler
, onCut ∷ f EventHandler
, onDoubleClick ∷ f EventHandler
, onDrag ∷ f EventHandler
, onDragEnd ∷ f EventHandler
, onDragEnter ∷ f EventHandler
, onDragExit ∷ f EventHandler
, onDragLeave ∷ f EventHandler
, onDragOver ∷ f EventHandler
, onDragStart ∷ f EventHandler
, onDrop ∷ f EventHandler
, onFocus ∷ f EventHandler
, onGotPointerCapture ∷ f EventHandler
, onInvalid ∷ f EventHandler
, onKeyDown ∷ f EventHandler
, onKeyPress ∷ f EventHandler
, onKeyUp ∷ f EventHandler
, onLostPointerCapture ∷ f EventHandler
, onMouseDown ∷ f EventHandler
, onMouseEnter ∷ f EventHandler
, onMouseLeave ∷ f EventHandler
, onMouseMove ∷ f EventHandler
, onMouseOut ∷ f EventHandler
, onMouseOver ∷ f EventHandler
, onMouseUp ∷ f EventHandler
, onPaste ∷ f EventHandler
, onPointerCancel ∷ f EventHandler
, onPointerDown ∷ f EventHandler
, onPointerEnter ∷ f EventHandler
, onPointerLeave ∷ f EventHandler
, onPointerMove ∷ f EventHandler
, onPointerOut ∷ f EventHandler
, onPointerOver ∷ f EventHandler
, onPointerUp ∷ f EventHandler
, onSelect ∷ f EventHandler
, onSubmit ∷ f EventHandler
, onTouchCancel ∷ f EventHandler
, onTouchEnd ∷ f EventHandler
, onTouchMove ∷ f EventHandler
, onTouchStart ∷ f EventHandler
, onTransitionEnd ∷ f EventHandler
, onWheel ∷ f EventHandler
, prefix ∷ f String
, property ∷ f String
, radioGroup ∷ f String
, readOnly ∷ f Boolean
, ref ∷ f (Ref (Nullable Node))
, resource ∷ f String
, role ∷ f String
, rowSpan ∷ f Int
, scoped ∷ f Boolean
, seamless ∷ f Boolean
, security ∷ f String
, spellCheck ∷ f Boolean
, srcDoc ∷ f JSX
, srcLang ∷ f String
, srcSet ∷ f String
, style ∷ f CSS
, suppressContentEditableWarning ∷ f Boolean
, tabIndex ∷ f Int
, title ∷ f String
, typeof ∷ f String
, unselectable ∷ f Boolean
, useMap ∷ f String
, vocab ∷ f String
, wmode ∷ f String
| more
)
type DivPropsF f more
= ( _aria ∷ f (Object String)
, _data ∷ f (Object String)
, about ∷ f String
, acceptCharset ∷ f String
, accessKey ∷ f String
, allowFullScreen ∷ f Boolean
, autoFocus ∷ f Boolean
, autoPlay ∷ f Boolean
, capture ∷ f Boolean
, cellPadding ∷ f String
, cellSpacing ∷ f String
, charSet ∷ f String
, children ∷ f (Array JSX)
, classID ∷ f String
, colSpan ∷ f Int
, contentEditable ∷ f Boolean
, contextMenu ∷ f String
, crossOrigin ∷ f String
, dangerouslySetInnerHTML ∷ f { __html ∷ f String }
, datatype ∷ f String
, dateTime ∷ f String
, dir ∷ f String
, draggable ∷ f Boolean
, encType ∷ f String
, formAction ∷ f String
, formEncType ∷ f String
, formMethod ∷ f String
, formNoValidate ∷ f Boolean
, formTarget ∷ f String
, frameBorder ∷ f String
, hidden ∷ f Boolean
, hrefLang ∷ f String
, htmlFor ∷ f String
, httpEquiv ∷ f String
, icon ∷ f String
, id ∷ f String
, inlist ∷ f String
, inputMode ∷ f String
, is ∷ f String
, itemID ∷ f String
, itemProp ∷ f String
, itemRef ∷ f String
, itemScope ∷ f Boolean
, itemType ∷ f String
, keyParams ∷ f String
, keyType ∷ f String
, lang ∷ f String
, marginHeight ∷ f String
, marginWidth ∷ f String
, maxLength ∷ f Int
, mediaGroup ∷ f String
, minLength ∷ f Int
, noValidate ∷ f Boolean
, onAnimationEnd ∷ f EventHandler
, onAnimationIteration ∷ f EventHandler
, onAnimationStart ∷ f EventHandler
, onBlur ∷ f EventHandler
, onClick ∷ f EventHandler
, onCompositionEnd ∷ f EventHandler
, onCompositionStart ∷ f EventHandler
, onCompositionUpdate ∷ f EventHandler
, onContextMenu ∷ f EventHandler
, onCopy ∷ f EventHandler
, onCut ∷ f EventHandler
, onDoubleClick ∷ f EventHandler
, onDrag ∷ f EventHandler
, onDragEnd ∷ f EventHandler
, onDragEnter ∷ f EventHandler
, onDragExit ∷ f EventHandler
, onDragLeave ∷ f EventHandler
, onDragOver ∷ f EventHandler
, onDragStart ∷ f EventHandler
, onDrop ∷ f EventHandler
, onFocus ∷ f EventHandler
, onGotPointerCapture ∷ f EventHandler
, onInvalid ∷ f EventHandler
, onKeyDown ∷ f EventHandler
, onKeyPress ∷ f EventHandler
, onKeyUp ∷ f EventHandler
, onLostPointerCapture ∷ f EventHandler
, onMouseDown ∷ f EventHandler
, onMouseEnter ∷ f EventHandler
, onMouseLeave ∷ f EventHandler
, onMouseMove ∷ f EventHandler
, onMouseOut ∷ f EventHandler
, onMouseOver ∷ f EventHandler
, onMouseUp ∷ f EventHandler
, onPaste ∷ f EventHandler
, onPointerCancel ∷ f EventHandler
, onPointerDown ∷ f EventHandler
, onPointerEnter ∷ f EventHandler
, onPointerLeave ∷ f EventHandler
, onPointerMove ∷ f EventHandler
, onPointerOut ∷ f EventHandler
, onPointerOver ∷ f EventHandler
, onPointerUp ∷ f EventHandler
, onSelect ∷ f EventHandler
, onSubmit ∷ f EventHandler
, onTouchCancel ∷ f EventHandler
, onTouchEnd ∷ f EventHandler
, onTouchMove ∷ f EventHandler
, onTouchStart ∷ f EventHandler
, onTransitionEnd ∷ f EventHandler
, onWheel ∷ f EventHandler
, prefix ∷ f String
, property ∷ f String
, radioGroup ∷ f String
, readOnly ∷ f Boolean
, ref ∷ f (Ref (Nullable Node))
, resource ∷ f String
, role ∷ f String
, rowSpan ∷ f Int
, scoped ∷ f Boolean
, seamless ∷ f Boolean
, security ∷ f String
, spellCheck ∷ f Boolean
, srcDoc ∷ f JSX
, srcLang ∷ f String
, srcSet ∷ f String
, style ∷ f CSS
, suppressContentEditableWarning ∷ f Boolean
, tabIndex ∷ f Int
, title ∷ f String
, typeof ∷ f String
, unselectable ∷ f Boolean
, useMap ∷ f String
, vocab ∷ f String
, wmode ∷ f String
| more
)
type InputProps =
InputPropsF Id ()
type InputProps
= InputPropsF Id ()
type InputPropsF f more =
( _aria ∷ f (Object String)
, _data ∷ f (Object String)
, about ∷ f String
, accept ∷ f String
, acceptCharset ∷ f String
, accessKey ∷ f String
, allowFullScreen ∷ f Boolean
, alt ∷ f String
, autoCapitalize ∷ f String
, autoComplete ∷ f String
, autoCorrect ∷ f String
, autoFocus ∷ f Boolean
, autoPlay ∷ f Boolean
, autoSave ∷ f String
, capture ∷ f Boolean
, cellPadding ∷ f String
, cellSpacing ∷ f String
, charSet ∷ f String
, checked ∷ f Boolean
, classID ∷ f String
, colSpan ∷ f Int
, contentEditable ∷ f Boolean
, contextMenu ∷ f String
, crossOrigin ∷ f String
, dangerouslySetInnerHTML ∷ f { __html ∷ f String }
, datatype ∷ f String
, dateTime ∷ f String
, defaultChecked ∷ f String
, defaultValue ∷ f String
, dir ∷ f String
, disabled ∷ f Boolean
, draggable ∷ f Boolean
, encType ∷ f String
, form ∷ f String
, formAction ∷ f String
, formEncType ∷ f String
, formMethod ∷ f String
, formNoValidate ∷ f Boolean
, formTarget ∷ f String
, frameBorder ∷ f String
, height ∷ f String
, hidden ∷ f Boolean
, hrefLang ∷ f String
, htmlFor ∷ f String
, httpEquiv ∷ f String
, icon ∷ f String
, id ∷ f String
, inlist ∷ f String
, inputMode ∷ f String
, is ∷ f String
, itemID ∷ f String
, itemProp ∷ f String
, itemRef ∷ f String
, itemScope ∷ f Boolean
, itemType ∷ f String
, keyParams ∷ f String
, keyType ∷ f String
, lang ∷ f String
, list ∷ f String
, marginHeight ∷ f String
, marginWidth ∷ f String
, maxLength ∷ f Int
, mediaGroup ∷ f String
, minLength ∷ f Int
, multiple ∷ f Boolean
, name ∷ f String
, noValidate ∷ f Boolean
, onAnimationEnd ∷ f EventHandler
, onAnimationIteration ∷ f EventHandler
, onAnimationStart ∷ f EventHandler
, onBlur ∷ f EventHandler
, onChange ∷ f EventHandler
, onClick ∷ f EventHandler
, onCompositionEnd ∷ f EventHandler
, onCompositionStart ∷ f EventHandler
, onCompositionUpdate ∷ f EventHandler
, onContextMenu ∷ f EventHandler
, onCopy ∷ f EventHandler
, onCut ∷ f EventHandler
, onDoubleClick ∷ f EventHandler
, onDrag ∷ f EventHandler
, onDragEnd ∷ f EventHandler
, onDragEnter ∷ f EventHandler
, onDragExit ∷ f EventHandler
, onDragLeave ∷ f EventHandler
, onDragOver ∷ f EventHandler
, onDragStart ∷ f EventHandler
, onDrop ∷ f EventHandler
, onFocus ∷ f EventHandler
, onGotPointerCapture ∷ f EventHandler
, onInvalid ∷ f EventHandler
, onKeyDown ∷ f EventHandler
, onKeyPress ∷ f EventHandler
, onKeyUp ∷ f EventHandler
, onLostPointerCapture ∷ f EventHandler
, onMouseDown ∷ f EventHandler
, onMouseEnter ∷ f EventHandler
, onMouseLeave ∷ f EventHandler
, onMouseMove ∷ f EventHandler
, onMouseOut ∷ f EventHandler
, onMouseOver ∷ f EventHandler
, onMouseUp ∷ f EventHandler
, onPaste ∷ f EventHandler
, onPointerCancel ∷ f EventHandler
, onPointerDown ∷ f EventHandler
, onPointerEnter ∷ f EventHandler
, onPointerLeave ∷ f EventHandler
, onPointerMove ∷ f EventHandler
, onPointerOut ∷ f EventHandler
, onPointerOver ∷ f EventHandler
, onPointerUp ∷ f EventHandler
, onSelect ∷ f EventHandler
, onSubmit ∷ f EventHandler
, onTouchCancel ∷ f EventHandler
, onTouchEnd ∷ f EventHandler
, onTouchMove ∷ f EventHandler
, onTouchStart ∷ f EventHandler
, onTransitionEnd ∷ f EventHandler
, onWheel ∷ f EventHandler
, pattern ∷ f String
, placeholder ∷ f String
, prefix ∷ f String
, property ∷ f String
, radioGroup ∷ f String
, ref ∷ f (Ref (Nullable Node))
, readOnly ∷ f Boolean
, required ∷ f Boolean
, resource ∷ f String
, results ∷ f String
, role ∷ f String
, rowSpan ∷ f Int
, scoped ∷ f Boolean
, seamless ∷ f Boolean
, security ∷ f String
, size ∷ f Int
, spellCheck ∷ f Boolean
, src ∷ f String
, srcDoc ∷ f JSX
, srcLang ∷ f String
, srcSet ∷ f String
, step ∷ f String
, style ∷ f CSS
, suppressContentEditableWarning ∷ f Boolean
, tabIndex ∷ f Int
, title ∷ f String
, title ∷ f String
, type ∷ f String
, typeof ∷ f String
, unselectable ∷ f Boolean
, useMap ∷ f String
, value ∷ f String
, vocab ∷ f String
, width ∷ f String
, wmode ∷ f String
, min ∷ f (String)
, max ∷ f (String)
| more
)
type InputPropsF f more
= ( _aria ∷ f (Object String)
, _data ∷ f (Object String)
, about ∷ f String
, accept ∷ f String
, acceptCharset ∷ f String
, accessKey ∷ f String
, allowFullScreen ∷ f Boolean
, alt ∷ f String
, autoCapitalize ∷ f String
, autoComplete ∷ f String
, autoCorrect ∷ f String
, autoFocus ∷ f Boolean
, autoPlay ∷ f Boolean
, autoSave ∷ f String
, capture ∷ f Boolean
, cellPadding ∷ f String
, cellSpacing ∷ f String
, charSet ∷ f String
, checked ∷ f Boolean
, classID ∷ f String
, colSpan ∷ f Int
, contentEditable ∷ f Boolean
, contextMenu ∷ f String
, crossOrigin ∷ f String
, dangerouslySetInnerHTML ∷ f { __html ∷ f String }
, datatype ∷ f String
, dateTime ∷ f String
, defaultChecked ∷ f String
, defaultValue ∷ f String
, dir ∷ f String
, disabled ∷ f Boolean
, draggable ∷ f Boolean
, encType ∷ f String
, form ∷ f String
, formAction ∷ f String
, formEncType ∷ f String
, formMethod ∷ f String
, formNoValidate ∷ f Boolean
, formTarget ∷ f String
, frameBorder ∷ f String
, height ∷ f String
, hidden ∷ f Boolean
, hrefLang ∷ f String
, htmlFor ∷ f String
, httpEquiv ∷ f String
, icon ∷ f String
, id ∷ f String
, inlist ∷ f String
, inputMode ∷ f String
, is ∷ f String
, itemID ∷ f String
, itemProp ∷ f String
, itemRef ∷ f String
, itemScope ∷ f Boolean
, itemType ∷ f String
, keyParams ∷ f String
, keyType ∷ f String
, lang ∷ f String
, list ∷ f String
, marginHeight ∷ f String
, marginWidth ∷ f String
, maxLength ∷ f Int
, mediaGroup ∷ f String
, minLength ∷ f Int
, multiple ∷ f Boolean
, name ∷ f String
, noValidate ∷ f Boolean
, onAnimationEnd ∷ f EventHandler
, onAnimationIteration ∷ f EventHandler
, onAnimationStart ∷ f EventHandler
, onBlur ∷ f EventHandler
, onChange ∷ f EventHandler
, onClick ∷ f EventHandler
, onCompositionEnd ∷ f EventHandler
, onCompositionStart ∷ f EventHandler
, onCompositionUpdate ∷ f EventHandler
, onContextMenu ∷ f EventHandler
, onCopy ∷ f EventHandler
, onCut ∷ f EventHandler
, onDoubleClick ∷ f EventHandler
, onDrag ∷ f EventHandler
, onDragEnd ∷ f EventHandler
, onDragEnter ∷ f EventHandler
, onDragExit ∷ f EventHandler
, onDragLeave ∷ f EventHandler
, onDragOver ∷ f EventHandler
, onDragStart ∷ f EventHandler
, onDrop ∷ f EventHandler
, onFocus ∷ f EventHandler
, onGotPointerCapture ∷ f EventHandler
, onInvalid ∷ f EventHandler
, onKeyDown ∷ f EventHandler
, onKeyPress ∷ f EventHandler
, onKeyUp ∷ f EventHandler
, onLostPointerCapture ∷ f EventHandler
, onMouseDown ∷ f EventHandler
, onMouseEnter ∷ f EventHandler
, onMouseLeave ∷ f EventHandler
, onMouseMove ∷ f EventHandler
, onMouseOut ∷ f EventHandler
, onMouseOver ∷ f EventHandler
, onMouseUp ∷ f EventHandler
, onPaste ∷ f EventHandler
, onPointerCancel ∷ f EventHandler
, onPointerDown ∷ f EventHandler
, onPointerEnter ∷ f EventHandler
, onPointerLeave ∷ f EventHandler
, onPointerMove ∷ f EventHandler
, onPointerOut ∷ f EventHandler
, onPointerOver ∷ f EventHandler
, onPointerUp ∷ f EventHandler
, onSelect ∷ f EventHandler
, onSubmit ∷ f EventHandler
, onTouchCancel ∷ f EventHandler
, onTouchEnd ∷ f EventHandler
, onTouchMove ∷ f EventHandler
, onTouchStart ∷ f EventHandler
, onTransitionEnd ∷ f EventHandler
, onWheel ∷ f EventHandler
, pattern ∷ f String
, placeholder ∷ f String
, prefix ∷ f String
, property ∷ f String
, radioGroup ∷ f String
, ref ∷ f (Ref (Nullable Node))
, readOnly ∷ f Boolean
, required ∷ f Boolean
, resource ∷ f String
, results ∷ f String
, role ∷ f String
, rowSpan ∷ f Int
, scoped ∷ f Boolean
, seamless ∷ f Boolean
, security ∷ f String
, size ∷ f Int
, spellCheck ∷ f Boolean
, src ∷ f String
, srcDoc ∷ f JSX
, srcLang ∷ f String
, srcSet ∷ f String
, step ∷ f String
, style ∷ f CSS
, suppressContentEditableWarning ∷ f Boolean
, tabIndex ∷ f Int
, title ∷ f String
, title ∷ f String
, type ∷ f String
, typeof ∷ f String
, unselectable ∷ f Boolean
, useMap ∷ f String
, value ∷ f String
, vocab ∷ f String
, width ∷ f String
, wmode ∷ f String
, min ∷ f (String)
, max ∷ f (String)
| more
)

View File

@ -2,21 +2,24 @@ module Yoga.Block.Internal.OptionalProp where
import Prelude
import Control.Alt (class Alt, (<|>))
import Data.Foldable (class Foldable, foldMap, foldl, foldr)
import Data.Foldable (class Foldable, foldMap, foldl, foldr, for_)
import Data.Maybe (Maybe(..), maybe)
import Data.Newtype (class Newtype)
import Data.Symbol (class IsSymbol, SProxy, reflectSymbol)
import Effect.Uncurried (mkEffectFn1, runEffectFn1)
import Prim.Row (class Cons)
import React.Basic.Events (EventHandler)
import Record (set)
import Record.Unsafe (unsafeDelete)
import Unsafe.Coerce (unsafeCoerce)
import Untagged.Castable (class Castable)
import Untagged.Castable (class Castable, cast)
import Untagged.Union (UndefinedOr, defined, fromUndefinedOr, maybeToUor, uorToMaybe)
type Id a =
a
type Id a
= a
newtype OptionalProp a = OptionalProp (UndefinedOr a)
newtype OptionalProp a
= OptionalProp (UndefinedOr a)
setOrDelete ∷
∀ r a rNoA key.
@ -30,6 +33,18 @@ setOrDelete key v = case opToMaybe v of
Nothing -> unsafeDelete (reflectSymbol key)
Just v' -> set key v'
asOptional :: forall a. a -> OptionalProp a
asOptional = cast
asMaybe :: forall a. a -> Maybe a
asMaybe = asOptional >>> opToMaybe
composeHandler :: EventHandler -> EventHandler -> EventHandler
composeHandler handler propsHandler =
mkEffectFn1 \a -> do
for_ (propsHandler # asMaybe) $ flip runEffectFn1 a
for_ (handler # asMaybe) $ flip runEffectFn1 a -- not necessary but safer
unsafeUnOptional ∷ ∀ a. OptionalProp a -> a
unsafeUnOptional = unsafeCoerce
@ -41,7 +56,6 @@ opToMaybe (OptionalProp x) = uorToMaybe x
maybeToOp ∷ ∀ a. Maybe a -> OptionalProp a
maybeToOp mb = OptionalProp (maybeToUor mb)
derive instance ntOptionalProp ∷ Newtype (OptionalProp a) _
instance semigroupOptionalProp ∷ Semigroup a => Semigroup (OptionalProp a) where

View File

@ -26,4 +26,4 @@ import Untagged.Castable (cast)
import Web.DOM (Node)
import Web.HTML.HTMLElement (HTMLElement, DOMRect, blur, focus, getBoundingClientRect)
import Yoga ((/>), (</), (</*), (</*>), (</>), div, span, button)
import Yoga.Block.Internal (DivProps, DivPropsF, Id, InputProps, InputPropsF, NodeRef, OptionalProp(..), _0, appendIfDefined, createRef, dangerous, emotionDiv, emotionInput, forwardedRefAsMaybe, getBoundingBoxFromRef, getHTMLElementFromRef, getOr, getOrFlipped, ifTrue, isTruthy, maybeToOp, mkForwardRefComponent, mkForwardRefComponentEffect, opToMaybe, unsafeDiv, unsafeEmotion, unsafeMergeSecond, unsafeUnMaybe, unsafeUnOptional, unsafeUnionDroppingUndefined, (<>?), (?||), setOrDelete)
import Yoga.Block.Internal (DivProps, DivPropsF, Id, InputProps, InputPropsF, NodeRef, OptionalProp(..), _0, appendIfDefined, createRef, dangerous, emotionDiv, emotionInput, forwardedRefAsMaybe, getBoundingBoxFromRef, getHTMLElementFromRef, getOr, getOrFlipped, ifTrue, isTruthy, maybeToOp, mkForwardRefComponent, mkForwardRefComponentEffect, opToMaybe, unsafeDiv, unsafeEmotion, unsafeMergeSecond, unsafeUnMaybe, unsafeUnOptional, unsafeUnionDroppingUndefined, (<>?), (?||), setOrDelete, asOptional, composeHandler)