aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/main.css19
-rw-r--r--src/Lib/Dom/Element.ml9
-rw-r--r--src/Lib/Dom/Event.ml3
-rw-r--r--src/Lib/Dom/HE.ml2
-rw-r--r--src/Lib/FontAwesome.ml222
-rw-r--r--src/View/Form/Autocomplete.ml36
-rw-r--r--src/View/Map/Marker.ml28
7 files changed, 182 insertions, 137 deletions
diff --git a/public/main.css b/public/main.css
index c57ae2f..c93be65 100644
--- a/public/main.css
+++ b/public/main.css
@@ -38,8 +38,13 @@ body {
margin-bottom: 2rem;
}
+.g-Layout__Line {
+ display: flex;
+ align-items: center;
+}
+
.g-Layout__Line > *:not(:last-child) {
- margin-right: 2rem;
+ margin-right: 1.5rem;
}
/* Modal */
@@ -83,6 +88,10 @@ body {
font-size: 200%;
}
+.g-Modal__Close:hover {
+ background-color: #CCCCCC;
+}
+
/* Context menu */
:root {
@@ -139,7 +148,6 @@ body {
.g-Autocomplete {
position: relative;
- margin-bottom: 1rem;
}
.g-Autocomplete__Input {
@@ -206,6 +214,13 @@ body {
cursor: default;
}
+/* Marker form */
+
+.g-MarkerForm__Icon {
+ width: 1rem;
+ border: 1px solid #EEEEEE;
+}
+
/* Marker icon */
:root {
diff --git a/src/Lib/Dom/Element.ml b/src/Lib/Dom/Element.ml
index 391a95c..3c63ef4 100644
--- a/src/Lib/Dom/Element.ml
+++ b/src/Lib/Dom/Element.ml
@@ -1,10 +1,15 @@
-external set_value : Dom.element -> string -> unit = "value" [@@bs.set]
+external set_value : Dom.element -> string -> unit = "value"
+ [@@bs.set]
-external value : Dom.element -> string = "value" [@@bs.get]
+external value : Dom.element -> string = "value"
+ [@@bs.get]
external set_attribute : Dom.element -> string -> string -> unit = "setAttribute"
[@@bs.send]
+external set_class_name : Dom.element -> string -> unit = "className"
+ [@@bs.set]
+
external add_event_listener : Dom.element -> string -> (Dom.event -> unit) -> unit
= "addEventListener"
[@@bs.send]
diff --git a/src/Lib/Dom/Event.ml b/src/Lib/Dom/Event.ml
index 861afcf..9db46f0 100644
--- a/src/Lib/Dom/Event.ml
+++ b/src/Lib/Dom/Event.ml
@@ -1,6 +1,9 @@
external prevent_default : Dom.event -> unit = "preventDefault"
[@@bs.send]
+external stop_propagation : Dom.event -> unit = "stopPropagation"
+ [@@bs.send]
+
external target : Dom.event -> Dom.element = "target"
[@@bs.get]
diff --git a/src/Lib/Dom/HE.ml b/src/Lib/Dom/HE.ml
index 098259a..c9aac16 100644
--- a/src/Lib/Dom/HE.ml
+++ b/src/Lib/Dom/HE.ml
@@ -5,3 +5,5 @@ let on_click f = H.EventAttr ("click", f)
let on_input f = H.EventAttr ("input", f)
let on_submit f = H.EventAttr ("submit", f)
+
+let on_blur f = H.EventAttr ("blur", f)
diff --git a/src/Lib/FontAwesome.ml b/src/Lib/FontAwesome.ml
index ed8f5d5..daaf954 100644
--- a/src/Lib/FontAwesome.ml
+++ b/src/Lib/FontAwesome.ml
@@ -43,29 +43,29 @@ let icons =
; "arrows-alt"
; "arrows-h"
; "arrows-v"
- ; "asl-interpreting (alias)"
+ ; "asl-interpreting"
; "assistive-listening-systems"
; "asterisk"
; "at"
; "audio-description"
- ; "automobile (alias)"
+ ; "automobile"
; "backward"
; "balance-scale"
; "ban"
; "bandcamp"
- ; "bank (alias)"
+ ; "bank"
; "bar-chart"
- ; "bar-chart-o (alias)"
+ ; "bar-chart-o"
; "barcode"
; "bars"
; "bath"
- ; "bathtub (alias)"
- ; "battery (alias)"
- ; "battery-0 (alias)"
- ; "battery-1 (alias)"
- ; "battery-2 (alias)"
- ; "battery-3 (alias)"
- ; "battery-4 (alias)"
+ ; "bathtub"
+ ; "battery"
+ ; "battery-0"
+ ; "battery-1"
+ ; "battery-2"
+ ; "battery-3"
+ ; "battery-4"
; "battery-empty"
; "battery-full"
; "battery-half"
@@ -84,7 +84,7 @@ let icons =
; "birthday-cake"
; "bitbucket"
; "bitbucket-square"
- ; "bitcoin (alias)"
+ ; "bitcoin"
; "black-tie"
; "blind"
; "bluetooth"
@@ -105,7 +105,7 @@ let icons =
; "bullseye"
; "bus"
; "buysellads"
- ; "cab (alias)"
+ ; "cab"
; "calculator"
; "calendar"
; "calendar-check-o"
@@ -136,7 +136,7 @@ let icons =
; "cc-stripe"
; "cc-visa"
; "certificate"
- ; "chain (alias)"
+ ; "chain"
; "chain-broken"
; "check"
; "check-circle"
@@ -160,11 +160,11 @@ let icons =
; "clipboard"
; "clock-o"
; "clone"
- ; "close (alias)"
+ ; "close"
; "cloud"
; "cloud-download"
; "cloud-upload"
- ; "cny (alias)"
+ ; "cny"
; "code"
; "code-fork"
; "codepen"
@@ -183,7 +183,7 @@ let icons =
; "compress"
; "connectdevelop"
; "contao"
- ; "copy (alias)"
+ ; "copy"
; "copyright"
; "creative-commons"
; "credit-card"
@@ -193,29 +193,29 @@ let icons =
; "css3"
; "cube"
; "cubes"
- ; "cut (alias)"
+ ; "cut"
; "cutlery"
- ; "dashboard (alias)"
+ ; "dashboard"
; "dashcube"
; "database"
; "deaf"
- ; "deafness (alias)"
- ; "dedent (alias)"
+ ; "deafness"
+ ; "dedent"
; "delicious"
; "desktop"
; "deviantart"
; "diamond"
; "digg"
- ; "dollar (alias)"
+ ; "dollar"
; "dot-circle-o"
; "download"
; "dribbble"
- ; "drivers-license (alias)"
- ; "drivers-license-o (alias)"
+ ; "drivers-license"
+ ; "drivers-license-o"
; "dropbox"
; "drupal"
; "edge"
- ; "edit (alias)"
+ ; "edit"
; "eercast"
; "eject"
; "ellipsis-h"
@@ -230,7 +230,7 @@ let icons =
; "eraser"
; "etsy"
; "eur"
- ; "euro (alias)"
+ ; "euro"
; "exchange"
; "exclamation"
; "exclamation-circle"
@@ -242,15 +242,15 @@ let icons =
; "eye"
; "eye-slash"
; "eyedropper"
- ; "fa (alias)"
+ ; "fa"
; "facebook"
- ; "facebook-f (alias)"
+ ; "facebook-f"
; "facebook-official"
; "facebook-square"
; "fast-backward"
; "fast-forward"
; "fax"
- ; "feed (alias)"
+ ; "feed"
; "female"
; "fighter-jet"
; "file"
@@ -259,18 +259,18 @@ let icons =
; "file-code-o"
; "file-excel-o"
; "file-image-o"
- ; "file-movie-o (alias)"
+ ; "file-movie-o"
; "file-o"
; "file-pdf-o"
- ; "file-photo-o (alias)"
- ; "file-picture-o (alias)"
+ ; "file-photo-o"
+ ; "file-picture-o"
; "file-powerpoint-o"
- ; "file-sound-o (alias)"
+ ; "file-sound-o"
; "file-text"
; "file-text-o"
; "file-video-o"
; "file-word-o"
- ; "file-zip-o (alias)"
+ ; "file-zip-o"
; "files-o"
; "film"
; "filter"
@@ -281,7 +281,7 @@ let icons =
; "flag"
; "flag-checkered"
; "flag-o"
- ; "flash (alias)"
+ ; "flash"
; "flask"
; "flickr"
; "floppy-o"
@@ -302,9 +302,9 @@ let icons =
; "gamepad"
; "gavel"
; "gbp"
- ; "ge (alias)"
- ; "gear (alias)"
- ; "gears (alias)"
+ ; "ge"
+ ; "gear"
+ ; "gears"
; "genderless"
; "get-pocket"
; "gg"
@@ -316,24 +316,24 @@ let icons =
; "github-alt"
; "github-square"
; "gitlab"
- ; "gittip (alias)"
+ ; "gittip"
; "glass"
; "glide"
; "glide-g"
; "globe"
; "google"
; "google-plus"
- ; "google-plus-circle (alias)"
+ ; "google-plus-circle"
; "google-plus-official"
; "google-plus-square"
; "google-wallet"
; "graduation-cap"
; "gratipay"
; "grav"
- ; "group (alias)"
+ ; "group"
; "h-square"
; "hacker-news"
- ; "hand-grab-o (alias)"
+ ; "hand-grab-o"
; "hand-lizard-o"
; "hand-o-down"
; "hand-o-left"
@@ -345,9 +345,9 @@ let icons =
; "hand-rock-o"
; "hand-scissors-o"
; "hand-spock-o"
- ; "hand-stop-o (alias)"
+ ; "hand-stop-o"
; "handshake-o"
- ; "hard-of-hearing (alias)"
+ ; "hard-of-hearing"
; "hashtag"
; "hdd-o"
; "header"
@@ -358,11 +358,11 @@ let icons =
; "history"
; "home"
; "hospital-o"
- ; "hotel (alias)"
+ ; "hotel"
; "hourglass"
- ; "hourglass-1 (alias)"
- ; "hourglass-2 (alias)"
- ; "hourglass-3 (alias)"
+ ; "hourglass-1"
+ ; "hourglass-2"
+ ; "hourglass-3"
; "hourglass-end"
; "hourglass-half"
; "hourglass-o"
@@ -374,7 +374,7 @@ let icons =
; "id-card"
; "id-card-o"
; "ils"
- ; "image (alias)"
+ ; "image"
; "imdb"
; "inbox"
; "indent"
@@ -383,9 +383,9 @@ let icons =
; "info-circle"
; "inr"
; "instagram"
- ; "institution (alias)"
+ ; "institution"
; "internet-explorer"
- ; "intersex (alias)"
+ ; "intersex"
; "ioxhost"
; "italic"
; "joomla"
@@ -400,14 +400,14 @@ let icons =
; "lastfm-square"
; "leaf"
; "leanpub"
- ; "legal (alias)"
+ ; "legal"
; "lemon-o"
; "level-down"
; "level-up"
- ; "life-bouy (alias)"
- ; "life-buoy (alias)"
+ ; "life-bouy"
+ ; "life-buoy"
; "life-ring"
- ; "life-saver (alias)"
+ ; "life-saver"
; "lightbulb-o"
; "line-chart"
; "link"
@@ -428,9 +428,9 @@ let icons =
; "low-vision"
; "magic"
; "magnet"
- ; "mail-forward (alias)"
- ; "mail-reply (alias)"
- ; "mail-reply-all (alias)"
+ ; "mail-forward"
+ ; "mail-reply"
+ ; "mail-reply-all"
; "male"
; "map"
; "map-marker"
@@ -458,15 +458,15 @@ let icons =
; "minus-square-o"
; "mixcloud"
; "mobile"
- ; "mobile-phone (alias)"
+ ; "mobile-phone"
; "modx"
; "money"
; "moon-o"
- ; "mortar-board (alias)"
+ ; "mortar-board"
; "motorcycle"
; "mouse-pointer"
; "music"
- ; "navicon (alias)"
+ ; "navicon"
; "neuter"
; "newspaper-o"
; "object-group"
@@ -484,7 +484,7 @@ let icons =
; "paper-plane-o"
; "paperclip"
; "paragraph"
- ; "paste (alias)"
+ ; "paste"
; "pause"
; "pause-circle"
; "pause-circle-o"
@@ -496,7 +496,7 @@ let icons =
; "percent"
; "phone"
; "phone-square"
- ; "photo (alias)"
+ ; "photo"
; "picture-o"
; "pie-chart"
; "pied-piper"
@@ -527,7 +527,7 @@ let icons =
; "quora"
; "quote-left"
; "quote-right"
- ; "ra (alias)"
+ ; "ra"
; "random"
; "ravelry"
; "rebel"
@@ -537,44 +537,44 @@ let icons =
; "reddit-square"
; "refresh"
; "registered"
- ; "remove (alias)"
+ ; "remove"
; "renren"
- ; "reorder (alias)"
+ ; "reorder"
; "repeat"
; "reply"
; "reply-all"
- ; "resistance (alias)"
+ ; "resistance"
; "retweet"
- ; "rmb (alias)"
+ ; "rmb"
; "road"
; "rocket"
- ; "rotate-left (alias)"
- ; "rotate-right (alias)"
- ; "rouble (alias)"
+ ; "rotate-left"
+ ; "rotate-right"
+ ; "rouble"
; "rss"
; "rss-square"
; "rub"
- ; "ruble (alias)"
- ; "rupee (alias)"
- ; "s15 (alias)"
+ ; "ruble"
+ ; "rupee"
+ ; "s15"
; "safari"
- ; "save (alias)"
+ ; "save"
; "scissors"
; "scribd"
; "search"
; "search-minus"
; "search-plus"
; "sellsy"
- ; "send (alias)"
- ; "send-o (alias)"
+ ; "send"
+ ; "send-o"
; "server"
; "share"
; "share-alt"
; "share-alt-square"
; "share-square"
; "share-square-o"
- ; "shekel (alias)"
- ; "sheqel (alias)"
+ ; "shekel"
+ ; "sheqel"
; "shield"
; "ship"
; "shirtsinbulk"
@@ -586,7 +586,7 @@ let icons =
; "sign-language"
; "sign-out"
; "signal"
- ; "signing (alias)"
+ ; "signing"
; "simplybuilt"
; "sitemap"
; "skyatlas"
@@ -599,7 +599,7 @@ let icons =
; "snapchat-ghost"
; "snapchat-square"
; "snowflake-o"
- ; "soccer-ball-o (alias)"
+ ; "soccer-ball-o"
; "sort"
; "sort-alpha-asc"
; "sort-alpha-desc"
@@ -607,10 +607,10 @@ let icons =
; "sort-amount-desc"
; "sort-asc"
; "sort-desc"
- ; "sort-down (alias)"
+ ; "sort-down"
; "sort-numeric-asc"
; "sort-numeric-desc"
- ; "sort-up (alias)"
+ ; "sort-up"
; "soundcloud"
; "space-shuttle"
; "spinner"
@@ -622,8 +622,8 @@ let icons =
; "stack-overflow"
; "star"
; "star-half"
- ; "star-half-empty (alias)"
- ; "star-half-full (alias)"
+ ; "star-half-empty"
+ ; "star-half-full"
; "star-half-o"
; "star-o"
; "steam"
@@ -646,7 +646,7 @@ let icons =
; "sun-o"
; "superpowers"
; "superscript"
- ; "support (alias)"
+ ; "support"
; "table"
; "tablet"
; "tachometer"
@@ -664,12 +664,12 @@ let icons =
; "th-large"
; "th-list"
; "themeisle"
- ; "thermometer (alias)"
- ; "thermometer-0 (alias)"
- ; "thermometer-1 (alias)"
- ; "thermometer-2 (alias)"
- ; "thermometer-3 (alias)"
- ; "thermometer-4 (alias)"
+ ; "thermometer"
+ ; "thermometer-0"
+ ; "thermometer-1"
+ ; "thermometer-2"
+ ; "thermometer-3"
+ ; "thermometer-4"
; "thermometer-empty"
; "thermometer-full"
; "thermometer-half"
@@ -684,15 +684,15 @@ let icons =
; "times"
; "times-circle"
; "times-circle-o"
- ; "times-rectangle (alias)"
- ; "times-rectangle-o (alias)"
+ ; "times-rectangle"
+ ; "times-rectangle-o"
; "tint"
- ; "toggle-down (alias)"
- ; "toggle-left (alias)"
+ ; "toggle-down"
+ ; "toggle-left"
; "toggle-off"
; "toggle-on"
- ; "toggle-right (alias)"
- ; "toggle-up (alias)"
+ ; "toggle-right"
+ ; "toggle-up"
; "trademark"
; "train"
; "transgender"
@@ -708,8 +708,8 @@ let icons =
; "tty"
; "tumblr"
; "tumblr-square"
- ; "turkish-lira (alias)"
- ; "tv (alias)"
+ ; "turkish-lira"
+ ; "tv"
; "twitch"
; "twitter"
; "twitter-square"
@@ -718,10 +718,10 @@ let icons =
; "undo"
; "universal-access"
; "university"
- ; "unlink (alias)"
+ ; "unlink"
; "unlock"
; "unlock-alt"
- ; "unsorted (alias)"
+ ; "unsorted"
; "upload"
; "usb"
; "usd"
@@ -734,8 +734,8 @@ let icons =
; "user-secret"
; "user-times"
; "users"
- ; "vcard (alias)"
- ; "vcard-o (alias)"
+ ; "vcard"
+ ; "vcard-o"
; "venus"
; "venus-double"
; "venus-mars"
@@ -751,8 +751,8 @@ let icons =
; "volume-down"
; "volume-off"
; "volume-up"
- ; "warning (alias)"
- ; "wechat (alias)"
+ ; "warning"
+ ; "wechat"
; "weibo"
; "weixin"
; "whatsapp"
@@ -766,7 +766,7 @@ let icons =
; "window-minimize"
; "window-restore"
; "windows"
- ; "won (alias)"
+ ; "won"
; "wordpress"
; "wpbeginner"
; "wpexplorer"
@@ -775,12 +775,12 @@ let icons =
; "xing"
; "xing-square"
; "y-combinator"
- ; "y-combinator-square (alias)"
+ ; "y-combinator-square"
; "yahoo"
- ; "yc (alias)"
- ; "yc-square (alias)"
+ ; "yc"
+ ; "yc-square"
; "yelp"
- ; "yen (alias)"
+ ; "yen"
; "yoast"
; "youtube"
; "youtube-play"
diff --git a/src/View/Form/Autocomplete.ml b/src/View/Form/Autocomplete.ml
index 537316d..324a834 100644
--- a/src/View/Form/Autocomplete.ml
+++ b/src/View/Form/Autocomplete.ml
@@ -1,11 +1,8 @@
let search s xs =
- if s == "" then
- [| |]
- else
- let results = Js.Array.filter (Js.String.includes s) xs in
- if Js.Array.length results == 1 && results.(0) == s then [| |] else results
+ let results = Js.Array.filter (Js.String.includes s) xs in
+ if Js.Array.length results == 1 && results.(0) == s then [| |] else results
-let render_completion on_select entries =
+let render_completion render_entry on_select entries =
H.div
[| HA.class_ "g-Autocomplete__Completion" |]
(entries
@@ -13,11 +10,14 @@ let render_completion on_select entries =
H.button
[| HA.class_ "g-Autocomplete__Entry"
; HA.type_ "button"
- ; HE.on_click (fun _ -> on_select c)
+ ; HE.on_click (fun e ->
+ let () = Event.stop_propagation e in
+ let () = Event.prevent_default e in
+ on_select c)
|]
- [| H.text c |]))
+ (render_entry c)))
-let create id label values on_input attrs =
+let create attrs id values render_entry on_input =
let completion =
H.div [| |] [| |]
@@ -26,6 +26,7 @@ let create id label values on_input attrs =
let update_completion target value =
let entries = search value values in
Element.mount_on completion (render_completion
+ render_entry
(fun selected ->
let () = Element.set_value target selected in
let () = Element.remove_children completion in
@@ -33,15 +34,13 @@ let create id label values on_input attrs =
entries)
in
+ let hide_completion () =
+ Element.mount_on completion (H.text "")
+ in
+
H.div
[| HA.class_ "g-Autocomplete" |]
- [| H.div
- [| HA.class_ "g-Form__Label" |]
- [| H.label
- [| HA.for_ id |]
- [| H.text label |]
- |]
- ; H.input
+ [| H.input
(Js.Array.concat
[| HA.id id
; HA.class_ "g-Autocomplete__Input"
@@ -55,6 +54,11 @@ let create id label values on_input attrs =
let value = Element.value target in
let () = update_completion target value in
on_input value)
+ ; HE.on_blur (fun _ ->
+ let _ = Js.Global.setTimeout
+ (fun _ -> hide_completion ())
+ 100
+ in ())
|]
attrs)
[| |]
diff --git a/src/View/Map/Marker.ml b/src/View/Map/Marker.ml
index 58ec4bd..e793742 100644
--- a/src/View/Map/Marker.ml
+++ b/src/View/Map/Marker.ml
@@ -20,12 +20,28 @@ let form on_validate init_name init_color init_icon =
[| |]
[| Form.input "g-MarkerForm__Name" "Name" init_name (fun newName -> name := newName)
; Form.color_input "g-MarkerForm__Color" "Color" init_color (fun newColor -> color := newColor)
- ; Autocomplete.create
- "g-MarkerForm__Icon"
- "Icon"
- FontAwesome.icons
- (fun newIcon -> let () = Js.log newIcon in icon := newIcon)
- [| HA.value init_icon |]
+ ; H.div
+ [| HA.class_ "g-Form__Field" |]
+ [| H.div
+ [| HA.class_ "g-Form__Label" |]
+ [| H.label
+ [| HA.for_ "g-MarkerForm__IconInput" |]
+ [| H.text "Icon" |]
+ |]
+ ; let dom_icon = H.div [| HA.class_ ("fa fa-" ^ !icon) |] [| |] in
+ Layout.line
+ [| |]
+ [| H.div [| HA.class_ "g-MarkerForm__Icon" |] [| dom_icon |]
+ ; Autocomplete.create
+ [| HA.value init_icon |]
+ "g-MarkerForm__IconInput"
+ FontAwesome.icons
+ (fun icon -> [| H.div [| HA.class_ ("fa fa-" ^ icon) |] [| |] ; H.text icon |])
+ (fun newIcon ->
+ let () = icon := newIcon in
+ Element.set_class_name dom_icon ("fa fa-" ^ newIcon))
+ |]
+ |]
|]
; Layout.line
[| |]