mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
🐛 Fix font selector highlight inconsistency (#6990)
* 🐛 Fix font selector highlight inconsistency * ⚡ Add minor performance enhancements --------- Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
efaf6573bd
commit
708a40bff1
2 changed files with 48 additions and 53 deletions
|
@ -51,6 +51,7 @@
|
||||||
- Fix opacity on stroke gradients [Taiga #11646](https://tree.taiga.io/project/penpot/issue/11646)
|
- Fix opacity on stroke gradients [Taiga #11646](https://tree.taiga.io/project/penpot/issue/11646)
|
||||||
- Fix change from gradient to solid color [Taiga #11648](https://tree.taiga.io/project/penpot/issue/11648)
|
- Fix change from gradient to solid color [Taiga #11648](https://tree.taiga.io/project/penpot/issue/11648)
|
||||||
- Fix the context menu always closes after any action [Taiga #11624](https://tree.taiga.io/project/penpot/issue/11624)
|
- Fix the context menu always closes after any action [Taiga #11624](https://tree.taiga.io/project/penpot/issue/11624)
|
||||||
|
- Fix font selector highlight inconsistency when using keyboard navigation [Taiga #11668](https://tree.taiga.io/project/penpot/issue/11668)
|
||||||
|
|
||||||
## 2.8.1 (Unreleased)
|
## 2.8.1 (Unreleased)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
["react-virtualized" :as rvt]
|
["react-virtualized" :as rvt]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.exceptions :as ex]
|
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
[app.main.constants :refer [max-input-length]]
|
[app.main.constants :refer [max-input-length]]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
|
@ -41,25 +40,9 @@
|
||||||
""
|
""
|
||||||
(ust/format-precision value 2)))
|
(ust/format-precision value 2)))
|
||||||
|
|
||||||
(defn- get-next-font
|
|
||||||
[{:keys [id] :as current} fonts]
|
|
||||||
(if (seq fonts)
|
|
||||||
(let [index (d/index-of-pred fonts #(= (:id %) id))
|
|
||||||
index (or index -1)
|
|
||||||
next (ex/ignoring (nth fonts (inc index)))]
|
|
||||||
(or next (first fonts)))
|
|
||||||
current))
|
|
||||||
|
|
||||||
(defn- get-prev-font
|
|
||||||
[{:keys [id] :as current} fonts]
|
|
||||||
(if (seq fonts)
|
|
||||||
(let [index (d/index-of-pred fonts #(= (:id %) id))
|
|
||||||
next (ex/ignoring (nth fonts (dec index)))]
|
|
||||||
(or next (peek fonts)))
|
|
||||||
current))
|
|
||||||
|
|
||||||
(mf/defc font-item*
|
(mf/defc font-item*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]
|
||||||
|
::mf/private true}
|
||||||
[{:keys [font is-current on-click style]}]
|
[{:keys [font is-current on-click style]}]
|
||||||
(let [item-ref (mf/use-ref)
|
(let [item-ref (mf/use-ref)
|
||||||
on-click (mf/use-fn (mf/deps font) #(on-click font))]
|
on-click (mf/use-fn (mf/deps font) #(on-click font))]
|
||||||
|
@ -83,7 +66,7 @@
|
||||||
|
|
||||||
(declare row-renderer)
|
(declare row-renderer)
|
||||||
|
|
||||||
(defn filter-fonts
|
(defn- filter-fonts
|
||||||
[{:keys [term backends]} fonts]
|
[{:keys [term backends]} fonts]
|
||||||
(let [term (str/lower term)
|
(let [term (str/lower term)
|
||||||
xform (cond-> (map identity)
|
xform (cond-> (map identity)
|
||||||
|
@ -96,8 +79,7 @@
|
||||||
|
|
||||||
(mf/defc font-selector*
|
(mf/defc font-selector*
|
||||||
[{:keys [on-select on-close current-font show-recent full-size]}]
|
[{:keys [on-select on-close current-font show-recent full-size]}]
|
||||||
(let [selected (mf/use-state current-font)
|
(let [state* (mf/use-state
|
||||||
state* (mf/use-state
|
|
||||||
#(do {:term "" :backends #{}}))
|
#(do {:term "" :backends #{}}))
|
||||||
state (deref state*)
|
state (deref state*)
|
||||||
|
|
||||||
|
@ -112,23 +94,41 @@
|
||||||
recent-fonts (mf/with-memo [state recent-fonts]
|
recent-fonts (mf/with-memo [state recent-fonts]
|
||||||
(filter-fonts state recent-fonts))
|
(filter-fonts state recent-fonts))
|
||||||
|
|
||||||
full-size? (boolean (and full-size show-recent))
|
;; Combine recent fonts with filtered fonts, avoiding duplicates
|
||||||
|
combined-fonts
|
||||||
|
(mf/with-memo [recent-fonts fonts]
|
||||||
|
(let [recent-ids (into #{} d/xf:map-id recent-fonts)]
|
||||||
|
(into recent-fonts (remove #(contains? recent-ids (:id %))) fonts)))
|
||||||
|
|
||||||
|
;; Initialize selected with current font index
|
||||||
|
selected-index
|
||||||
|
(mf/use-state
|
||||||
|
(fn []
|
||||||
|
(or (some (fn [[idx font]]
|
||||||
|
(when (= (:id current-font) (:id font)) idx))
|
||||||
|
(map-indexed vector combined-fonts))
|
||||||
|
0)))
|
||||||
|
|
||||||
|
full-size?
|
||||||
|
(boolean (and full-size show-recent))
|
||||||
|
|
||||||
select-next
|
select-next
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps fonts)
|
(mf/deps combined-fonts)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(swap! selected get-next-font fonts)))
|
(let [next-idx (mod (inc @selected-index) (count combined-fonts))]
|
||||||
|
(reset! selected-index next-idx))))
|
||||||
|
|
||||||
select-prev
|
select-prev
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps fonts)
|
(mf/deps combined-fonts)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(swap! selected get-prev-font fonts)))
|
(let [prev-idx (mod (dec @selected-index) (count combined-fonts))]
|
||||||
|
(reset! selected-index prev-idx))))
|
||||||
|
|
||||||
on-select-and-close
|
on-select-and-close
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -139,35 +139,32 @@
|
||||||
|
|
||||||
on-key-down
|
on-key-down
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps fonts)
|
(mf/deps combined-fonts)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(cond
|
(cond
|
||||||
(kbd/up-arrow? event) (select-prev event)
|
(kbd/up-arrow? event) (select-prev event)
|
||||||
(kbd/down-arrow? event) (select-next event)
|
(kbd/down-arrow? event) (select-next event)
|
||||||
(kbd/esc? event) (on-close)
|
(kbd/esc? event) (on-close)
|
||||||
(kbd/enter? event) (do (on-select-and-close @selected))
|
(kbd/enter? event) (do
|
||||||
|
(let [selected-font (nth combined-fonts @selected-index)]
|
||||||
|
(on-select-and-close selected-font)))
|
||||||
:else (dom/focus! (mf/ref-val input)))))
|
:else (dom/focus! (mf/ref-val input)))))
|
||||||
|
|
||||||
on-filter-change
|
on-filter-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(swap! state* assoc :term event)))
|
(swap! state* assoc :term event)
|
||||||
|
;; Reset selection to first item when filter changes
|
||||||
on-select-and-close
|
(reset! selected-index 0)))]
|
||||||
(mf/use-fn
|
|
||||||
(mf/deps on-select on-close)
|
|
||||||
(fn [font]
|
|
||||||
(on-select font)
|
|
||||||
(on-close)))]
|
|
||||||
|
|
||||||
(mf/with-effect [fonts]
|
(mf/with-effect [fonts]
|
||||||
(let [key (events/listen js/document "keydown" on-key-down)]
|
(let [key (events/listen js/document "keydown" on-key-down)]
|
||||||
#(events/unlistenByKey key)))
|
#(events/unlistenByKey key)))
|
||||||
|
|
||||||
(mf/with-effect [@selected]
|
(mf/with-effect [@selected-index]
|
||||||
(when-let [inst (mf/ref-val flist)]
|
(when-let [inst (mf/ref-val flist)]
|
||||||
(when-let [index (:index @selected)]
|
(when (and (>= @selected-index 0) (< @selected-index (count combined-fonts)))
|
||||||
(.scrollToRow ^js inst index))))
|
(.scrollToRow ^js inst @selected-index))))
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(st/emit! (dsc/push-shortcuts :typography {}))
|
(st/emit! (dsc/push-shortcuts :typography {}))
|
||||||
|
@ -175,15 +172,12 @@
|
||||||
(st/emit! (dsc/pop-shortcuts :typography))))
|
(st/emit! (dsc/pop-shortcuts :typography))))
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(let [index (d/index-of-pred fonts #(= (:id %) (:id current-font)))
|
(let [index (d/index-of-pred combined-fonts #(= (:id %) (:id current-font)))
|
||||||
inst (mf/ref-val flist)]
|
inst (mf/ref-val flist)]
|
||||||
(tm/schedule
|
(when (and index (>= index 0))
|
||||||
#(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})]
|
(tm/schedule
|
||||||
(.scrollToPosition ^js inst offset)))))
|
#(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})]
|
||||||
|
(.scrollToPosition ^js inst offset))))))
|
||||||
(mf/with-effect [(:term state) fonts]
|
|
||||||
(when (and (seq fonts) (not= (:id @selected) (:id (first fonts))))
|
|
||||||
(reset! selected (first fonts))))
|
|
||||||
|
|
||||||
[:div {:class (stl/css :font-selector)}
|
[:div {:class (stl/css :font-selector)}
|
||||||
[:div {:class (stl/css-case :font-selector-dropdown true :font-selector-dropdown-full-size full-size?)}
|
[:div {:class (stl/css-case :font-selector-dropdown true :font-selector-dropdown-full-size full-size?)}
|
||||||
|
@ -200,7 +194,7 @@
|
||||||
:font font
|
:font font
|
||||||
:style {}
|
:style {}
|
||||||
:on-click on-select-and-close
|
:on-click on-select-and-close
|
||||||
:is-current (= (:id font) (:id @selected))}])])]
|
:is-current (= idx @selected-index)}])])]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :fonts-list true
|
[:div {:class (stl/css-case :fonts-list true
|
||||||
:fonts-list-full-size full-size?)}
|
:fonts-list-full-size full-size?)}
|
||||||
|
@ -208,17 +202,17 @@
|
||||||
(fn [props]
|
(fn [props]
|
||||||
(let [width (unchecked-get props "width")
|
(let [width (unchecked-get props "width")
|
||||||
height (unchecked-get props "height")
|
height (unchecked-get props "height")
|
||||||
render #(row-renderer fonts @selected on-select-and-close %)]
|
render #(row-renderer combined-fonts @selected-index on-select-and-close %)]
|
||||||
(mf/html
|
(mf/html
|
||||||
[:> rvt/List #js {:height height
|
[:> rvt/List #js {:height height
|
||||||
:ref flist
|
:ref flist
|
||||||
:width width
|
:width width
|
||||||
:rowCount (count fonts)
|
:rowCount (count combined-fonts)
|
||||||
:rowHeight 36
|
:rowHeight 36
|
||||||
:rowRenderer render}])))]]]]))
|
:rowRenderer render}])))]]]]))
|
||||||
|
|
||||||
(defn row-renderer
|
(defn row-renderer
|
||||||
[fonts selected on-select props]
|
[fonts selected-index on-select props]
|
||||||
(let [index (unchecked-get props "index")
|
(let [index (unchecked-get props "index")
|
||||||
key (unchecked-get props "key")
|
key (unchecked-get props "key")
|
||||||
style (unchecked-get props "style")
|
style (unchecked-get props "style")
|
||||||
|
@ -228,7 +222,7 @@
|
||||||
:font font
|
:font font
|
||||||
:style style
|
:style style
|
||||||
:on-click on-select
|
:on-click on-select
|
||||||
:is-current (= (:id font) (:id selected))}])))
|
:is-current (= index selected-index)}])))
|
||||||
|
|
||||||
(mf/defc font-options
|
(mf/defc font-options
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue