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

Code before:
                  :on-key-down handle-key-down-cancel}
      (tr "labels.cancel")]
     [:> button* {:variant "primary"
                  :type "submit"
                  :on-click on-save-form
                  :on-key-down handle-key-down-save
                  :disabled disabled?}
      (tr "workspace.token.save-theme")]]))

(defn- make-lib-with-theme
  [theme sets]
  (let [tlib (-> (ctob/make-tokens-lib)
                 (ctob/add-theme theme))
        tlib (reduce ctob/add-set tlib sets)]
    (ctob/activate-theme tlib (:group theme) (:name theme))))

(mf/defc edit-create-theme*
  [{:keys [state change-view theme on-save is-editing]}]
  (let [ordered-token-sets (mf/deref refs/workspace-ordered-token-sets)
        token-sets (mf/deref refs/workspace-token-sets-tree)

        current-theme* (mf/use-state theme)
        current-theme (deref current-theme*)
        lib (make-lib-with-theme current-theme ordered-token-sets)

        has-back-button? (contains? #{:empty-themes :themes-overview} (:prev-type state))

        ;; Form / Modal handlers
        on-back (mf/use-fn
                 (mf/deps change-view)
                 #(change-view :themes-overview))
        disabled? (-> (:name current-theme)
                      (str/trim)
                      (str/empty?))

        on-change-field
        (mf/use-fn
         (fn [field value]
           (swap! current-theme* #(assoc % field value))))

        on-save-form
        (mf/use-fn
         (mf/deps current-theme on-save on-back)
         (fn [e]
           (dom/prevent-default e)
           (let [theme' (-> current-theme
                            (update :name str/trim)
                            (update :group str/trim)
                            (update :description str/trim))]
             (when-not (str/empty? (:name theme'))
               (on-save theme'))

Review comment (suggestion):
I'd prefer not leaking state here. My proposal is to add a component parameter like `is-first-view` that is calculated by the caller, looking if `:prev-type` is empty. And here, show the back button only if it's not the first view.

Code after:
                  :on-key-down handle-key-down-cancel}
      (tr "labels.cancel")]
     [:> button* {:variant "primary"
                  :type "submit"
                  :on-click on-save-form
                  :on-key-down handle-key-down-save
                  :disabled disabled?}
      (tr "workspace.token.save-theme")]]))

(defn- make-lib-with-theme
  [theme sets]
  (let [tlib (-> (ctob/make-tokens-lib)
                 (ctob/add-theme theme))
        tlib (reduce ctob/add-set tlib sets)]
    (ctob/activate-theme tlib (:group theme) (:name theme))))

(mf/defc edit-create-theme*
  [{:keys [change-view theme on-save is-editing has-prev-view]}]
  (let [ordered-token-sets (mf/deref refs/workspace-ordered-token-sets)
        token-sets (mf/deref refs/workspace-token-sets-tree)

        current-theme* (mf/use-state theme)
        current-theme (deref current-theme*)
        lib (make-lib-with-theme current-theme ordered-token-sets)

        ;; Form / Modal handlers
        on-back (mf/use-fn
                 (mf/deps change-view)
                 #(change-view :themes-overview))
        disabled? (-> (:name current-theme)
                      (str/trim)
                      (str/empty?))

        on-change-field
        (mf/use-fn
         (fn [field value]
           (swap! current-theme* #(assoc % field value))))

        on-save-form
        (mf/use-fn
         (mf/deps current-theme on-save on-back)
         (fn [e]
           (dom/prevent-default e)
           (let [theme' (-> current-theme
                            (update :name str/trim)
                            (update :group str/trim)
                            (update :description str/trim))]
             (when-not (str/empty? (:name theme'))
               (on-save theme'))
             (on-back))))