git.iko.soy/rowtype-yoga/psfp
on 557f5b0 help sign in
131 lines 4.1 kB history raw
1module Editor where
3import Prelude
4import CSS.Safer (cssSafer)
5import Control.Promise (Promise)
6import Control.Promise as Promise
7import Data.Maybe (Maybe(..))
8import Data.Nullable (notNull, null)
9import Effect (Effect)
10import Effect.Aff (Aff)
11import Effect.Class (liftEffect)
12import Effect.Class.Console (warn)
13import Effect.Uncurried (EffectFn2, mkEffectFn2)
14import Foreign (Foreign, unsafeToForeign)
15import Prim.Row (class Union)
16import React.Basic (JSX, ReactComponent, element, fragment)
17import React.Basic.DOM as R
18import React.Basic.Events (handler_)
19import React.Basic.Hooks (component, readRefMaybe, useRef, writeRef)
20import React.Basic.Hooks as React
21import React.Basic.Hooks.Aff (useAff)
22import React.Helpers (wrapperDiv)
23import Theme.Styles (makeStyles_)
24import Web.DOM (Node)
26type EditorProps
27 = ( value ∷ String
28 , language ∷ String
29 , editorDidMount ∷ EffectFn2 Node Editor Unit
30 , theme ∷ String
31 , line ∷ Number
32 , width ∷ String
33 , height ∷ String
34 , loading ∷ JSX
35 , options ∷ Foreign
36 )
38foreign import editorImpl ∷ ∀ attrs. ReactComponent { | attrs }
40foreign import initMonacoImpl ∷ Effect (Promise Monaco)
42foreign import defineThemeImpl ∷ Monaco -> String -> MonacoTheme -> Effect Unit
44foreign import setThemeImpl ∷ Monaco -> String -> Effect Unit
46foreign import nightOwlTheme ∷ MonacoTheme
48foreign import getValue ∷ Editor -> Effect String
50foreign import data Monaco ∷ Type
52foreign import data Editor ∷ Type
54foreign import data MonacoTheme ∷ Type
56editor ∷
57 ∀ attrs attrs_. Union attrs attrs_ EditorProps => ReactComponent { | attrs }
58editor = editorImpl
60initMonaco ∷ Aff Monaco
61initMonaco = liftEffect initMonacoImpl >>= Promise.toAff
63themeName ∷ String
64themeName = "NightOwl"
66foreign import data MonarchLanguage ∷ Type
68foreign import purescriptSyntax ∷ MonarchLanguage
70foreign import registerLanguageImpl ∷ Monaco -> String -> Effect Unit
72foreign import setMonarchTokensProviderImpl ∷ Monaco -> String -> MonarchLanguage -> Effect Unit
74mkEditor ∷ Effect (ReactComponent {})
75mkEditor = do
76 useStyles <-
77 makeStyles_
78 { wrapper:
79 cssSafer
80 { margin: "0"
81 , boxSizing: "border-box"
82 , padding: "35px 40px"
83 , width: "100%"
84 , height: "100%"
85 , borderRadius: "32px"
86 , backgroundColor: "#011627"
87 }
88 }
89 component "Editor" \{} -> React.do
90 classes <- useStyles
91 ref <- useRef null
92 useAff unit
93 $ do
94 monaco <- initMonaco
95 defineThemeImpl monaco themeName nightOwlTheme # liftEffect
96 setThemeImpl monaco themeName # liftEffect
97 registerLanguageImpl monaco "purescript" # liftEffect
98 setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
99 pure
100 $ fragment
101 [ R.button
102 { onClick:
103 handler_ do
104 maybeEditor <- readRefMaybe ref
105 case maybeEditor of
106 Nothing -> pure unit
107 Just ed -> do
108 v <- getValue ed
109 warn $ "Value: " <> v
110 }
111 , wrapperDiv { className: classes.wrapper }
112 $ element editor
113 { theme: themeName
114 , options:
115 unsafeToForeign
116 { fontFamily: "PragmataPro"
117 , fontLigatures: true
118 , fontSize: "16pt"
119 , lineNumbers: "off"
120 , glyphMargin: false
121 , folding: false
122 , lineDecorationsWidth: 0
123 , lineNumbersMinChars: 0
124 , minimap: { enabled: false }
125 }
126 , language: "purescript"
127 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
128 , editorDidMount:
129 mkEffectFn2 \_ -> notNull >>> writeRef ref
130 }
131 ]