git.iko.soy/rowtype-yoga/ry-blocks
on main help sign in
Refactoring input
344d03eMark Eibes
src/Yoga/Block/Atom/Input/View.purs+3−104
@@ -4,8 +4,6 @@ import Yoga.Prelude.View
4import Data.Array as Array
4import Data.Array as Array
5import Data.Interpolate (i)
5import Data.Interpolate (i)
6import Data.String.NonEmpty (NonEmptyString)
6import Data.String.NonEmpty (NonEmptyString)
7−import Data.String.NonEmpty as NonEmptyString
8−import Effect.Unsafe (unsafePerformEffect)
9import Foreign.Object (Object)
7import Foreign.Object (Object)
10import Foreign.Object as Object
8import Foreign.Object as Object
11import Framer.Motion as M
9import Framer.Motion as M
@@ -13,13 +11,14 @@ import Partial.Unsafe (unsafeCrashWith)
13import React.Basic.DOM (CSS, css)
11import React.Basic.DOM (CSS, css)
14import React.Basic.DOM as R
12import React.Basic.DOM as R
15import React.Basic.Emotion (Style)
13import React.Basic.Emotion (Style)
16−import React.Basic.Hooks (reactComponent)
17import React.Basic.Hooks as React
14import React.Basic.Hooks as React
18import Web.HTML.HTMLInputElement as InputElement
15import Web.HTML.HTMLInputElement as InputElement
19import Yoga.Block.Atom.Icon as Icon
16import Yoga.Block.Atom.Icon as Icon
20import Yoga.Block.Atom.Input.Style as Style
17import Yoga.Block.Atom.Input.Style as Style
21import Yoga.Block.Atom.Input.Types (HTMLInput)
18import Yoga.Block.Atom.Input.Types (HTMLInput)
22import Yoga.Block.Atom.Input.Types as HTMLInput
19import Yoga.Block.Atom.Input.Types as HTMLInput
20+import Yoga.Block.Atom.Input.View.Container (rawContainer)
21+import Yoga.Block.Atom.Input.View.Label as Label
23import Yoga.Block.Icon.SVG as SVGIcon
22import Yoga.Block.Icon.SVG as SVGIcon
24
23
25type PropsF f =
24type PropsF f =
@@ -129,42 +128,6 @@ rawInput =
129 inputProps = props { type = HTMLInput.toString <$> props.type # unsafeUnOptional }
128 inputProps = props { type = HTMLInput.toString <$> props.type # unsafeUnOptional }
130 pure result
129 pure result
131
130
132−rawContainer ∷ ∀ p. ReactComponent { | p }
133−rawContainer =
134− mkForwardRefComponent "InputContainer" do
135− \( props ∷
136− { children ∷ Array JSX
137− , label ∷ JSX
138− , css ∷ OptionalProp Style
139− , hasFocus ∷ Boolean
140− , inputProps ∷ { | InputPropsF OptionalProp () }
141− }
142− ) propsRef -> React.do
143− -- Left icon width to correctly place the label
144− let
145− aria ∷ Object String
146− aria = props.inputProps._aria # opToMaybe # fold
147− inputContainer =
148− M.div
149− </* M.motion
150− { variants: M.variants containerVariants
151− , animate: M.animate if props.hasFocus then containerVariantLabels.focussed else containerVariantLabels.blurred
152− }
153− { className: "ry-input-container"
154− , css: Style.inputContainer props
155− , _data:
156− Object.fromHomogeneous
157− { "invalid": aria # Object.lookup "invalid" # fromMaybe ""
158− }
159− }
160− /> props.children
161− pure
162− $ div
163− </* { className: "ry-label-and-input-wrapper"
164− , css: Style.labelAndInputWrapper
165− }
166− /> [ inputContainer, props.label ]
167−
168rawComponent ∷ ∀ p. ReactComponent (Record p)
131rawComponent ∷ ∀ p. ReactComponent (Record p)
169rawComponent =
132rawComponent =
170 mkForwardRefComponent "InputContainer" do
133 mkForwardRefComponent "InputContainer" do
@@ -192,7 +155,7 @@ rawComponent =
192 maybeLabelText = props.label # opToMaybe
155 maybeLabelText = props.label # opToMaybe
193 mkLabel ∷ NonEmptyString -> JSX
156 mkLabel ∷ NonEmptyString -> JSX
194 mkLabel labelText =
157 mkLabel labelText =
195− inputLabel
158+ Label.component
196 </> { onClickLargeLabel: handler preventDefault (const focusInput)
159 </> { onClickLargeLabel: handler preventDefault (const focusInput)
197 , isFocussed: hasFocus
160 , isFocussed: hasFocus
198 , isRequired: aria # Object.lookup "required" # (_ == Just "true")
161 , isRequired: aria # Object.lookup "required" # (_ == Just "true")
@@ -265,70 +228,6 @@ rawComponent =
265 }
228 }
266 /> [ inputContainer, mkLabel labelText ]
229 /> [ inputContainer, mkLabel labelText ]
267
230
268−inputLabel ∷
269− ReactComponent
270− { onClickLargeLabel ∷ EventHandler
271− , isRequired ∷ Boolean
272− , isInvalid ∷ Boolean
273− , isFocussed ∷ Boolean
274− , renderLargeLabel ∷ Boolean
275− , leftIconRef ∷ NodeRef
276− , inputRef ∷ NodeRef
277− , labelId ∷ String
278− , inputId ∷ String
279− , labelText ∷ NonEmptyString
280− }
281−inputLabel =
282− unsafePerformEffect
283− $ reactComponent "Password" \props -> React.do
284− inputBbox /\ setInputBbox <- useState' (zero ∷ DOMRect)
285− useEffectOnce do
286− maybeBBox <- getBoundingBoxFromRef props.inputRef
287− for_ maybeBBox setInputBbox
288− mempty
289− -- Left Icon
290− leftIconBbox /\ setLeftIconBbox <- useState' Nothing
291− useEffectAlways do
292− when (leftIconBbox == Nothing) do
293− maybeBBox <- getBoundingBoxFromRef props.leftIconRef
294− for_ maybeBBox (setLeftIconBbox <<< Just)
295− mempty
296− let container = div </* { className: "ry-input-label-container", css: Style.labelContainer }
297− let
298− labelSpan =
299− M.span
300− </ { onClick: props.onClickLargeLabel
301− , layout: M.layout true
302− , layoutId: M.layoutId "ry-input-label-text"
303− , htmlFor: props.inputId
304− , id: props.labelId
305− }
306− pure
307− $ container
308− [ M.animateSharedLayout </ { type: M.switch }
309− /> [ guard (inputBbox /= zero)
310− $ M.div
311− </* { className: if props.renderLargeLabel then "ry-input-label-large" else "ry-input-label-small"
312− , layoutId: M.layoutId "ry-input-label"
313− , css:
314− if props.renderLargeLabel then
315− Style.labelLarge { leftIconWidth: leftIconBbox <#> _.width, inputWidth: inputBbox.width }
316− else
317− Style.labelSmall
318− , layout: M.layout true
319− , transition: M.transition { duration: 0.18, ease: "easeOut" }
320− , _data:
321− Object.fromHomogeneous
322− { "has-focus": show props.isFocussed
323− , "invalid": show props.isInvalid
324− , "required": show props.isRequired
325− }
326− , initial: M.initial false
327− }
328− /> [ labelSpan [ R.text $ NonEmptyString.toString props.labelText ] ]
329− ]
330− ]
331−
332password ∷ ∀ p. ReactComponent { | p }
231password ∷ ∀ p. ReactComponent { | p }
333password =
232password =
334 mkForwardRefComponent "Password" do
233 mkForwardRefComponent "Password" do