Skip to content

Instantly share code, notes, and snippets.

@Conaws
Last active December 19, 2016 01:44
Show Gist options
  • Save Conaws/0c191c29f9e9f3781efa4b3535d28e7f to your computer and use it in GitHub Desktop.
Save Conaws/0c191c29f9e9f3781efa4b3535d28e7f to your computer and use it in GitHub Desktop.
(ns polya.multi
(:require
[reagent.core :as r])
(:require-macros
[devcards.core :refer [defcard-rg]]))
(defn multi [{:keys [highlight-class
placeholder
item-class
list-class
options
save! selections on-delete]}]
(let [a (r/atom "")
selected-index (r/atom -1)
typeahead-hidden? (r/atom false)
mouse-on-list? (r/atom false)
]
(fn []
(let [options (if (clojure.string/blank? @a)
[]
(filter
#(-> % (.toLowerCase %) (.indexOf (.toLowerCase @a)) (> -1))
options))
matching-options (filter (comp not (set @selections)) options)
choose-selected #(if (and (not-empty matching-options)
(> @selected-index -1))
(let [choice (nth matching-options @selected-index)]
(save! choice)
(reset! selected-index 0)
(reset! a ""))
(when (not (str/blank? @a))
(do
(save! @a)
(reset! selected-index 0)
(reset! a ""))))
]
[:div.tags.flex
[:div.tags-output
(when @selections
(for [x @selections]
^{:key x}[:button {:on-click #(swap! selections (fn [y] (remove #{x} y)))}(str x)]
))
[:input.tags-input
{:value @a
:placeholder placeholder
;; (if (empty? @selections ) placeholder nil)
:on-change #(reset! a (-> % .-target .-value))
:on-key-down #(do
(case (.-which %)
38 (do
(.preventDefault %)
(when-not (= @selected-index -1)
(swap! selected-index dec)))
40 (do
(.preventDefault %)
(when-not (= @selected-index (dec (count matching-options)))
(swap! selected-index inc)))
9 (choose-selected)
13 (choose-selected)
8 (when (clojure.string/blank? @a)
(on-delete))
27 (do #_(reset! typeahead-hidden? true)
(reset! selected-index -1))
"default"))}]
[:ul {:style
{:display (if (or (empty? matching-options) @typeahead-hidden?) :none :block) }
:class list-class
:on-mouse-enter #(reset! mouse-on-list? true)
:on-mouse-leave #(reset! mouse-on-list? false)}
(doall
(map-indexed
(fn [index result]
[:li {:tab-index index
:key index
:class (if (= @selected-index index) highlight-class item-class)
:on-mouse-over #(do
(reset! selected-index (js/parseInt (.getAttribute (.-target %) "tabIndex"))))
:on-click #(do
(reset! a "")
(save! result)
)}
result])
matching-options))]]])
)))
(defcard-rg tags-example
(let [selections (r/atom ["A" "B" "Conor Rules"])]
[multi {:highlight-class "highlight"
:selections selections
:on-delete #(swap! selections pop)
:save! #(swap! selections conj %)
:options ["Reagent""Re-frame""Re-com""Reaction"]}]))
.tags {
display:inline-block;
border: 0.1px solid grey;
/* font:normal normal normal 16px/18px Helmet,FreeSans,Sans-Serif; */
/* color:black; */
padding:4px 4px 0 0;
cursor:text;
transition: border-color 0s ease-out 0.3s, border-width 0.1s ease-out;
}
.tags-input {
display:inline-block;
width:10em;
margin:0 0 4px;
padding:4px 6px;
background:none;
border: 0;
outline:0;
font:inherit;
color:inherit;
text-align:left;
text-shadow:none;
}
.tags-output {
display:inline-block;
margin-left:4px;
}
.tags-output-item {
display:inline-block;
background-color:red;
margin:0 4px 4px 0;
padding:4px 6px;
border-radius:2px;
cursor:default;
}
.highlight {
background-color: #ccc;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment