BaseModal.purs 3.82 KB
Newer Older
arturo's avatar
arturo committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
module Gargantext.Components.Bootstrap.BaseModal (baseModal) where

import Gargantext.Prelude

import DOM.Simple (Window)
import Data.Foldable (intercalate)
import Effect (Effect)
import Effect.Uncurried (EffectFn2, runEffectFn2)
import Gargantext.Utils (nbsp, (?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T

foreign import _addClassName :: EffectFn2 Window String Unit
foreign import _removeClassName :: EffectFn2 Window String Unit

type Props =
  ( isVisibleBox :: T.Box Boolean
  | Options
  )

type Options =
  ( id :: String
  , title :: String
  , hasBackground :: Boolean
  , hasCollapsibleBackground :: Boolean
  )

options :: Record Options
options =
  { id: ""
  , title: ""
  , hasBackground: true
  , hasCollapsibleBackground: true
  }

componentName :: String
componentName = "b-modal"

vendorName :: String
vendorName = "modal"

baseModal :: forall r. R2.OptComponent Options Props r
baseModal = R2.optComponent component options

component :: R.Component Props
component = R.hooksComponent componentName cpt where
  cpt { isVisibleBox
      , id
      , title
      , hasBackground
      , hasCollapsibleBackground
      } children = do
    -- State
    isVisible <- R2.useLive' isVisibleBox

    -- Hooks
    -- R.useEffect1' isVisible $
      -- (isVisible ? addClassName $ removeClassName) window "modal-open"

    -- Computed
    let
      className = intercalate " "
        -- Component
        [ componentName
        , isVisible ?
            componentName <> "--visible" $
            componentName <> "--hidden"
        -- Vendor
        , vendorName
        ]

      hasHeader = not $ eq title ""

    -- Render
    R.createPortal
      [
        H.div
        { id
        , className
        , role: "dialog"
        , data: { show: true }
        }
        [
          R2.if' (hasBackground) $
            H.div
            { className: intercalate " "
                [ componentName <> "__overlay"
                , hasCollapsibleBackground ?
                    componentName <> "__overlay--collapsible" $
                    ""
                ]
            , on: { click: hasCollapsibleBackground ?
                      toggle isVisibleBox $
                      const $ pure unit
                  }
            }
            [ H.text $ nbsp 1 ]
        ,
          H.div
          { className: "modal-dialog modal-lg"
          , role: "document"
          }
          [
            H.div
            { className: intercalate " "
                [ componentName <> "__content"
                , vendorName <> "-content"
                ]
            }
            [
              R2.if' (hasHeader) $
                H.div
                { className: intercalate " "
                    [ componentName <> "__header"
                    , vendorName <> "-header"
                    ]
                }
                [
                  H.div
                  { className: componentName <> "__header__content" }
                  [ H.text title ]
                ,
                  H.button
                  { type: "button"
                  , className: "close"
                  , data: { dismiss: "modal" }
                  }
                  [
                    H.a
                    { on: { click: toggle isVisibleBox }
                    , className: "btn fa fa-times" }
                    []
                  ]
                ]
            ,
              H.div
              { className: "modal-body" }
              children
            ]
          ]
        ]
      ]
      <$> R2.getPortalHost


toggle :: forall event. T.Box Boolean -> event -> Effect Unit
toggle box _ = T.modify_ not box

addClassName :: Window -> String -> Effect Unit
addClassName = runEffectFn2 _addClassName

removeClassName :: Window -> String -> Effect Unit
removeClassName = runEffectFn2 _removeClassName