|
|
@@ -6,35 +6,42 @@
|
|
|
|
|
|
(def mac? goog.userAgent/MAC)
|
|
|
(defn print-shortcut-key [key]
|
|
|
- (case key
|
|
|
- ("cmd" "command" "mod" "⌘" "meta") "⌘"
|
|
|
- ("return" "enter" "⏎") "⏎"
|
|
|
- ("shift" "⇧") "⇧"
|
|
|
- ("alt" "option" "opt" "⌥") "⌥"
|
|
|
- ("ctrl" "control" "⌃") "⌃"
|
|
|
- ("space" " ") " "
|
|
|
- ("up" "↑") "↑"
|
|
|
- ("down" "↓") "↓"
|
|
|
- ("left" "←") "←"
|
|
|
- ("right" "→") "→"
|
|
|
- ("tab") "⇥"
|
|
|
- ("open-square-bracket") "["
|
|
|
- ("close-square-bracket") "]"
|
|
|
- ("dash") "-"
|
|
|
- ("semicolon") ";"
|
|
|
- ("equals") "="
|
|
|
- ("single-quote") "'"
|
|
|
- ("backslash") "\\"
|
|
|
- ("comma") ","
|
|
|
- ("period") "."
|
|
|
- ("slash") "/"
|
|
|
- ("grave-accent") "`"
|
|
|
- ("page-up") ""
|
|
|
- ("page-down") ""
|
|
|
- (nil) ""
|
|
|
- (name key)))
|
|
|
+ (let [result (if (coll? key)
|
|
|
+ (string/join "+" key)
|
|
|
+ (case (if (string? key)
|
|
|
+ (string/lower-case key)
|
|
|
+ key)
|
|
|
+ ("cmd" "command" "mod" "⌘") (if mac? "⌘" "Ctrl")
|
|
|
+ ("meta") (if mac? "⌘" "⊞")
|
|
|
+ ("return" "enter" "⏎") "⏎"
|
|
|
+ ("shift" "⇧") "⇧"
|
|
|
+ ("alt" "option" "opt" "⌥") (if mac? "Opt" "Alt")
|
|
|
+ ("ctrl" "control" "⌃") "Ctrl"
|
|
|
+ ("space" " ") "Space"
|
|
|
+ ("up" "↑") "↑"
|
|
|
+ ("down" "↓") "↓"
|
|
|
+ ("left" "←") "←"
|
|
|
+ ("right" "→") "→"
|
|
|
+ ("tab") "Tab"
|
|
|
+ ("open-square-bracket") "["
|
|
|
+ ("close-square-bracket") "]"
|
|
|
+ ("dash") "-"
|
|
|
+ ("semicolon") ";"
|
|
|
+ ("equals") "="
|
|
|
+ ("single-quote") "'"
|
|
|
+ ("backslash") "\\"
|
|
|
+ ("comma") ","
|
|
|
+ ("period") "."
|
|
|
+ ("slash") "/"
|
|
|
+ ("grave-accent") "`"
|
|
|
+ ("page-up") ""
|
|
|
+ ("page-down") ""
|
|
|
+ (nil) ""
|
|
|
+ (name key)))]
|
|
|
+ (if (= (count result) 1)
|
|
|
+ result
|
|
|
+ (string/capitalize result))))
|
|
|
|
|
|
-;; TODO: shortcut component shouldn't worry about this
|
|
|
(defn to-string [input]
|
|
|
(cond
|
|
|
(string? input) input
|
|
|
@@ -45,57 +52,38 @@
|
|
|
(nil? input) ""
|
|
|
:else (pr-str input)))
|
|
|
|
|
|
+(defn- parse-shortcuts
|
|
|
+ [s]
|
|
|
+ (->> (string/split s #" \| ")
|
|
|
+ (map (fn [x]
|
|
|
+ (->> (string/split x #" ")
|
|
|
+ (map #(if (string/includes? % "+")
|
|
|
+ (string/split % #"\+")
|
|
|
+ %)))))))
|
|
|
+
|
|
|
+(rum/defc part
|
|
|
+ [context theme ks size]
|
|
|
+ (button/root {:theme theme
|
|
|
+ :interactive false
|
|
|
+ :tiled true
|
|
|
+ :tiles (map print-shortcut-key ks)
|
|
|
+ :size size
|
|
|
+ :mused true}
|
|
|
+ context))
|
|
|
+
|
|
|
(rum/defc root
|
|
|
- [shortcut context & {:keys [tiled size theme]
|
|
|
- :or {tiled true
|
|
|
- size :sm
|
|
|
+ [shortcut context & {:keys [size theme]
|
|
|
+ :or {size :sm
|
|
|
theme :gray}}]
|
|
|
(when (seq shortcut)
|
|
|
- (if (coll? shortcut)
|
|
|
- (let [texts (map print-shortcut-key shortcut)
|
|
|
- tiled? (every? #(= (count %) 1) texts)]
|
|
|
- (if tiled?
|
|
|
- [:div.flex.flex-row
|
|
|
- (for [text texts]
|
|
|
- (button/root {:theme theme
|
|
|
- :interactive false
|
|
|
- :text (to-string text)
|
|
|
- :tiled tiled?
|
|
|
- :size size
|
|
|
- :mused true}
|
|
|
- context))]
|
|
|
- (let [text' (string/join " " texts)]
|
|
|
- (button/root {:theme theme
|
|
|
- :interactive false
|
|
|
- :text text'
|
|
|
- :tiled false
|
|
|
- :size size
|
|
|
- :mused true}
|
|
|
- context))))
|
|
|
- [:<>
|
|
|
- (for [[index option] (map-indexed vector (string/split shortcut #" \| "))]
|
|
|
- [:<>
|
|
|
- (when (< 0 index)
|
|
|
- [:div.text-gray-11.text-sm "|"])
|
|
|
- (let [[system-default option] (if (.startsWith option "system default: ")
|
|
|
- [true (subs option 16)]
|
|
|
- [false option])]
|
|
|
- [:<>
|
|
|
- (when system-default
|
|
|
- [:div.mr-1.text-xs "System default: "])
|
|
|
- (for [sequence (string/split option #" ")
|
|
|
- :let [text (->> (string/split sequence #"\+")
|
|
|
- (map print-shortcut-key)
|
|
|
- (apply str))]]
|
|
|
- (let [tiled? (if (contains?
|
|
|
- #{"backspace" "delete" "home" "end" "insert"}
|
|
|
- (string/lower-case text))
|
|
|
- false
|
|
|
- tiled)]
|
|
|
- (button/root {:theme theme
|
|
|
- :interactive false
|
|
|
- :text (to-string text)
|
|
|
- :tiled tiled?
|
|
|
- :size size
|
|
|
- :mused true}
|
|
|
- context)))])])])))
|
|
|
+ (let [shortcuts (if (coll? shortcut)
|
|
|
+ [shortcut]
|
|
|
+ (parse-shortcuts shortcut))]
|
|
|
+ (for [[index binding] (map-indexed vector shortcuts)]
|
|
|
+ [:<>
|
|
|
+ (when (< 0 index)
|
|
|
+ [:div.text-gray-11.text-sm "|"])
|
|
|
+ (if (coll? (first binding)) ; + included
|
|
|
+ (for [ks binding]
|
|
|
+ (part context theme ks size))
|
|
|
+ (part context theme binding size))]))))
|