Repository: penpot/penpot
File: frontend/src/app/main/ui/workspace/tokens/changes.cljs (ClojureScript)

Code before:
  [{:keys [attributes attributes-to-remove token shape-ids on-update-shape]}]
  (ptk/reify ::apply-token
    ptk/WatchEvent
    (watch [_ state _]
      (when-let [tokens (some-> (dsh/lookup-file-data state)
                                (get :tokens-lib)
                                (ctob/get-active-themes-set-tokens))]
        (->> (rx/from (sd/resolve-tokens+ tokens))
             (rx/mapcat
              (fn [resolved-tokens]
                (let [undo-id (js/Symbol)
                      resolved-value (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value])
                      tokenized-attributes (wtt/attributes-map attributes token)]
                  (rx/of
                   (st/emit! (ptk/event ::ev/event {::ev/name "apply-tokens"}))
                   (dwu/start-undo-transaction undo-id)
                   (dwsh/update-shapes shape-ids (fn [shape]
                                                   (if (= :group (:type shape))
                                                     shape
                                                     (cond-> shape
                                                       attributes-to-remove
                                                       (update :applied-tokens #(apply (partial dissoc %) attributes-to-remove))
                                                       :always
                                                       (update :applied-tokens merge tokenized-attributes)))))
                   (when on-update-shape
                     (on-update-shape resolved-value shape-ids attributes))
                   (dwu/commit-undo-transaction undo-id))))))))))

(defn unapply-token
  "Removes `attributes` that match `token` for `shape-ids`.

  Doesn't update shape attributes."
  [{:keys [attributes token shape-ids] :as _props}]
  (ptk/reify ::unapply-token
    ptk/WatchEvent
    (watch [_ _ _]
      (rx/of
       (let [remove-token #(when % (wtt/remove-attributes-for-token attributes token %))]
         (dwsh/update-shapes
          shape-ids
          (fn [shape]
            (update shape :applied-tokens remove-token))))))))

(defn toggle-token
  [{:keys [token shapes]}]
  (ptk/reify ::on-toggle-token
    ptk/WatchEvent
    (watch [_ _ _]
      (let [{:keys [attributes all-attributes on-update-shape]}
            (get token-properties (:type token))


Review comment (suggestion):
I've seen that now when you double click the token pill with a group selected, the token is not applied but the attribute value is anyway changed. This is done by this function `on-update-shape`. You need to also add the check of group here.

Code after:
  [{:keys [attributes attributes-to-remove token shape-ids on-update-shape]}]
  (ptk/reify ::apply-token
    ptk/WatchEvent
    (watch [_ state _]
      (when-let [tokens (some-> (dsh/lookup-file-data state)
                                (get :tokens-lib)
                                (ctob/get-active-themes-set-tokens))]
        (->> (rx/from (sd/resolve-tokens+ tokens))
             (rx/mapcat
              (fn [resolved-tokens]
                (let [undo-id (js/Symbol)
                      objects (dsh/lookup-page-objects state)

                      shape-ids (or (->> (select-keys objects shape-ids)
                                         (filter (fn [[_ shape]] (not= (:type shape) :group)))
                                         (keys))
                                    [])

                      resolved-value (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value])
                      tokenized-attributes (wtt/attributes-map attributes token)]
                  (rx/of
                   (st/emit! (ptk/event ::ev/event {::ev/name "apply-tokens"}))
                   (dwu/start-undo-transaction undo-id)
                   (dwsh/update-shapes shape-ids (fn [shape]
                                                   (cond-> shape
                                                     attributes-to-remove
                                                     (update :applied-tokens #(apply (partial dissoc %) attributes-to-remove))
                                                     :always
                                                     (update :applied-tokens merge tokenized-attributes))))
                   (when on-update-shape
                     (on-update-shape resolved-value shape-ids attributes))
                   (dwu/commit-undo-transaction undo-id))))))))))

(defn unapply-token
  "Removes `attributes` that match `token` for `shape-ids`.

  Doesn't update shape attributes."
  [{:keys [attributes token shape-ids] :as _props}]
  (ptk/reify ::unapply-token
    ptk/WatchEvent
    (watch [_ _ _]
      (rx/of
       (let [remove-token #(when % (wtt/remove-attributes-for-token attributes token %))]
         (dwsh/update-shapes
          shape-ids
          (fn [shape]
            (update shape :applied-tokens remove-token))))))))

(defn toggle-token
  [{:keys [token shapes]}]
  (ptk/reify ::on-toggle-token