Improve handling open-status and tokens selection

This commit is contained in:
Andrey Antukh 2025-02-05 11:46:07 +01:00
parent c91b7606a0
commit 81036b9330
3 changed files with 46 additions and 39 deletions

View file

@ -312,7 +312,7 @@
(ptk/reify ::set-token-type-section-open
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-tokens :open-status token-type] open?))))
(assoc-in state [:workspace-local :token-type-open-status token-type] open?))))
;; === Token Context Menu

View file

@ -8,6 +8,7 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.types.tokens-lib :as ctob]
[app.main.data.event :as ev]
[app.main.data.modal :as modal]
@ -44,8 +45,8 @@
[rumext.v2 :as mf]
[shadow.resource]))
(def lens:token-type-open-status
(l/derived (l/in [:workspace-tokens :open-status]) st/state))
(def ref:token-type-open-status
(l/derived #(dm/get-in % [:workspace-local :token-type-open-status]) st/state))
;; Components ------------------------------------------------------------------
@ -65,20 +66,19 @@
:sizing "expand"
"add"))
(defn attribute-actions [token selected-shapes attributes]
(def ^:private
xf:map-id
(map :id))
(defn- all-selected? [token selected-shapes attributes]
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
shape-ids (into #{} (map :id selected-shapes))]
{:all-selected? (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)
:shape-ids shape-ids
:selected-pred #(seq (% ids-by-attributes))}))
shape-ids (into #{} xf:map-id selected-shapes)]
(wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)))
(mf/defc token-group*
{::mf/private true}
[{:keys [type tokens selected-shapes active-theme-tokens]}]
(let [open? (mf/deref (-> (l/key type)
(l/derived lens:token-type-open-status)))
{:keys [modal attributes all-attributes title] :as token-type-props}
[{:keys [type tokens selected-shapes active-theme-tokens is-open]}]
(let [{:keys [modal attributes all-attributes title] :as token-type-props}
(get wtch/token-properties type)
tokens
@ -98,23 +98,24 @@
on-toggle-open-click
(mf/use-fn
(mf/deps open? tokens)
#(st/emit! (dt/set-token-type-section-open type (not open?))))
(mf/deps is-open type)
#(st/emit! (dt/set-token-type-section-open type (not is-open))))
on-popover-open-click
(mf/use-fn
(mf/deps type title modal)
(fn [event]
(mf/deps type title)
(let [{:keys [key fields]} modal]
(dom/stop-propagation event)
(st/emit! (dt/set-token-type-section-open type true))
(modal/show! key {:x (.-clientX ^js event)
:y (.-clientY ^js event)
:position :right
:fields fields
:title title
:action "create"
:token-type type}))))
(dom/stop-propagation event)
(st/emit! (dt/set-token-type-section-open type true)
;; FIXME: use dom/get-client-position
(modal/show (:key modal)
{:x (.-clientX ^js event)
:y (.-clientY ^js event)
:position :right
:fields (:fields modal)
:title title
:action "create"
:token-type type}))))
on-token-pill-click
(mf/use-fn
@ -131,7 +132,7 @@
[:& cmm/asset-section {:icon (token-section-icon type)
:title title
:assets-count tokens-count
:open? open?}
:open? is-open}
[:& cmm/asset-section-block {:role :title-button}
(when can-edit?
[:> icon-button* {:on-click on-popover-open-click
@ -139,13 +140,13 @@
:icon "add"
;; TODO: This needs translation
:aria-label (str "Add token: " title)}])]
(when open?
(when is-open
[:& cmm/asset-section-block {:role :content}
[:div {:class (stl/css :token-pills-wrapper)}
(for [token tokens]
(let [theme-token (get active-theme-tokens (:name token))
multiple-selection (< 1 (count selected-shapes))
full-applied (:all-selected? (attribute-actions token selected-shapes (or all-attributes attributes)))
full-applied (all-selected? token selected-shapes (or all-attributes attributes))
applied (wtt/shapes-token-applied? token selected-shapes (or all-attributes attributes))]
[:> token-pill*
@ -270,6 +271,7 @@
[]
(let [objects (mf/deref refs/workspace-page-objects)
selected (mf/deref refs/selected-shapes)
open-status (mf/deref ref:token-type-open-status)
selected-shapes
(mf/with-memo [selected objects]
@ -309,6 +311,7 @@
(for [type filled-group]
(let [tokens (get tokens-by-type type)]
[:> token-group* {:key (name type)
:is-open (get open-status type false)
:type type
:selected-shapes selected-shapes
:active-theme-tokens active-theme-tokens

View file

@ -1,6 +1,7 @@
(ns app.main.ui.workspace.tokens.token
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
[clojure.set :as set]
[cuerdas.core :as str]))
@ -45,7 +46,7 @@
(defn token-attribute-applied?
"Test if `token` is applied to a `shape` on single `token-attribute`."
[token shape token-attribute]
(when-let [id (get-in shape [:applied-tokens token-attribute])]
(when-let [id (dm/get-in shape [:applied-tokens token-attribute])]
(= (token-identifier token) id)))
(defn token-applied?
@ -58,15 +59,18 @@
[token shapes token-attributes]
(some #(token-applied? token % token-attributes) shapes))
(defn shapes-ids-by-applied-attributes [token shapes token-attributes]
(reduce (fn [acc shape]
(let [applied-ids-by-attribute (->> (map #(when (token-attribute-applied? token shape %)
[% #{(:id shape)}])
token-attributes)
(filter some?)
(into {}))]
(merge-with into acc applied-ids-by-attribute)))
{} shapes))
(defn shapes-ids-by-applied-attributes
[token shapes token-attributes]
(let [conj* (fnil conj #{})]
(reduce (fn [result shape]
(let [shape-id (dm/get-prop shape :id)]
(->> token-attributes
(filter #(token-attribute-applied? token shape %))
(reduce (fn [result attr]
(update result attr conj* shape-id))
result))))
{}
shapes)))
(defn shapes-applied-all? [ids-by-attributes shape-ids attributes]
(every? #(set/superset? (get ids-by-attributes %) shape-ids) attributes))