<commit_before>(ns reabledit.cells.dropdown
  (:require [reabledit.util :as util]
            [clojure.string :as str]
            [reagent.core :as reagent]
            [goog.dom :as dom]))

(defn set-state!
  [state v]
  (swap! state assoc :edit? true :selected v))

(defn handle-key-down
  [e state options k commit!]
  (let [keycode (.-keyCode e)
        {:keys [edit? selected]} @state
        position (util/find-index (map :key options) selected)
        set-selected! (fn [k]
                        (.preventDefault e)
                        (.stopPropagation e)
                        (set-state! state k))]
    (cond

      ;; Enter and F2 start edit mode with old value
      (and (not edit?) (or (= keycode 13) (= keycode 113)))
      (set-selected! k)

      ;; Arrow keys navigate the dropdown up and down
      (and edit? (= keycode 38))
      (if (zero? position)
        (set-selected! (-> options last :key))
        (set-selected! (:key (nth options (dec position)))))

      (and edit? (= keycode 40))
      (if (= position (-> options count dec))
        (set-selected! (-> options first :key))
        (set-selected! (:key (nth options (inc position)))))

      ;; Enter commits the changes when dropdown is edit
      (and edit? (= keycode 13))
      (commit!)

      ;; Navigation with arrow keys is blocked when dropdown is edit
      (and edit? (contains? #{37 39} keycode))
      (.stopPropagation e)

      :else nil)))

(defn handle-on-change
  [e state options k]
  (let [input (str/lower-case (-> e .-target .-value))
        option (first (filter #(str/starts-with? (-> % :value str/lower-case)
                                                 input)
                              options))]
    (set-state! state (or (:key option) k))))

(defn handle-paste
  [e state options commit!]
  (let [input (str/lower-case (util/get-clipboard-data e))
        option (first (filter #(= (-> % :value str/lower-case)
                                  input)
                              options))]
    (when option
      (set-state! state (:key option))
      (commit!))))

(defn dropdown-cell
  [{:keys [row-data column-key commit! opts]}]
  (let [state (reagent/atom nil)]
    (reagent/create-class
     {:component-did-mount
      (fn [this]
        (util/add-blur-emulator! state
                                 #(if-not (dom/contains this (.-target %))
                                    (swap! state dissoc :edit? :selected))))
      :component-will-unmount
      (fn [_]
        (util/remove-blur-emulator! state))
      :reagent-render
      (fn [{:keys [row-data column-key commit! opts]}]
        (let [options (:options opts)
              k (get row-data column-key)
              v (-> (filter #(= (:key %) k) options) first :value)
              commit! (fn []
                        (if (and (:edit? @state) (not= (:selected @state) k))
                          (commit! (assoc row-data
                                          column-key<commit_msg>Fix bug where dropdown options would not appear when clicking toggle button<commit_after>(ns reabledit.cells.dropdown
  (:require [reabledit.util :as util]
            [clojure.string :as str]
            [reagent.core :as reagent]
            [goog.dom :as dom]))

(defn set-state!
  [state v]
  (swap! state assoc :edit? true :selected v))

(defn handle-key-down
  [e state options k commit!]
  (let [keycode (.-keyCode e)
        {:keys [edit? selected]} @state
        position (util/find-index (map :key options) selected)
        set-selected! (fn [k]
                        (.preventDefault e)
                        (.stopPropagation e)
                        (set-state! state k))]
    (cond

      ;; Enter and F2 start edit mode with old value
      (and (not edit?) (or (= keycode 13) (= keycode 113)))
      (set-selected! k)

      ;; Arrow keys navigate the dropdown up and down
      (and edit? (= keycode 38))
      (if (zero? position)
        (set-selected! (-> options last :key))
        (set-selected! (:key (nth options (dec position)))))

      (and edit? (= keycode 40))
      (if (= position (-> options count dec))
        (set-selected! (-> options first :key))
        (set-selected! (:key (nth options (inc position)))))

      ;; Enter commits the changes when dropdown is edit
      (and edit? (= keycode 13))
      (commit!)

      ;; Navigation with arrow keys is blocked when dropdown is edit
      (and edit? (contains? #{37 39} keycode))
      (.stopPropagation e)

      :else nil)))

(defn handle-on-change
  [e state options k]
  (let [input (str/lower-case (-> e .-target .-value))
        option (first (filter #(str/starts-with? (-> % :value str/lower-case)
                                                 input)
                              options))]
    (set-state! state (or (:key option) k))))

(defn handle-paste
  [e state options commit!]
  (let [input (str/lower-case (util/get-clipboard-data e))
        option (first (filter #(= (-> % :value str/lower-case)
                                  input)
                              options))]
    (when option
      (set-state! state (:key option))
      (commit!))))

(defn dropdown-cell
  [{:keys [row-data column-key commit! opts]}]
  (let [state (reagent/atom nil)]
    (reagent/create-class
     {:component-did-mount
      (fn [this]
        (util/add-blur-emulator! state
                                 #(if-not (dom/getAncestorByClass (.-target %)
                                                                  "reabledit-dropdown-cell")
                                    (swap! state dissoc :edit? :selected))))
      :component-will-unmount
      (fn [_]
        (util/remove-blur-emulator! state))
      :reagent-render
      (fn [{:keys [row-data column-key commit! opts]}]
        (let [options (:options opts)
              k (get row-data column-key)
              v (-> (filter #(= (:key %) k) options) first :value)
              commit! (fn []
                        (if (and (:edit? @state) (not= (:selected @state) k))
                          (commit! (assoc row-data
                                          column-key
{'fraction_non_alphanumeric': 0.13749390541199416, 'fraction_numerical': 0.00520071509832602, 'mean_word_length': 1.6756521739130434, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2343662', 'n_tokens_mistral': 1884, 'n_tokens_neox': 1761, 'n_words': 552}