diff --git a/frontend/src/app/main/ui/workspace/tokens/changes.cljs b/frontend/src/app/main/ui/workspace/tokens/changes.cljs index cab2069fe..28474304e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/changes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/changes.cljs @@ -38,7 +38,7 @@ Optionally remove attributes from `attributes-to-remove`, this is useful for applying a single attribute from an attributes set while removing other applied tokens from this set." - [{:keys [attributes attributes-to-remove token shape-ids on-update-shape] :as _props}] + [{:keys [attributes attributes-to-remove token shape-ids on-update-shape]}] (ptk/reify ::apply-token ptk/WatchEvent (watch [_ state _] diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 2f7c594bc..21f987f0e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -285,7 +285,7 @@ [:> theme-sets-list* props]]]])) (mf/defc tokens-tab* - [] + [{:keys [tokens-lib]}] (let [objects (mf/deref refs/workspace-page-objects) selected (mf/deref refs/selected-shapes) open-status (mf/deref ref:token-type-open-status) @@ -295,16 +295,36 @@ (into [] (keep (d/getf objects)) selected)) active-theme-tokens - (sd/use-active-theme-tokens) + (mf/with-memo [tokens-lib] + (if tokens-lib + (ctob/get-active-themes-set-tokens tokens-lib) + {})) + + ;; Resolve tokens as second step + active-theme-tokens + (sd/use-resolved-tokens* active-theme-tokens) + + ;; This only checks for the currently explicitly selected set + ;; name, it is ephimeral and can be nil + selected-token-set-name + (mf/deref refs/selected-token-set-name) + + ;; If we have not selected any set explicitly we just + ;; select the first one from the list of sets + selected-token-set-tokens + (if selected-token-set-name + (-> (ctob/get-set tokens-lib selected-token-set-name) + (get :tokens)) + (-> (ctob/get-sets tokens-lib) + (first) + (get :tokens))) tokens - (sd/use-resolved-workspace-tokens) + (mf/with-memo [active-theme-tokens selected-token-set-tokens] + (merge active-theme-tokens selected-token-set-tokens)) - selected-token-set-tokens - (mf/deref refs/workspace-selected-token-set-tokens) - - selected-token-set-name - (mf/deref refs/workspace-selected-token-set-name) + tokens + (sd/use-resolved-tokens* tokens) tokens-by-type (mf/with-memo [tokens selected-token-set-tokens] diff --git a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs index 28d72e34e..945ec37b8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs @@ -166,10 +166,10 @@ ([tokens-tree get-token] (resolve-tokens-tree+ tokens-tree get-token (StyleDictionary. default-config))) ([tokens-tree get-token style-dictionary] - (-> style-dictionary - (add-tokens tokens-tree) - (build-dictionary) - (p/then #(process-sd-tokens % get-token))))) + (let [sdict (-> style-dictionary + (add-tokens tokens-tree) + (build-dictionary))] + (p/fmap #(process-sd-tokens % get-token) sdict)))) (defn sd-token-name [^js sd-token] (.. sd-token -original -name)) @@ -177,8 +177,10 @@ (defn sd-token-uuid [^js sd-token] (uuid (.-uuid (.-id ^js sd-token)))) -(defn resolve-tokens+ [tokens] - (resolve-tokens-tree+ (ctob/tokens-tree tokens) #(get tokens (sd-token-name %)))) +(defn resolve-tokens+ + [tokens] + (let [tokens-tree (ctob/tokens-tree tokens)] + (resolve-tokens-tree+ tokens-tree #(get tokens (sd-token-name %))))) (defn resolve-tokens-interactive+ "Interactive check of resolving tokens. @@ -267,36 +269,45 @@ :or {cache-atom !tokens-cache} :as config}] (let [tokens-state (mf/use-state (get @cache-atom tokens))] - (mf/use-effect - (mf/deps tokens config) - (fn [] - (let [cached (get @cache-atom tokens)] - (cond - (nil? tokens) nil - ;; The tokens are already processing somewhere - (p/promise? cached) (-> cached - (p/then #(reset! tokens-state %)) - #_(p/catch js/console.error)) - ;; Get the cached entry - (some? cached) (reset! tokens-state cached) - ;; No cached entry, start processing - :else (let [promise+ (if interactive? - (resolve-tokens-interactive+ tokens) - (resolve-tokens+ tokens))] - (swap! cache-atom assoc tokens promise+) - (p/then promise+ (fn [resolved-tokens] - (swap! cache-atom assoc tokens resolved-tokens) - (reset! tokens-state resolved-tokens)))))))) + + ;; FIXME: this with effect with trigger all the time because + ;; `config` will be always a different instance + + (mf/with-effect [tokens config] + (let [cached (get @cache-atom tokens)] + (cond + (nil? tokens) nil + ;; The tokens are already processing somewhere + (p/promise? cached) (-> cached + (p/then #(reset! tokens-state %)) + #_(p/catch js/console.error)) + ;; Get the cached entry + (some? cached) (reset! tokens-state cached) + ;; No cached entry, start processing + :else (let [promise+ (if interactive? + (resolve-tokens-interactive+ tokens) + (resolve-tokens+ tokens))] + (swap! cache-atom assoc tokens promise+) + (p/then promise+ (fn [resolved-tokens] + (swap! cache-atom assoc tokens resolved-tokens) + (reset! tokens-state resolved-tokens))))))) @tokens-state)) -(defn use-resolved-workspace-tokens [] - (let [active-theme-tokens (mf/deref refs/workspace-active-theme-sets-tokens) - selected-token-set-tokens (mf/deref refs/workspace-selected-token-set-tokens) - prefer-selected-token-set-tokens (merge active-theme-tokens selected-token-set-tokens)] - (use-resolved-tokens prefer-selected-token-set-tokens))) +(defn use-resolved-tokens* + "This hook will return the unresolved tokens as state until they are + processed, then the state will be updated with the resolved tokens. -(defn use-active-theme-tokens - "A hook that returns active tokens for the current active theme" - [] - (-> (mf/deref refs/workspace-active-theme-sets-tokens) - (use-resolved-tokens {:cache-atom !theme-tokens-cache}))) + This is a cache-less, simplified version of use-resolved-tokens + hook." + [tokens & {:keys [interactive?]}] + (let [state* (mf/use-state tokens)] + (mf/with-effect [tokens interactive?] + (when (seq tokens) + (let [promise (if interactive? + (resolve-tokens-interactive+ tokens) + (resolve-tokens+ tokens))] + + (->> promise + (p/fmap (fn [resolved-tokens] + (reset! state* resolved-tokens))))))) + @state*))