mirror of
https://github.com/penpot/penpot.git
synced 2025-02-24 07:46:13 -05:00
⚡ Improve efficiency of grouping and sorting token types
This commit is contained in:
parent
e4bf2bd9ad
commit
831b0baddd
3 changed files with 59 additions and 38 deletions
|
@ -35,6 +35,7 @@
|
||||||
[app.main.ui.workspace.tokens.token :as wtt]
|
[app.main.ui.workspace.tokens.token :as wtt]
|
||||||
[app.main.ui.workspace.tokens.token-pill :refer [token-pill*]]
|
[app.main.ui.workspace.tokens.token-pill :refer [token-pill*]]
|
||||||
[app.main.ui.workspace.tokens.token-types :as wtty]
|
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||||
|
[app.util.array :as array]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[app.util.webapi :as wapi]
|
[app.util.webapi :as wapi]
|
||||||
|
@ -74,10 +75,12 @@
|
||||||
|
|
||||||
(mf/defc token-group*
|
(mf/defc token-group*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [type tokens selected-shapes token-type-props active-theme-tokens]}]
|
[{:keys [type tokens selected-shapes active-theme-tokens]}]
|
||||||
(let [open? (mf/deref (-> (l/key type)
|
(let [open? (mf/deref (-> (l/key type)
|
||||||
(l/derived lens:token-type-open-status)))
|
(l/derived lens:token-type-open-status)))
|
||||||
{:keys [modal attributes all-attributes title]} token-type-props
|
|
||||||
|
{:keys [modal attributes all-attributes title] :as token-type-props}
|
||||||
|
(get wtty/token-types type)
|
||||||
|
|
||||||
tokens
|
tokens
|
||||||
(mf/with-memo [tokens]
|
(mf/with-memo [tokens]
|
||||||
|
@ -150,7 +153,6 @@
|
||||||
|
|
||||||
[:> token-pill*
|
[:> token-pill*
|
||||||
{:key (:name token)
|
{:key (:name token)
|
||||||
:token-type-props token-type-props
|
|
||||||
:token (d/nilv theme-token token)
|
:token (d/nilv theme-token token)
|
||||||
:selected-shapes selected-shapes
|
:selected-shapes selected-shapes
|
||||||
:active-theme-tokens active-theme-tokens
|
:active-theme-tokens active-theme-tokens
|
||||||
|
@ -163,19 +165,23 @@
|
||||||
:on-context-menu on-context-menu}]))]])]]))
|
:on-context-menu on-context-menu}]))]])]]))
|
||||||
|
|
||||||
(defn- get-sorted-token-groups
|
(defn- get-sorted-token-groups
|
||||||
"Separate token-types into groups of `:empty` or `:filled` depending if tokens exist for that type.
|
"Separate token-types into groups of `empty` or `filled` depending if
|
||||||
Sort each group alphabetically (by their `:token-key`)."
|
tokens exist for that type. Sort each group alphabetically (by
|
||||||
[tokens]
|
their type)."
|
||||||
(let [tokens-by-type (ctob/group-by-type tokens)
|
[tokens-by-type]
|
||||||
{:keys [empty filled]} (->> wtty/token-types
|
(loop [empty #js []
|
||||||
(map (fn [[token-key token-type-props]]
|
filled #js []
|
||||||
{:token-key token-key
|
types (-> wtty/token-types keys seq)]
|
||||||
:token-type-props token-type-props
|
(if-let [type (first types)]
|
||||||
:tokens (get tokens-by-type token-key [])}))
|
(if (not-empty (get tokens-by-type type))
|
||||||
(group-by (fn [{:keys [tokens]}]
|
(recur empty
|
||||||
(if (empty? tokens) :empty :filled))))]
|
(array/conj! filled type)
|
||||||
{:empty (sort-by :token-key empty)
|
(rest types))
|
||||||
:filled (sort-by :token-key filled)}))
|
(recur (array/conj! empty type)
|
||||||
|
filled
|
||||||
|
(rest types)))
|
||||||
|
[(seq (array/sort! empty))
|
||||||
|
(seq (array/sort! filled))])))
|
||||||
|
|
||||||
(mf/defc themes-header
|
(mf/defc themes-header
|
||||||
[_props]
|
[_props]
|
||||||
|
@ -283,31 +289,39 @@
|
||||||
selected-token-set-name
|
selected-token-set-name
|
||||||
(mf/deref refs/workspace-selected-token-set-name)
|
(mf/deref refs/workspace-selected-token-set-name)
|
||||||
|
|
||||||
token-groups
|
tokens-by-type
|
||||||
(mf/with-memo [tokens selected-token-set-tokens]
|
(mf/with-memo [tokens selected-token-set-tokens]
|
||||||
(-> (select-keys tokens (keys selected-token-set-tokens))
|
(let [tokens (reduce-kv (fn [tokens k _]
|
||||||
(get-sorted-token-groups)))]
|
(if (contains? selected-token-set-tokens k)
|
||||||
|
tokens
|
||||||
|
(dissoc tokens k)))
|
||||||
|
tokens
|
||||||
|
tokens)]
|
||||||
|
(ctob/group-by-type tokens)))
|
||||||
|
|
||||||
|
[empty-group filled-group]
|
||||||
|
(mf/with-memo [tokens-by-type]
|
||||||
|
(get-sorted-token-groups tokens-by-type))]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
[:& token-context-menu]
|
[:& token-context-menu]
|
||||||
[:& title-bar {:all-clickable true
|
[:& title-bar {:all-clickable true
|
||||||
:title (tr "workspace.token.tokens-section-title" selected-token-set-name)}]
|
:title (tr "workspace.token.tokens-section-title" selected-token-set-name)}]
|
||||||
|
|
||||||
(for [{:keys [token-key token-type-props tokens]} (:filled token-groups)]
|
(for [type filled-group]
|
||||||
[:> token-group* {:key token-key
|
(let [tokens (get tokens-by-type type)]
|
||||||
:type token-key
|
[:> token-group* {:key (name type)
|
||||||
|
:type type
|
||||||
:selected-shapes selected-shapes
|
:selected-shapes selected-shapes
|
||||||
:active-theme-tokens active-theme-tokens
|
:active-theme-tokens active-theme-tokens
|
||||||
:tokens tokens
|
:tokens tokens}]))
|
||||||
:token-type-props token-type-props}])
|
|
||||||
|
|
||||||
(for [{:keys [token-key token-type-props tokens]} (:empty token-groups)]
|
(for [type empty-group]
|
||||||
[:> token-group* {:key token-key
|
[:> token-group* {:key (name type)
|
||||||
:type token-key
|
:type type
|
||||||
:selected-shapes selected-shapes
|
:selected-shapes selected-shapes
|
||||||
:active-theme-tokens active-theme-tokens
|
:active-theme-tokens active-theme-tokens
|
||||||
:tokens tokens
|
:tokens []}])]))
|
||||||
:token-type-props token-type-props}])]))
|
|
||||||
|
|
||||||
(mf/defc import-export-button
|
(mf/defc import-export-button
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
||||||
[app.main.ui.workspace.tokens.token :as wtt]
|
[app.main.ui.workspace.tokens.token :as wtt]
|
||||||
|
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
|
@ -95,9 +96,9 @@
|
||||||
|
|
||||||
(defn- generate-tooltip
|
(defn- generate-tooltip
|
||||||
"Generates a tooltip for a given token"
|
"Generates a tooltip for a given token"
|
||||||
[is-viewer shape token-type-props token half-applied no-valid-value ref-not-in-active-set]
|
[is-viewer shape token half-applied no-valid-value ref-not-in-active-set]
|
||||||
(let [{:keys [name value resolved-value type]} token
|
(let [{:keys [name value resolved-value type]} token
|
||||||
{:keys [title]} token-type-props
|
{:keys [title] :as token-type-props} (get wtty/token-types (:type token))
|
||||||
applied-tokens (:applied-tokens shape)
|
applied-tokens (:applied-tokens shape)
|
||||||
app-token-vals (set (vals applied-tokens))
|
app-token-vals (set (vals applied-tokens))
|
||||||
app-token-keys (keys applied-tokens)
|
app-token-keys (keys applied-tokens)
|
||||||
|
@ -142,7 +143,7 @@
|
||||||
(contains? active-tokens match)))
|
(contains? active-tokens match)))
|
||||||
|
|
||||||
(mf/defc token-pill*
|
(mf/defc token-pill*
|
||||||
[{:keys [on-click token full-applied on-context-menu half-applied selected-shapes token-type-props active-theme-tokens]}]
|
[{:keys [on-click token full-applied on-context-menu half-applied selected-shapes active-theme-tokens]}]
|
||||||
(let [{:keys [name value errors]} token
|
(let [{:keys [name value errors]} token
|
||||||
|
|
||||||
is-reference? (wtt/is-reference? token)
|
is-reference? (wtt/is-reference? token)
|
||||||
|
@ -203,8 +204,7 @@
|
||||||
(mf/deps selected-shapes is-viewer)
|
(mf/deps selected-shapes is-viewer)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [node (dom/get-current-target event)
|
(let [node (dom/get-current-target event)
|
||||||
title (generate-tooltip is-viewer (first selected-shapes)
|
title (generate-tooltip is-viewer (first selected-shapes) token
|
||||||
token-type-props token
|
|
||||||
half-applied no-valid-value ref-not-in-active-set)]
|
half-applied no-valid-value ref-not-in-active-set)]
|
||||||
(dom/set-attribute! node "title" title))))]
|
(dom/set-attribute! node "title" title))))]
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
|
|
||||||
(ns app.util.array
|
(ns app.util.array
|
||||||
"A collection of helpers for work with javascript arrays."
|
"A collection of helpers for work with javascript arrays."
|
||||||
(:refer-clojure :exclude [conj! conj filter map reduce find])
|
(:refer-clojure :exclude [conj! conj filter map reduce find sort])
|
||||||
(:require
|
(:require
|
||||||
[cljs.core :as c]))
|
[cljs.core :as c]
|
||||||
|
[goog.array :as garray]))
|
||||||
|
|
||||||
(defn conj
|
(defn conj
|
||||||
"A conj like function for js arrays."
|
"A conj like function for js arrays."
|
||||||
|
@ -67,3 +68,9 @@
|
||||||
(defn find
|
(defn find
|
||||||
[f v]
|
[f v]
|
||||||
(.find ^js/Array v f))
|
(.find ^js/Array v f))
|
||||||
|
|
||||||
|
(defn sort!
|
||||||
|
[a]
|
||||||
|
(garray/sort a compare)
|
||||||
|
a)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue