     out))
 
 (def ^:private typeahead-state-initial
-  {:text ""
+  {:input-text ""
    :waiting? false
    :suggestions []})
 
 (defn- wrap [index count]
   (mod (+ count index) count))
 
-(defn- suggestion-select-prev
+(defn- select-prev
   [{:as state :keys [suggestions]}]
-  (update state :suggestion-selected-index #(-> % (or 0) dec (wrap (count suggestions)))))
-
-(defn- suggestion-select-next
+  (update state :selected-index #(-> % (or 0) dec (wrap (count suggestions)))))
+
+(defn- select-next
   [{:as state :keys [suggestions]}]
-  (update state :suggestion-selected-index #(-> % (or -1) inc (wrap (count suggestions)))))
-
-(defn- suggestion-select-set
+  (update state :selected-index #(-> % (or -1) inc (wrap (count suggestions)))))
+
+(defn- select-set
   [state i]
-  (assoc state :suggestion-selected-index i))
-
-(defn- suggestion-select-choose
-  [{:as state :keys [suggestions suggestion-selected-index]}]
-  (-> state
-      (assoc :model (nth suggestions suggestion-selected-index))
-      (dissoc :suggestions)))
-
-(defn- suggestion-select-reset
+  (assoc state :selected-index i))
+
+(defn- select-choose
+  [{:as state :keys [suggestions selected-index on-change]}]
+  (let [[search suggestion :as selected] (nth suggestions selected-index)]
+    (when on-change
+      (on-change suggestion))
+    (-> state
+        (assoc :model suggestion :input-text "")
+        (dissoc :suggestions))))
+
+(defn- select-reset
   [state]
-  (dissoc state :suggestion-selected-index))
+  (dissoc state :selected-index))
 
 (defn- reset-typeahead
   [state]
   (-> state
-      (assoc :waiting? false :suggestions [])
-      suggestion-select-reset))
+      (assoc :waiting? false :suggestions [] :input-text "")
+      select-reset))
 
 (defn- search-data-source
   "Call the user-supplied `data-source` fn and put the result on `c-sugg`.

  (when-let [key (keys-by-code (.-which event))]
    (.preventDefault event)
    (case key
      :up    (swap! state-atom suggestion-select-prev)
      :down  (swap! state-atom suggestion-select-next)
      :enter (swap! state-atom suggestion-select-choose)
      true)))

(defn- on-key-down

  [state-atom c-sugg]
  (go-loop []
    (let [[search suggestions] (<! c-sugg)]
      (when (= search (:input-text @state-atom))
        (swap! state-atom #(-> %
                               (assoc :suggestions suggestions :waiting? false)
                               select-reset))))
    (recur)))

(defn- make-typeahead-state
  [on-change]
  (let [c-input (chan)]
    (assoc typeahead-state-initial
           :on-change on-change
           :c-keypress (chan)
           :c-input c-input
           :c-search (debounce c-input 250) ;; FIXME hard-coded
