|
(ns app |
|
(:require [reagami.core :as r] |
|
[clojure.string :refer [includes?]])) |
|
|
|
(defonce !state (atom {:accumulator 0 :input ""})) |
|
|
|
(def root (js/document.getElementById "app")) |
|
|
|
|
|
|
|
(defn add-input [digit input] |
|
(swap! !state assoc :input (str input digit))) |
|
|
|
(defn view [{:keys [accumulator input]}] |
|
[:div |
|
[:h1 "reagami calculator"] |
|
[:div {:class "gui"} |
|
[:div {:class "row"} "accumulator: " [:span {:id "display" :style {:float "right"}} accumulator]] |
|
[:div {:class "row"} "input:" [:span {:id "input" :style {:float "right"}} input]] |
|
[:div {:class "row"} |
|
[:button {:id "clear" :on-click (fn [_] (swap! !state assoc :input ""))} "C"] |
|
[:button {:id "all-clear" :style {:width "4em"} :on-click (fn [_] (swap! !state assoc :input "" :accumulator 0))} "AC"] |
|
[:button {:id "divide" :on-click (fn [_] (swap! !state assoc :accumulator (/ accumulator (js/Number input)) :input ""))} "/"]] |
|
|
|
[:div {:class "row"} [:button {:id "seven" :on-click (fn [_] (add-input "7" input))} 7] |
|
[:button {:id "eight" :on-click (fn [_] (add-input "8" input))} 8] |
|
[:button {:id "nine" :on-click (fn [_] (add-input "9" input))} 9] |
|
[:button {:id "multiply" :on-click (fn [_] (swap! !state assoc :accumulator (* accumulator (js/Number input)) :input ""))} "x"]] |
|
[:div {:class "row"} [:button {:id "four" :on-click (fn [_] (add-input "4" input))} 4] |
|
[:button {:id "five" :on-click (fn [_] (add-input "5" input))} 5] |
|
[:button {:id "six" :on-click (fn [_] (add-input "6" input))} 6] |
|
[:button {:id "subtract" :on-click (fn [_] (swap! !state assoc :accumulator (- accumulator (js/Number input)) :input ""))} "-"]] |
|
[:div {:class "row"} [:button {:id "one" :on-click (fn [_] (add-input "1" input))} 1] |
|
[:button {:id "two" :on-click (fn [_] (add-input "2" input))} 2] |
|
[:button {:id "three" :on-click (fn [_] (add-input "3" input))} 3] |
|
[:button {:id "add" :on-click (fn [_] (swap! !state assoc :accumulator (+ accumulator (js/Number input)) :input ""))} "+"]] |
|
[:div {:class "row"} [:button {:id "zero" :on-click (fn [_] (add-input "0" input))} 0] |
|
[:button {:id "period" :on-click (fn [_] (when-not (includes? input ".") (add-input "." input)))} "."] |
|
[:button {:id "delete" :style {:width "4em"} :on-click (fn [_] (when (> (count input) 0) (swap! !state assoc :input (subs input 0 (dec (count input))))))} "<<"]]]]) |
|
|
|
(defn render! [] |
|
(r/render root (view @!state))) |
|
|
|
(add-watch !state ::render (fn [_ _ _ _] (render!))) |
|
(render!) |
|
|
|
;; the Squint Vite plugin calls this after a hot reload, so an edit repaints |
|
;; and the atom keeps its state |
|
(defn ^:dev/after-load re-render [] (render!)) |