mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 14:14:55 +00:00
redesigned Shortcut component
This commit is contained in:
312
deps/shui/src/logseq/shui/shortcut/v2.cljs
vendored
Normal file
312
deps/shui/src/logseq/shui/shortcut/v2.cljs
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
(ns logseq.shui.shortcut.v2
|
||||
"Unified keyboard shortcut component with three styles: combo, separate, and compact.
|
||||
|
||||
Expected shortcut formats:
|
||||
- Combo keys (simultaneous): \"shift+cmd\", [\"shift\" \"cmd\"], or [[\"shift\" \"cmd\"]]
|
||||
- Separate keys (sequential): [\"cmd\" \"up\"], or [\"cmd\" \"k\"]
|
||||
- Compact: same formats but with :style :compact
|
||||
|
||||
Platform mapping:
|
||||
- :mod or \"mod\" maps to ⌘ on macOS, Ctrl on Windows/Linux
|
||||
- Other keys are mapped via print-shortcut-key function"
|
||||
(:require [clojure.string :as string]
|
||||
[goog.userAgent]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(def mac? goog.userAgent/MAC)
|
||||
|
||||
(defn print-shortcut-key
|
||||
"Maps logical keys to display keys, with platform-specific handling.
|
||||
Supports :mod for platform-agnostic modifier key.
|
||||
Automatically uppercases single letter keys (a-z) while preserving
|
||||
multi-character keys like Ctrl, Backspace, Delete, Opt, etc."
|
||||
[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") ""
|
||||
("esc" "escape") "Esc"
|
||||
("backspace") "Backspace"
|
||||
("delete") "Delete"
|
||||
(nil) ""
|
||||
(name key)))
|
||||
;; If result is a single letter (a-z), uppercase it
|
||||
;; Otherwise, capitalize only if it's a single character (for symbols)
|
||||
final-result (cond
|
||||
(and (= (count result) 1)
|
||||
(re-matches #"[a-z]" result))
|
||||
(string/upper-case result)
|
||||
|
||||
(= (count result) 1)
|
||||
result
|
||||
|
||||
:else
|
||||
(string/capitalize result))]
|
||||
final-result))
|
||||
|
||||
(defn- flatten-keys
|
||||
"Recursively flattens nested collections, preserving strings."
|
||||
[coll]
|
||||
(mapcat (fn [x]
|
||||
(if (and (coll? x) (not (string? x)))
|
||||
(flatten-keys x)
|
||||
[x]))
|
||||
coll))
|
||||
|
||||
(defn- normalize-binding
|
||||
"Normalizes a shortcut binding to a string format for data attributes.
|
||||
Examples: 'cmd+k', 'shift+cmd+k', 'cmd up'"
|
||||
[binding]
|
||||
(cond
|
||||
(string? binding)
|
||||
(string/lower-case (string/trim binding))
|
||||
|
||||
(coll? binding)
|
||||
(let [first-item (first binding)
|
||||
keys (flatten-keys binding)
|
||||
normalize-key (fn [k]
|
||||
(cond
|
||||
(string? k) (string/lower-case k)
|
||||
(keyword? k) (name k)
|
||||
(symbol? k) (name k)
|
||||
(number? k) (str k)
|
||||
:else (str k)))]
|
||||
(string/join "+" (map normalize-key keys)))
|
||||
|
||||
(keyword? binding)
|
||||
(name binding)
|
||||
|
||||
(symbol? binding)
|
||||
(name binding)
|
||||
|
||||
:else
|
||||
(str binding)))
|
||||
|
||||
(defn- detect-style
|
||||
"Automatically detects style from shortcut format.
|
||||
Returns :combo, :separate, or :compact"
|
||||
[shortcut]
|
||||
(cond
|
||||
(string? shortcut)
|
||||
(if (string/includes? shortcut "+")
|
||||
:combo
|
||||
:separate)
|
||||
|
||||
(coll? shortcut)
|
||||
(let [first-item (first shortcut)]
|
||||
(cond
|
||||
(coll? first-item) :combo ; nested collection means combo
|
||||
(string/includes? (str first-item) "+") :combo
|
||||
:else :separate))
|
||||
|
||||
:else :separate))
|
||||
|
||||
(defn- parse-shortcuts
|
||||
"Parses shortcut string into structured format.
|
||||
Handles ' | ' separator for multiple shortcuts."
|
||||
[s]
|
||||
(->> (string/split s #" \| ")
|
||||
(map (fn [x]
|
||||
(->> (string/split x #" ")
|
||||
(map #(if (string/includes? % "+")
|
||||
(string/split % #"\+")
|
||||
%)))))))
|
||||
|
||||
(defn shortcut-press!
|
||||
"Central helper to trigger key press animation.
|
||||
Finds all nodes with matching data-shortcut-binding and toggles pressed class.
|
||||
Optionally highlights parent row.
|
||||
|
||||
Args:
|
||||
- binding: normalized shortcut binding string (e.g., \"cmd+k\")
|
||||
- highlight-row?: if true, also highlights parent row (default: false)"
|
||||
([binding] (shortcut-press! binding false))
|
||||
([binding highlight-row?]
|
||||
(let [normalized (normalize-binding binding)
|
||||
selector (str "[data-shortcut-binding=\"" normalized "\"]")
|
||||
elements (.querySelectorAll js/document selector)]
|
||||
(doseq [^js el (array-seq elements)]
|
||||
(.add (.-classList el) "shui-shortcut-key-pressed")
|
||||
(when highlight-row?
|
||||
(let [^js row (or (.closest el ".shui-shortcut-row")
|
||||
(.-parentElement el))]
|
||||
(when row
|
||||
(.add (.-classList row) "shui-shortcut-row--pressed"))))
|
||||
;; Auto-reset after animation duration
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(.remove (.-classList el) "shui-shortcut-key-pressed")
|
||||
(when highlight-row?
|
||||
(let [^js row (or (.closest el ".shui-shortcut-row")
|
||||
(.-parentElement el))]
|
||||
(when row
|
||||
(.remove (.-classList row) "shui-shortcut-row--pressed")))))
|
||||
160)))))
|
||||
|
||||
(rum/defc combo-keys
|
||||
"Renders combo keys (simultaneous key combinations) with separator."
|
||||
[keys binding {:keys [interactive? aria-label aria-hidden? glow?]}]
|
||||
(let [key-elements (map print-shortcut-key keys)
|
||||
normalized-binding (normalize-binding binding)
|
||||
container-class (str "shui-shortcut-combo" (when glow? " shui-shortcut-glow"))
|
||||
container-attrs {:class container-class
|
||||
:data-shortcut-binding normalized-binding
|
||||
:style {:white-space "nowrap"}}
|
||||
container-attrs (if aria-label
|
||||
(assoc container-attrs :aria-label aria-label)
|
||||
container-attrs)
|
||||
container-attrs (if aria-hidden?
|
||||
(assoc container-attrs :aria-hidden "true")
|
||||
container-attrs)]
|
||||
[:div container-attrs
|
||||
(for [[index key-text] (map-indexed vector key-elements)]
|
||||
(list
|
||||
(when (< 0 index)
|
||||
[:span.shui-shortcut-separator {:key (str "sep-" index)}])
|
||||
[:kbd.shui-shortcut-key
|
||||
{:key (str "combo-key-" index)
|
||||
:aria-hidden (if aria-label "true" "false")
|
||||
:tab-index (if interactive? 0 -1)
|
||||
:role (when interactive? "button")}
|
||||
key-text]))]))
|
||||
|
||||
(rum/defc separate-keys
|
||||
"Renders separate keys (sequential key presses) with 4px gap."
|
||||
[keys binding {:keys [interactive? aria-label aria-hidden? glow?]}]
|
||||
(let [key-elements (map print-shortcut-key keys)
|
||||
normalized-binding (normalize-binding binding)
|
||||
container-class (str "shui-shortcut-separate" (when glow? " shui-shortcut-glow"))
|
||||
container-attrs {:class container-class
|
||||
:data-shortcut-binding normalized-binding
|
||||
:style {:white-space "nowrap"
|
||||
:gap "4px"}}
|
||||
container-attrs (if aria-label
|
||||
(assoc container-attrs :aria-label aria-label)
|
||||
container-attrs)
|
||||
container-attrs (if aria-hidden?
|
||||
(assoc container-attrs :aria-hidden "true")
|
||||
container-attrs)]
|
||||
[:div container-attrs
|
||||
(for [[index key-text] (map-indexed vector key-elements)]
|
||||
[:kbd.shui-shortcut-key
|
||||
{:key (str "separate-key-" index)
|
||||
:aria-hidden (if aria-label "true" "false")
|
||||
:tab-index (if interactive? 0 -1)
|
||||
:role (when interactive? "button")
|
||||
:style {:min-width "fit-content"}}
|
||||
key-text])]))
|
||||
|
||||
(rum/defc compact-keys
|
||||
"Renders compact style (text-only, minimal styling)."
|
||||
[keys binding {:keys [aria-label aria-hidden?]}]
|
||||
(let [key-elements (map print-shortcut-key keys)
|
||||
normalized-binding (normalize-binding binding)
|
||||
container-attrs {:class "shui-shortcut-compact"
|
||||
:data-shortcut-binding normalized-binding
|
||||
:style {:white-space "nowrap"}}
|
||||
container-attrs (if aria-label
|
||||
(assoc container-attrs :aria-label aria-label)
|
||||
container-attrs)
|
||||
container-attrs (if aria-hidden?
|
||||
(assoc container-attrs :aria-hidden "true")
|
||||
container-attrs)]
|
||||
[:div container-attrs
|
||||
(for [[index key-text] (map-indexed vector key-elements)]
|
||||
[:span
|
||||
{:key (str "compact-key-" index)
|
||||
:style {:display "inline-block"
|
||||
:margin-right "2px"}}
|
||||
key-text])]))
|
||||
|
||||
(rum/defc root
|
||||
"Main shortcut component with automatic style detection.
|
||||
|
||||
Props:
|
||||
- :style - :combo, :separate, :compact, or :auto (default: :auto)
|
||||
- :interactive? - if true, keys are focusable (default: false)
|
||||
- :aria-label - accessibility label for container
|
||||
- :aria-hidden? - if true, hides from screen readers (default: false for decorative hints)
|
||||
- :animate-on-press? - if true, enables press animation (default: true)
|
||||
- :glow? - if true, adds inner glow effect to combo/separate keys (default: true)"
|
||||
[shortcut & {:keys [style size theme interactive? aria-label aria-hidden? animate-on-press? glow?]
|
||||
:or {style :auto
|
||||
size :xs
|
||||
interactive? false
|
||||
aria-hidden? false
|
||||
animate-on-press? true
|
||||
glow? true}}]
|
||||
(when (and shortcut (seq shortcut))
|
||||
(let [shortcuts (if (coll? shortcut)
|
||||
(if (every? string? shortcut)
|
||||
[shortcut] ; single shortcut as vector
|
||||
(if (string? (first shortcut))
|
||||
[shortcut] ; single shortcut string
|
||||
shortcut)) ; multiple shortcuts
|
||||
(parse-shortcuts shortcut))
|
||||
opts {:interactive? interactive?
|
||||
:aria-label aria-label
|
||||
:aria-hidden? aria-hidden?
|
||||
:glow? glow?}]
|
||||
(for [[index binding] (map-indexed vector shortcuts)]
|
||||
(let [detected-style (if (= style :auto)
|
||||
(detect-style binding)
|
||||
style)
|
||||
keys (cond
|
||||
(string? binding)
|
||||
(if (string/includes? binding "+")
|
||||
(string/split binding #"\+") ; combo: "cmd+k" -> ["cmd" "k"]
|
||||
(string/split binding #" ")) ; separate: "cmd k" -> ["cmd" "k"]
|
||||
|
||||
(and (coll? binding) (coll? (first binding)))
|
||||
(first binding) ; combo: nested collection like [["shift" "cmd"]]
|
||||
|
||||
(coll? binding)
|
||||
(let [flattened (mapcat #(if (coll? %) % [%]) binding)]
|
||||
(if (every? string? flattened)
|
||||
flattened ; separate: flat collection like ["cmd" "k"] or ["⇧" "g"]
|
||||
(map str flattened))) ; convert any non-strings to strings
|
||||
|
||||
:else
|
||||
[(str binding)])
|
||||
render-fn (case detected-style
|
||||
:combo combo-keys
|
||||
:separate separate-keys
|
||||
:compact compact-keys
|
||||
separate-keys)] ; fallback
|
||||
[:span
|
||||
{:key (str "shortcut-" index)
|
||||
:style {:display "inline-flex"
|
||||
:align-items "center"
|
||||
:min-height "20px"
|
||||
:white-space "nowrap"}}
|
||||
(when (< 0 index)
|
||||
[:span.text-gray-11.text-sm {:key (str "sep-" index)
|
||||
:style {:margin "0 4px"}} "|"])
|
||||
(render-fn keys binding opts)])))))
|
||||
|
||||
4
deps/shui/src/logseq/shui/ui.cljs
vendored
4
deps/shui/src/logseq/shui/ui.cljs
vendored
@@ -7,6 +7,7 @@
|
||||
[logseq.shui.select.core :as select-core]
|
||||
[logseq.shui.select.multi :as select-multi]
|
||||
[logseq.shui.shortcut.v1 :as shui.shortcut.v1]
|
||||
[logseq.shui.shortcut.v2 :as shui.shortcut.v2]
|
||||
[logseq.shui.table.core :as table-core]
|
||||
[logseq.shui.toaster.core :as toaster-core]
|
||||
[logseq.shui.util :as util]))
|
||||
@@ -20,7 +21,8 @@
|
||||
(def link base-core/link)
|
||||
(def trigger-as base-core/trigger-as)
|
||||
(def trigger-child-wrap base-core/trigger-child-wrap)
|
||||
(def ^:todo shortcut shui.shortcut.v1/root)
|
||||
(def ^:todo shortcut shui.shortcut.v2/root)
|
||||
(def shortcut-press! shui.shortcut.v2/shortcut-press!)
|
||||
(def ^:export tabler-icon icon-v2/root)
|
||||
|
||||
(def alert (util/lsui-wrap "Alert"))
|
||||
|
||||
@@ -267,11 +267,148 @@ div[data-radix-popper-content-wrapper] {
|
||||
}
|
||||
}
|
||||
|
||||
.ui__button-shortcut-key {
|
||||
@apply text-xs font-normal h-5 w-5 flex items-center justify-center rounded bg-gray-06-alpha;
|
||||
/* Deprecated: .ui__button-shortcut-key - replaced by shui-shortcut-key */
|
||||
|
||||
&:first-of-type {
|
||||
@apply ml-2;
|
||||
/* Unified Keyboard Shortcut Component Styles */
|
||||
|
||||
/* Combo Keys - simultaneous key combinations with separator */
|
||||
.shui-shortcut-combo {
|
||||
@apply flex items-start relative rounded;
|
||||
background-color: rgba(223, 239, 254, 0.14);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Glow effect for combo and separate keys */
|
||||
/* Combo keys: glow on container (wraps all keys together) */
|
||||
.shui-shortcut-combo.shui-shortcut-glow {
|
||||
box-shadow: rgba(255, 255, 255, 0.15) 0px 1px 0px 0px inset, rgba(0, 0, 0, 0.15) 0px -1px 0px 0px inset;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Separate keys: glow on individual keys (not container) */
|
||||
.shui-shortcut-separate.shui-shortcut-glow kbd.shui-shortcut-key {
|
||||
box-shadow: rgba(255, 255, 255, 0.15) 0px 1px 0px 0px inset, rgba(0, 0, 0, 0.15) 0px -1px 0px 0px inset;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.shui-shortcut-combo kbd.shui-shortcut-key {
|
||||
@apply flex flex-col items-center justify-center px-1 py-0.5 relative shrink-0;
|
||||
min-width: fit-content;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.shui-shortcut-separator {
|
||||
background-color: rgba(224, 243, 255, 0.18);
|
||||
align-self: stretch;
|
||||
flex-shrink: 0;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
/* Separate Keys - sequential key presses with 4px gap */
|
||||
.shui-shortcut-separate {
|
||||
@apply flex items-start relative;
|
||||
gap: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.shui-shortcut-separate kbd.shui-shortcut-key {
|
||||
@apply flex flex-col items-center justify-center px-1 py-0.5 relative rounded shrink-0;
|
||||
background-color: rgba(223, 239, 254, 0.14);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
/* Compact Keys - minimal text-only style */
|
||||
.shui-shortcut-compact {
|
||||
@apply flex items-start relative;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: normal;
|
||||
line-height: 16px;
|
||||
font-style: normal;
|
||||
color: #ecedee;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
letter-spacing: -0.5px;
|
||||
white-space: nowrap;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
/* Individual key styling with inner glow */
|
||||
kbd.shui-shortcut-key,
|
||||
.shui-shortcut-key {
|
||||
@apply text-xs font-normal h-5 flex items-center justify-center;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #ecedee;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
letter-spacing: -0.5px;
|
||||
padding: 2px 4px;
|
||||
line-height: 16px;
|
||||
min-width: fit-content;
|
||||
transition: transform 140ms ease-out, box-shadow 140ms ease-out;
|
||||
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Keys in separate containers get their own styling */
|
||||
.shui-shortcut-separate kbd.shui-shortcut-key {
|
||||
@apply rounded;
|
||||
background-color: rgba(223, 239, 254, 0.14);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Key press animation */
|
||||
kbd.shui-shortcut-key-pressed,
|
||||
.shui-shortcut-key-pressed {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
/* Key press animation with glow - preserve glow effect */
|
||||
/* Combo keys: animate the container */
|
||||
.shui-shortcut-combo.shui-shortcut-glow.shui-shortcut-key-pressed {
|
||||
box-shadow: rgba(255, 255, 255, 0.15) 0px 2px 0px 0px inset, rgba(0, 0, 0, 0.15) 0px 0px 0px 0px inset, 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Separate keys: animate individual keys */
|
||||
.shui-shortcut-separate.shui-shortcut-glow kbd.shui-shortcut-key-pressed {
|
||||
box-shadow: rgba(255, 255, 255, 0.15) 0px 2px 0px 0px inset, rgba(0, 0, 0, 0.15) 0px 0px 0px 0px inset, 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Key press animation without glow */
|
||||
.shui-shortcut-combo:not(.shui-shortcut-glow) kbd.shui-shortcut-key-pressed,
|
||||
.shui-shortcut-separate:not(.shui-shortcut-glow) kbd.shui-shortcut-key-pressed {
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Row highlight animation */
|
||||
.shui-shortcut-row--pressed {
|
||||
background-color: rgba(223, 239, 254, 0.1);
|
||||
transition: background-color 160ms ease-out;
|
||||
}
|
||||
|
||||
/* Ensure consistent height for shortcut containers */
|
||||
.shui-shortcut-row {
|
||||
min-height: 20px;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
/* Respect reduced motion preference */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
kbd.shui-shortcut-key,
|
||||
.shui-shortcut-key,
|
||||
.shui-shortcut-row--pressed {
|
||||
transition: none;
|
||||
transform: none;
|
||||
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.shui-shortcut-row--pressed {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -669,10 +669,10 @@
|
||||
(if (= show :more)
|
||||
[:div.flex.flex-row.gap-1.items-center
|
||||
"Show less"
|
||||
(shui/shortcut "mod up" nil)]
|
||||
(shui/shortcut "mod up" {:style :compact})]
|
||||
[:div.flex.flex-row.gap-1.items-center
|
||||
"Show more"
|
||||
(shui/shortcut "mod down" nil)])])])
|
||||
(shui/shortcut "mod down" {:style :compact})])])])
|
||||
|
||||
[:div.search-results
|
||||
(for [item visible-items
|
||||
@@ -805,6 +805,10 @@
|
||||
(show-less)
|
||||
(move-highlight state -1))
|
||||
(and enter? (not composing?)) (do
|
||||
(when shift?
|
||||
(shui/shortcut-press! "shift+return" true))
|
||||
(when-not shift?
|
||||
(shui/shortcut-press! "return" true))
|
||||
(handle-action :default state e)
|
||||
(util/stop-propagation e))
|
||||
esc? (let [filter' @(::filter state)]
|
||||
@@ -817,6 +821,7 @@
|
||||
(util/stop e)
|
||||
(handle-input-change state nil ""))))
|
||||
(and meta? (= keyname "c")) (do
|
||||
(shui/shortcut-press! (if goog.userAgent/MAC "cmd+c" "ctrl+c") true)
|
||||
(copy-block-ref state)
|
||||
(util/stop-propagation e))
|
||||
(and meta? (= keyname "o"))
|
||||
@@ -923,16 +928,9 @@
|
||||
[[:span.opacity-60 text]
|
||||
;; shortcut
|
||||
(when (not-empty shortcut)
|
||||
(for [key shortcut]
|
||||
[:div.ui__button-shortcut-key
|
||||
(case key
|
||||
"cmd" [:div (if goog.userAgent/MAC "⌘" "Ctrl")]
|
||||
"shift" [:div "⇧"]
|
||||
"return" [:div "⏎"]
|
||||
"esc" [:div.tracking-tightest {:style {:transform "scaleX(0.8) scaleY(1.2) "
|
||||
:font-size "0.5rem"
|
||||
:font-weight "500"}} "ESC"]
|
||||
(cond-> key (string? key) .toUpperCase))]))]))
|
||||
(shui/shortcut shortcut {:style :separate
|
||||
:interactive? false
|
||||
:aria-hidden? true}))]))
|
||||
|
||||
(rum/defc hints
|
||||
[state]
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
(when value
|
||||
[:span.text-gray-11 (to-string value)])])
|
||||
(when shortcut
|
||||
[:div {:class "flex gap-1"
|
||||
:style {:opacity (if (or highlighted hover?) 1 0.9)}}
|
||||
(shui/shortcut shortcut)])]]))
|
||||
[:div {:class "flex gap-1 shui-shortcut-row items-center"
|
||||
:style {:opacity (if (or highlighted hover?) 1 0.9)
|
||||
:min-height "20px"
|
||||
:flex-wrap "nowrap"}}
|
||||
(shui/shortcut shortcut {:interactive? false
|
||||
:aria-hidden? true})])]]))
|
||||
|
||||
@@ -477,6 +477,9 @@
|
||||
|
||||
(not unset?)
|
||||
[:code.flex.items-center.bg-transparent
|
||||
{:style {:min-height "20px"
|
||||
:flex-wrap "nowrap"
|
||||
:white-space "nowrap"}}
|
||||
(shui/shortcut
|
||||
(string/join " | " (map #(dh/binding-for-display id %) binding))
|
||||
{:size :md :interactive? true})])]]))))])])]]))
|
||||
|
||||
@@ -207,7 +207,9 @@
|
||||
(string/trim)
|
||||
(string/lower-case)
|
||||
(string/split #" "))
|
||||
sequence)]
|
||||
sequence)
|
||||
opts (merge {:interactive? false
|
||||
:aria-hidden? true} opts)]
|
||||
[:span.keyboard-shortcut
|
||||
(shui/shortcut sequence opts)]))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user