@@ -0,0 +1,130 @@
1+module Yoga.Block.Atom.Input.View.Container where
2+
3+import Yoga.Prelude.View
4+import Data.Array as Array
5+import Data.Interpolate (i)
6+import Foreign.Object as Object
7+import Framer.Motion as M
8+import Partial.Unsafe (unsafeCrashWith)
9+import React.Basic.DOM (CSS, css)
10+import React.Basic.Emotion (Style)
11+import Yoga.Block.Atom.Input.Style as Style
12+
13+type PropsF f =
14+ ( css ∷ f Style
15+ , isInvalid ∷ f Boolean
16+ | Style.Props f (MandatoryProps ())
17+ )
18+
19+type MandatoryProps r =
20+ ( children ∷ Array JSX
21+ , hasFocus ∷ Boolean
22+ | r
23+ )
24+
25+type Props =
26+ PropsF Id
27+
28+type PropsOptional =
29+ PropsF OptionalProp
30+
31+component ∷ ∀ p q. Union p q Props => ReactComponent { | MandatoryProps p }
32+component = rawContainer
33+
34+type Propski =
35+ { css ∷ OptionalProp Style
36+ , hasFocus ∷ Boolean
37+ , isInvalid ∷ OptionalProp Boolean
38+ , children ∷ Array JSX
39+ }
40+
41+rawContainer ∷ ∀ p. ReactComponent { | p }
42+rawContainer =
43+ mkForwardRefComponent "InputContainer" do
44+ \(props ∷ { | PropsOptional }) ref -> React.do
45+ let
46+ result =
47+ M.div
48+ </* M.motion
49+ { variants: M.variants containerVariants
50+ , animate: M.animate if props.hasFocus then containerVariantLabels.focussed else containerVariantLabels.blurred
51+ }
52+ { className: "ry-input-container"
53+ , css: Style.inputContainer props
54+ , _data:
55+ props.isInvalid
56+ # foldMap \isInvalid ->
57+ Object.fromHomogeneous
58+ { "invalid": show isInvalid
59+ }
60+ , ref
61+ }
62+ /> props.children
63+ pure result
64+
65+drawPathUntil ∷ Int -> Array Point -> String
66+drawPathUntil idx thePath = do
67+ let fn { x, y } = i x "%" " " y "%"
68+ let firstFew = Array.take idx thePath
69+ let lastFew = Array.drop idx thePath $> (Array.last firstFew # fromMaybe' \_ -> unsafeCrashWith "ogod")
70+ let rendered = intercalate "," $ fn <$> (firstFew <> lastFew)
71+ i "polygon(" rendered ")"
72+
73+path ∷ Array Point
74+path = mkPath 4 8
75+
76+mkPath ∷ Int -> Int -> Array Point
77+mkPath borderX borderY = do
78+ let
79+ inside =
80+ [ {- ⌜ -} p borderX borderY
81+ , {- ⌞ -} p borderX (100 - borderY)
82+ , {- ⌟ -} p (100 - borderX) (100 - borderY)
83+ , {- ⌝ -} p (100 - borderX) borderY
84+ , {- ⌜ -} p borderX borderY
85+ ]
86+ outside =
87+ [ {-⌜ -} p 0 0
88+ , {-⌞ -} p 0 100
89+ , {- . -} p 25 100
90+ , {- . -} p 50 100
91+ , {- . -} p 75 100
92+ , {- ⌟-} p 100 100
93+ , {- ⌝-} p 100 0
94+ , {- ^ -} p 75 0
95+ , {- ^ -} p 50 0
96+ , {- ^ -} p 25 0
97+ , {-⌜ -} p 0 0
98+ ]
99+ inside <> outside <> (Array.reverse inside)
100+ where
101+ p ∷ Int -> Int -> Point
102+ p x y = { x, y }
103+
104+containerVariantLabels ∷
105+ { blurred ∷ M.VariantLabel
106+ , focussed ∷ M.VariantLabel
107+ }
108+containerVariantLabels = M.makeVariantLabels containerVariants
109+
110+containerVariants ∷
111+ { blurred ∷ CSS
112+ , focussed ∷ CSS
113+ }
114+containerVariants =
115+ { focussed:
116+ css
117+ { clipPath
118+ , transition: { duration: 0.6 }
119+ }
120+ , blurred:
121+ css
122+ { clipPath:
123+ drawPathUntil (Array.length path + 1) path
124+ }
125+ }
126+ where
127+ clipPath = 6 Array... (Array.length path) <#> \ln -> drawPathUntil ln path
128+
129+type Point =
130+ { x ∷ Int, y ∷ Int }