From b62722bdbb7527ee7fc78ffa84a0c066bb8a0911 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 14:11:13 +0200 Subject: [PATCH 01/48] Add themes modal dialog --- .../app/main/ui/workspace/tokens/modals.cljs | 35 +++++++++++-------- .../ui/workspace/tokens/modals/themes.cljs | 28 +++++++++++++++ .../ui/workspace/tokens/modals/themes.scss | 34 ++++++++++++++++++ .../app/main/ui/workspace/tokens/sidebar.cljs | 8 ++++- 4 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs create mode 100644 frontend/src/app/main/ui/workspace/tokens/modals/themes.scss diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.cljs b/frontend/src/app/main/ui/workspace/tokens/modals.cljs index 23edf75ed..30a45c49f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals.cljs @@ -8,6 +8,7 @@ (:require-macros [app.main.style :as stl]) (:require [app.main.data.modal :as modal] + [app.main.ui.workspace.tokens.modals.themes :as wtmt] [app.main.refs :as refs] [app.main.ui.workspace.tokens.form :refer [form]] [okulary.core :as l] @@ -37,7 +38,7 @@ (-> (calculate-position vport position x y) (clj->js)))) -(mf/defc modal +(mf/defc token-update-create-modal {::mf/wrap-props false} [{:keys [x y position token token-type] :as _args}] (let [wrapper-style (use-viewport-position-style x y position)] @@ -47,82 +48,88 @@ [:& form {:token token :token-type token-type}]])) +(mf/defc token-themes-modal + {::mf/register modal/components + ::mf/register-as :tokens/themes} + [args] + [:& wtmt/modal args]) + ;; Modals ---------------------------------------------------------------------- (mf/defc boolean-modal {::mf/register modal/components ::mf/register-as :tokens/boolean} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc border-radius-modal {::mf/register modal/components ::mf/register-as :tokens/border-radius} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc stroke-width-modal {::mf/register modal/components ::mf/register-as :tokens/stroke-width} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc box-shadow-modal {::mf/register modal/components ::mf/register-as :tokens/box-shadow} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc sizing-modal {::mf/register modal/components ::mf/register-as :tokens/sizing} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc dimensions-modal {::mf/register modal/components ::mf/register-as :tokens/dimensions} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc numeric-modal {::mf/register modal/components ::mf/register-as :tokens/numeric} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc opacity-modal {::mf/register modal/components ::mf/register-as :tokens/opacity} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc other-modal {::mf/register modal/components ::mf/register-as :tokens/other} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc rotation-modal {::mf/register modal/components ::mf/register-as :tokens/rotation} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc spacing-modal {::mf/register modal/components ::mf/register-as :tokens/spacing} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc string-modal {::mf/register modal/components ::mf/register-as :tokens/string} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) (mf/defc typography-modal {::mf/register modal/components ::mf/register-as :tokens/typography} [properties] - [:& modal properties]) + [:& token-update-create-modal properties]) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs new file mode 100644 index 000000000..8c146d370 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -0,0 +1,28 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.ui.workspace.tokens.modals.themes + (:require-macros [app.main.style :as stl]) + (:require + [rumext.v2 :as mf] + [app.main.data.modal :as modal] + [app.main.store :as st] + [app.main.ui.icons :as i])) + +(def ^:private close-icon + (i/icon-xref :close (stl/css :close-icon))) + +(mf/defc modal + {::mf/wrap-props false} + [{:keys [] :as _args}] + (let [handle-close-dialog (mf/use-callback #(st/emit! (modal/hide)))] + [:div {:class (stl/css :modal-overlay)} + [:div {:class (stl/css :modal-dialog)} + [:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon] + [:div {:class (stl/css :modal-title)} "Themes"] + + [:div {:class (stl/css :modal-content)} + "Themes"]]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss new file mode 100644 index 000000000..475e3997a --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -0,0 +1,34 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@import "refactor/common-refactor.scss"; + +.modal-overlay { + @extend .modal-overlay-base; +} + +.modal-dialog { + @extend .modal-container-base; + display: grid; + grid-template-rows: auto 1fr auto; + width: 100%; + max-width: $s-640; +} + +.modal-title { + @include headlineMediumTypography; + margin-block-end: $s-32; + color: var(--modal-title-foreground-color); +} + +.modal-content { + display: flex; + flex-direction: column; +} + +.close-btn { + @extend .modal-close-btn-base; +} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index b9e6c6a87..59019201a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -107,6 +107,7 @@ (let [{:keys [key fields]} modal] (dom/stop-propagation event) (st/emit! (dt/set-token-type-section-open type true)) + (js/console.log "key" key) (modal/show! key {:x (.-clientX ^js event) :y (.-clientY ^js event) :position :right @@ -190,7 +191,12 @@ :collapsed (not @open?) :all-clickable true :title "THEMES" - :on-collapsed #(swap! open? not)}]] + :on-collapsed #(swap! open? not)}] + [:button {:class (stl/css :add-set) + :on-click (fn [event] + (modal/show! :tokens/themes {:x (.-clientX ^js event) + :y (.-clientY ^js event)}))} + i/add]] (when @open? [:div [:style From d23c5cbbbe182b0decd7cf03e5881946fd759114 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 14:53:22 +0200 Subject: [PATCH 02/48] Move the temporary ui to modal --- .../ui/workspace/tokens/modals/themes.cljs | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 8c146d370..73046feda 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -7,14 +7,65 @@ (ns app.main.ui.workspace.tokens.modals.themes (:require-macros [app.main.style :as stl]) (:require - [rumext.v2 :as mf] [app.main.data.modal :as modal] + [app.main.data.tokens :as wdt] + [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.icons :as i])) + [app.main.ui.icons :as i] + [app.util.dom :as dom] + [rumext.v2 :as mf])) (def ^:private close-icon (i/icon-xref :close (stl/css :close-icon))) +(mf/defc empty-themes + [{:keys []}] + "Empty") + +(mf/defc themes-overview + [{:keys []}] + (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) + themes (mf/deref refs/workspace-ordered-token-themes)] + [:ul + (for [[group themes] themes] + [:li + {:key (str "token-theme-group" group)} + group + [:ul + (for [{:keys [id name] :as _theme} themes] + [:li {:key (str "tokene-theme-" id)} + [:div.spaced + name + [:div.spaced + [:button + {:on-click (fn [e] + (dom/prevent-default e) + (dom/stop-propagation e) + (st/emit! (wdt/toggle-token-theme id)))} + (if (get active-theme-ids id) "✅" "❎")] + [:button {:on-click (fn [e] + (dom/prevent-default e) + (dom/stop-propagation e) + (st/emit! (wdt/delete-token-theme id)))} + "🗑️"]]]])]])])) + +(mf/defc edit-theme + [{:keys []}] + "Edit Theme") + +(mf/defc themes + [{:keys [] :as _args}] + (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) + themes (mf/deref refs/workspace-ordered-token-themes) + _ (js/console.log "themes" themes) + state (mf/use-state (if (empty? themes) + :empty-themes + :themes-overview))] + (case @state + :empty-themes [:& empty-themes] + :themes-overview [:& themes-overview] + :edit-theme [:& edit-theme]))) + (mf/defc modal {::mf/wrap-props false} [{:keys [] :as _args}] @@ -23,6 +74,5 @@ [:div {:class (stl/css :modal-dialog)} [:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon] [:div {:class (stl/css :modal-title)} "Themes"] - [:div {:class (stl/css :modal-content)} - "Themes"]]])) + [:& themes]]]])) From cc7de14539455047a3308d9f79a56e279d9ea2fa Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 15:08:53 +0200 Subject: [PATCH 03/48] Add basic toggle switch --- .../ui/workspace/tokens/modals/themes.cljs | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 73046feda..8ca7e7423 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -8,6 +8,8 @@ (:require-macros [app.main.style :as stl]) (:require [app.main.data.modal :as modal] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] + [cuerdas.core :as str] [app.main.data.tokens :as wdt] [app.main.refs :as refs] [app.main.store :as st] @@ -15,6 +17,7 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) + (def ^:private close-icon (i/icon-xref :close (stl/css :close-icon))) @@ -22,6 +25,22 @@ [{:keys []}] "Empty") + +(mf/defc switch + [{:keys [selected? name on-change]}] + (let [selected (if selected? :on :off)] + [:& radio-buttons {:selected selected + :on-change on-change + :name name} + [:& radio-button {:id :on + :value :on + :icon i/tick + :label ""}] + [:& radio-button {:id :off + :value :off + :icon i/close + :label ""}]])) + (mf/defc themes-overview [{:keys []}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) @@ -37,12 +56,9 @@ [:div.spaced name [:div.spaced - [:button - {:on-click (fn [e] - (dom/prevent-default e) - (dom/stop-propagation e) - (st/emit! (wdt/toggle-token-theme id)))} - (if (get active-theme-ids id) "✅" "❎")] + [:& switch {:name (str "Theme" name) + :on-change #(st/emit! (wdt/toggle-token-theme id)) + :selected? (get active-theme-ids id)}] [:button {:on-click (fn [e] (dom/prevent-default e) (dom/stop-propagation e) From 7970440ffca53db6ccf0dc4d0006a7622cca9a1a Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 15:30:17 +0200 Subject: [PATCH 04/48] Toggle theme via ui --- .../ui/workspace/tokens/modals/themes.cljs | 35 ++++++----- .../ui/workspace/tokens/modals/themes.scss | 63 ++++++++++++++++++- 2 files changed, 79 insertions(+), 19 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 8ca7e7423..cc65f0c3a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -45,25 +45,28 @@ [{:keys []}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) themes (mf/deref refs/workspace-ordered-token-themes)] - [:ul + [:ul {:class (stl/css :theme-group-wrapper)} (for [[group themes] themes] - [:li - {:key (str "token-theme-group" group)} - group - [:ul + [:li {:key (str "token-theme-group" group)} + [:span {:class (stl/css :theme-group-label)} group] + [:ul {:class (stl/css :theme-group-rows-wrapper)} (for [{:keys [id name] :as _theme} themes] - [:li {:key (str "tokene-theme-" id)} - [:div.spaced - name - [:div.spaced + [:li {:key (str "token-theme-" id) + :class (stl/css :theme-row)} + [:div {:class (stl/css :theme-row-left)} + [:div {:on-click (fn [e] + (dom/stop-propagation e) + (st/emit! (wdt/toggle-token-theme id)))} [:& switch {:name (str "Theme" name) - :on-change #(st/emit! (wdt/toggle-token-theme id)) - :selected? (get active-theme-ids id)}] - [:button {:on-click (fn [e] - (dom/prevent-default e) - (dom/stop-propagation e) - (st/emit! (wdt/delete-token-theme id)))} - "🗑️"]]]])]])])) + :on-change (constantly nil) + :selected? (get active-theme-ids id)}]] + [:span {:class (stl/css :theme-row-label)} name]] + [:div {:class (stl/css :delete-theme-button)} + [:button {:on-click (fn [e] + (dom/prevent-default e) + (dom/stop-propagation e) + (st/emit! (wdt/delete-token-theme id)))} + i/delete]]])]])])) (mf/defc edit-theme [{:keys []}] diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index 475e3997a..e60939f2b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -15,13 +15,14 @@ display: grid; grid-template-rows: auto 1fr auto; width: 100%; - max-width: $s-640; + max-width: $s-468; } .modal-title { @include headlineMediumTypography; - margin-block-end: $s-32; - color: var(--modal-title-foreground-color); + font-weight: 500; + margin-block-end: $s-16; + color: var(--color-foreground-secondary); } .modal-content { @@ -32,3 +33,59 @@ .close-btn { @extend .modal-close-btn-base; } + +.theme-group-label { + display: block; + @include headlineMediumTypography; + color: var(--color-foreground-secondary); + margin-bottom: $s-8; +} + +.theme-group-rows-wrapper { + display: flex; + flex-direction: column; + gap: $s-6; +} + +.theme-group-wrapper { + display: flex; + flex-direction: column; + gap: $s-8; +} + +.theme-row { + display: flex; + align-items: center; + gap: $s-12; + justify-content: space-between; +} + +.theme-row-left { + display: flex; + align-items: center; + gap: $s-12; +} + +.theme-row-label { + @include bodyMediumTypography; +} + +.delete-theme-button { + @extend .button-tertiary; + height: $s-28; + width: $s-28; + button { + @include buttonStyle; + @include flexCenter; + width: $s-24; + height: 100%; + svg { + @extend .button-icon-small; + height: $s-12; + width: $s-12; + color: transparent; + fill: none; + stroke: var(--icon-foreground); + } + } +} From cac421f862a48a939bbfbe591c16613183ff41f6 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 15:41:32 +0200 Subject: [PATCH 05/48] Design --- .../src/app/main/ui/components/title_bar.cljs | 1 - .../ui/workspace/tokens/modals/themes.cljs | 60 ++++++++++++------- .../ui/workspace/tokens/modals/themes.scss | 52 +++++++++++++++- 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/frontend/src/app/main/ui/components/title_bar.cljs b/frontend/src/app/main/ui/components/title_bar.cljs index 04e621133..49a996570 100644 --- a/frontend/src/app/main/ui/components/title_bar.cljs +++ b/frontend/src/app/main/ui/components/title_bar.cljs @@ -10,7 +10,6 @@ [app.common.data.macros :as dm] [app.main.ui.icons :as i] [rumext.v2 :as mf])) - (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index cc65f0c3a..de46ed40e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -17,6 +17,8 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) +(def ^:private chevron-icon + (i/icon-xref :arrow (stl/css :chevron-icon))) (def ^:private close-icon (i/icon-xref :close (stl/css :close-icon))) @@ -45,28 +47,42 @@ [{:keys []}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) themes (mf/deref refs/workspace-ordered-token-themes)] - [:ul {:class (stl/css :theme-group-wrapper)} - (for [[group themes] themes] - [:li {:key (str "token-theme-group" group)} - [:span {:class (stl/css :theme-group-label)} group] - [:ul {:class (stl/css :theme-group-rows-wrapper)} - (for [{:keys [id name] :as _theme} themes] - [:li {:key (str "token-theme-" id) - :class (stl/css :theme-row)} - [:div {:class (stl/css :theme-row-left)} - [:div {:on-click (fn [e] - (dom/stop-propagation e) - (st/emit! (wdt/toggle-token-theme id)))} - [:& switch {:name (str "Theme" name) - :on-change (constantly nil) - :selected? (get active-theme-ids id)}]] - [:span {:class (stl/css :theme-row-label)} name]] - [:div {:class (stl/css :delete-theme-button)} - [:button {:on-click (fn [e] - (dom/prevent-default e) - (dom/stop-propagation e) - (st/emit! (wdt/delete-token-theme id)))} - i/delete]]])]])])) + [:div + [:ul {:class (stl/css :theme-group-wrapper)} + (for [[group themes] themes] + [:li {:key (str "token-theme-group" group)} + (when (seq group) + [:span {:class (stl/css :theme-group-label)} group]) + [:ul {:class (stl/css :theme-group-rows-wrapper)} + (for [{:keys [id name] :as theme} themes] + [:li {:key (str "token-theme-" id) + :class (stl/css :theme-row)} + [:div {:class (stl/css :theme-row-left)} + [:div {:on-click (fn [e] + (dom/stop-propagation e) + (st/emit! (wdt/toggle-token-theme id)))} + [:& switch {:name (str "Theme" name) + :on-change (constantly nil) + :selected? (get active-theme-ids id)}]] + [:span {:class (stl/css :theme-row-label)} name]] + [:div {:class (stl/css :theme-row-right)} + (if-let [sets-count (some-> theme :sets seq count)] + [:button {:class (stl/css :sets-count-button)} + (str sets-count " sets") + chevron-icon] + [:button {:class (stl/css :sets-count-empty-button)} + "No sets defined" + chevron-icon]) + [:div {:class (stl/css :delete-theme-button)} + [:button {:on-click (fn [e] + (dom/prevent-default e) + (dom/stop-propagation e) + (st/emit! (wdt/delete-token-theme id)))} + i/delete]]]])]])] + [:div {:class (stl/css :button-footer)} + [:button {:class (stl/css :create-theme-button)} + i/add + "Create theme"]]])) (mf/defc edit-theme [{:keys []}] diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index e60939f2b..9381e69e1 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -10,6 +10,10 @@ @extend .modal-overlay-base; } +hr { + border-color: var(--color-background-tertiary); +} + .modal-dialog { @extend .modal-container-base; display: grid; @@ -30,6 +34,22 @@ flex-direction: column; } +.button-footer { + display: flex; + justify-content: flex-end; +} + +.create-theme-button { + @extend .button-secondary; + padding: $s-6; + padding-right: $s-8; + svg { + margin-right: $s-6; + @extend .button-icon; + stroke: var(--icon-foreground); + } +} + .close-btn { @extend .modal-close-btn-base; } @@ -63,11 +83,41 @@ .theme-row-left { display: flex; align-items: center; - gap: $s-12; + gap: $s-16; +} + +.theme-row-right { + display: flex; + align-items: center; + gap: $s-6; +} + +.sets-count-button { + @extend .button-secondary; + padding: $s-6; + padding-left: $s-12; + svg { + margin-left: $s-6; + @extend .button-icon; + stroke: var(--icon-foreground); + } +} + +.sets-count-empty-button { + @extend .button-secondary; + padding: $s-6; + padding-left: $s-12; + svg { + margin-left: $s-6; + @extend .button-icon; + stroke: var(--icon-foreground); + } } .theme-row-label { @include bodyMediumTypography; + font-weight: 500; + color: var(--color-foreground-primary); } .delete-theme-button { From c7fa0f2cf8702c21f0703f940a6aeaf53bcb94a6 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 16:27:42 +0200 Subject: [PATCH 06/48] Cleanup --- frontend/src/app/main/ui/workspace/tokens/token_set.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs index 6a6a737c8..858183250 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs @@ -69,7 +69,7 @@ (defn toggle-active-theme-id "Toggle a `theme-id` by checking `:token-active-themes`. - De-activate all theme-ids that have the same group as `theme-id` when activating `theme-id`. + Deactivate all theme-ids that have the same group as `theme-id` when activating `theme-id`. Ensures that the temporary theme id is selected when the resulting set is empty." [theme-id state] (let [temp-theme-id-set (some->> (get-temp-theme-id state) (conj #{})) From 1c0233098d479fdc71a46a5567ac3106cb518990 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 16:28:06 +0200 Subject: [PATCH 07/48] Add sets list for theme --- .../ui/workspace/tokens/modals/themes.cljs | 55 +++++++++++++------ .../ui/workspace/tokens/modals/themes.scss | 6 ++ 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index de46ed40e..581b87643 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -10,6 +10,7 @@ [app.main.data.modal :as modal] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [cuerdas.core :as str] + [app.main.ui.workspace.tokens.sets :as wts] [app.main.data.tokens :as wdt] [app.main.refs :as refs] [app.main.store :as st] @@ -44,9 +45,14 @@ :label ""}]])) (mf/defc themes-overview - [{:keys []}] + [{:keys [set-state]}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) - themes (mf/deref refs/workspace-ordered-token-themes)] + themes (mf/deref refs/workspace-ordered-token-themes) + on-edit-theme (fn [theme e] + (dom/prevent-default e) + (dom/stop-propagation e) + (set-state (fn [_] {:type :edit-theme + :theme theme})))] [:div [:ul {:class (stl/css :theme-group-wrapper)} (for [[group themes] themes] @@ -54,23 +60,27 @@ (when (seq group) [:span {:class (stl/css :theme-group-label)} group]) [:ul {:class (stl/css :theme-group-rows-wrapper)} - (for [{:keys [id name] :as theme} themes] + (for [{:keys [id name] :as theme} themes + :let [selected? (some? (get active-theme-ids id))]] [:li {:key (str "token-theme-" id) :class (stl/css :theme-row)} [:div {:class (stl/css :theme-row-left)} [:div {:on-click (fn [e] + (dom/prevent-default e) (dom/stop-propagation e) (st/emit! (wdt/toggle-token-theme id)))} [:& switch {:name (str "Theme" name) :on-change (constantly nil) - :selected? (get active-theme-ids id)}]] + :selected? selected?}]] [:span {:class (stl/css :theme-row-label)} name]] [:div {:class (stl/css :theme-row-right)} (if-let [sets-count (some-> theme :sets seq count)] - [:button {:class (stl/css :sets-count-button)} + [:button {:class (stl/css :sets-count-button) + :on-click #(on-edit-theme theme %)} (str sets-count " sets") chevron-icon] - [:button {:class (stl/css :sets-count-empty-button)} + [:button {:class (stl/css :sets-count-empty-button) + :on-click #(on-edit-theme theme %)} "No sets defined" chevron-icon]) [:div {:class (stl/css :delete-theme-button)} @@ -85,21 +95,32 @@ "Create theme"]]])) (mf/defc edit-theme - [{:keys []}] - "Edit Theme") + [{:keys [state]}] + (let [{:keys [theme]} @state] + [:div {:class (stl/css :sets-list-wrapper)} + [:& wts/sets-list]])) (mf/defc themes [{:keys [] :as _args}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) themes (mf/deref refs/workspace-ordered-token-themes) - _ (js/console.log "themes" themes) state (mf/use-state (if (empty? themes) - :empty-themes - :themes-overview))] - (case @state - :empty-themes [:& empty-themes] - :themes-overview [:& themes-overview] - :edit-theme [:& edit-theme]))) + {:type :empty-themes} + {:type :themes-overview})) + set-state (mf/use-callback #(swap! state %)) + title (case (:type @state) + :edit-theme "Edit Theme" + "Themes") + component (case (:type @state) + :empty-themes empty-themes + :themes-overview themes-overview + :edit-theme edit-theme)] + [:div + + [:div {:class (stl/css :modal-title)} title] + [:div {:class (stl/css :modal-content)} + [:& component {:state state + :set-state set-state}]]])) (mf/defc modal {::mf/wrap-props false} @@ -108,6 +129,4 @@ [:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-dialog)} [:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon] - [:div {:class (stl/css :modal-title)} "Themes"] - [:div {:class (stl/css :modal-content)} - [:& themes]]]])) + [:& themes]]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index 9381e69e1..bb01cb0a0 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -103,6 +103,12 @@ hr { } } +.sets-list-wrapper { + border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent); + border-radius: $s-8; + overflow: hidden; +} + .sets-count-empty-button { @extend .button-secondary; padding: $s-6; From 8a20e3a698f29a66e4b189b03e86cbfe10477a47 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 16:34:33 +0200 Subject: [PATCH 08/48] Allow tokens sets component to be controlled --- .../ui/workspace/tokens/modals/themes.cljs | 19 ++++++++++++++-- .../app/main/ui/workspace/tokens/sets.cljs | 22 ++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 581b87643..eac37fe8e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -96,9 +96,24 @@ (mf/defc edit-theme [{:keys [state]}] - (let [{:keys [theme]} @state] + (let [{:keys [theme]} @state + token-sets (mf/deref refs/workspace-token-sets) + selected-token-set-id (mf/deref refs/workspace-selected-token-set-id) + token-set-selected? (mf/use-callback + (mf/deps selected-token-set-id) + (fn [id] + (= id selected-token-set-id))) + active-token-set-ids (mf/deref refs/workspace-active-set-ids) + token-set-active? (mf/use-callback + (mf/deps active-token-set-ids) + (fn [id] + (get active-token-set-ids id)))] [:div {:class (stl/css :sets-list-wrapper)} - [:& wts/sets-list]])) + [:& wts/controlled-sets-list + {:token-sets token-sets + :selected-token-set-id selected-token-set-id + :token-set-selected? token-set-selected? + :token-set-active? token-set-active?}]])) (mf/defc themes [{:keys [] :as _args}] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 852844bf5..fb1780469 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -64,6 +64,15 @@ :set-id child-id :selected-set-id selected-token-set-id)])])])) +(mf/defc controlled-sets-list + [{:keys [token-sets] :as props}] + [:ul {:class (stl/css :sets-list)} + (for [[id token-set] token-sets] + [:& sets-tree (-> (assoc props + :key id + :token-set token-set) + (dissoc :token-sets))])]) + (mf/defc sets-list [{:keys []}] (let [token-sets (mf/deref refs/workspace-token-sets) @@ -77,11 +86,8 @@ (mf/deps active-token-set-ids) (fn [id] (get active-token-set-ids id)))] - [:ul {:class (stl/css :sets-list)} - (for [[id token-set] token-sets] - [:& sets-tree - {:key id - :token-set token-set - :selected-token-set-id selected-token-set-id - :token-set-selected? token-set-selected? - :token-set-active? token-set-active?}])])) + [:& controlled-sets-list + {:token-sets token-sets + :selected-token-set-id selected-token-set-id + :token-set-selected? token-set-selected? + :token-set-active? token-set-active?}])) From 7e7203eb7cd1e494fd5c497ba5d439597b0868f4 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 16:44:11 +0200 Subject: [PATCH 09/48] Allow passing custom functions --- .../ui/workspace/tokens/modals/themes.cljs | 9 ++++++--- .../app/main/ui/workspace/tokens/sets.cljs | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index eac37fe8e..7d9467bb8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -111,9 +111,12 @@ [:div {:class (stl/css :sets-list-wrapper)} [:& wts/controlled-sets-list {:token-sets token-sets - :selected-token-set-id selected-token-set-id - :token-set-selected? token-set-selected? - :token-set-active? token-set-active?}]])) + :token-set-selected? (constantly false) + :token-set-active? token-set-active? + :on-select (fn [id] + (js/console.log "id" id)) + :on-toggle (fn [id] + (js/console.log "id" id))}]])) (mf/defc themes [{:keys [] :as _args}] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index fb1780469..00d8da654 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -17,11 +17,10 @@ (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) -(defn on-toggle-token-set-click [id event] - (dom/stop-propagation event) +(defn on-toggle-token-set-click [id] (st/emit! (wdt/toggle-token-set id))) -(defn on-select-token-set-click [id event] +(defn on-select-token-set-click [id] (st/emit! (wdt/set-selected-token-set-id id))) (defn on-delete-token-set-click [id event] @@ -29,7 +28,7 @@ (st/emit! (wdt/delete-token-set id))) (mf/defc sets-tree - [{:keys [token-set token-set-active? token-set-selected?] :as _props}] + [{:keys [token-set token-set-active? token-set-selected? on-select on-toggle] :as _props}] (let [{:keys [id name _children]} token-set selected? (and set? (token-set-selected? id)) visible? (token-set-active? id) @@ -37,7 +36,9 @@ set? true #_(= type :set) group? false #_(= type :group)] [:div {:class (stl/css :set-item-container) - :on-click #(on-select-token-set-click id %)} + :on-click (fn [event] + (dom/stop-propagation event) + (on-select id))} [:div {:class (stl/css-case :set-item-group group? :set-item-set set? :selected-set selected?)} @@ -54,7 +55,9 @@ i/delete]] (when set? [:span {:class (stl/css :action-btn) - :on-click #(on-toggle-token-set-click id %)} + :on-click (fn [event] + (dom/stop-propagation event) + (on-toggle id))} (if visible? i/shown i/hide)])] #_(when (and children (not @collapsed?)) [:div {:class (stl/css :set-children)} @@ -90,4 +93,6 @@ {:token-sets token-sets :selected-token-set-id selected-token-set-id :token-set-selected? token-set-selected? - :token-set-active? token-set-active?}])) + :token-set-active? token-set-active? + :on-select on-select-token-set-click + :on-toggle on-toggle-token-set-click}])) From 6f7b69c7ee5fff6eb591f4d2dbd02d7a5950426a Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 16:58:49 +0200 Subject: [PATCH 10/48] Allow toggling individual set themes --- frontend/src/app/main/data/tokens.cljs | 5 ++-- frontend/src/app/main/refs.cljs | 4 +++ frontend/src/app/main/ui.cljs | 2 ++ .../ui/workspace/tokens/modals/themes.cljs | 26 +++++++++---------- .../app/main/ui/workspace/tokens/sets.cljs | 4 +-- .../main/ui/workspace/tokens/token_set.cljs | 3 +++ 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index d40734f70..58cc38f75 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -157,11 +157,12 @@ (rx/of (dch/commit-changes changes))))))) -(defn toggle-token-set [token-set-id] +(defn toggle-token-set [{:keys [token-set-id token-theme-id]}] (ptk/reify ::toggle-token-set ptk/WatchEvent (watch [it state _] - (let [theme (some-> (wtts/update-theme-id state) + (js/console.log "token-set-id token-theme-id" token-set-id token-theme-id) + (let [theme (some-> (or token-theme-id (wtts/update-theme-id state)) (wtts/get-workspace-token-theme state)) changes (-> (pcb/empty-changes it) (pcb/update-token-theme diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index b1177e8c2..dcf7381f1 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -240,6 +240,10 @@ st/state =)) +(defn workspace-token-theme + [id] + (l/derived #(wtts/get-workspace-theme id %) st/state)) + (def workspace-active-theme-ids (l/derived wtts/get-active-theme-ids st/state)) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 60803b2ee..345265587 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -6,6 +6,7 @@ (ns app.main.ui (:require + [app.main.ui.workspace.tokens.modals.themes :as wtmt] [app.config :as cf] [app.main.refs :as refs] [app.main.store :as st] @@ -191,6 +192,7 @@ [:& (mf/provider ctx/current-route) {:value route} [:& (mf/provider ctx/current-profile) {:value profile} + [:& wtmt/modal] (if edata [:& static/exception-page {:data edata :route route}] [:* diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 7d9467bb8..9720bb16a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -52,7 +52,7 @@ (dom/prevent-default e) (dom/stop-propagation e) (set-state (fn [_] {:type :edit-theme - :theme theme})))] + :theme-id (:id theme)})))] [:div [:ul {:class (stl/css :theme-group-wrapper)} (for [[group themes] themes] @@ -96,27 +96,25 @@ (mf/defc edit-theme [{:keys [state]}] - (let [{:keys [theme]} @state + (let [{:keys [theme-id]} @state token-sets (mf/deref refs/workspace-token-sets) - selected-token-set-id (mf/deref refs/workspace-selected-token-set-id) - token-set-selected? (mf/use-callback - (mf/deps selected-token-set-id) - (fn [id] - (= id selected-token-set-id))) - active-token-set-ids (mf/deref refs/workspace-active-set-ids) + theme (mf/deref (refs/workspace-token-theme theme-id)) token-set-active? (mf/use-callback - (mf/deps active-token-set-ids) + (mf/deps (:sets theme)) (fn [id] - (get active-token-set-ids id)))] + (get-in theme [:sets id]))) + on-toggle-token-set (mf/use-callback + (mf/deps (:id theme)) + (fn [token-set-id] + (st/emit! (wdt/toggle-token-set {:token-set-id token-set-id + :token-theme-id (:id theme)}))))] [:div {:class (stl/css :sets-list-wrapper)} [:& wts/controlled-sets-list {:token-sets token-sets :token-set-selected? (constantly false) :token-set-active? token-set-active? - :on-select (fn [id] - (js/console.log "id" id)) - :on-toggle (fn [id] - (js/console.log "id" id))}]])) + :on-select on-toggle-token-set + :on-toggle on-toggle-token-set}]])) (mf/defc themes [{:keys [] :as _args}] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 00d8da654..a7813a9ea 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -17,8 +17,8 @@ (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) -(defn on-toggle-token-set-click [id] - (st/emit! (wdt/toggle-token-set id))) +(defn on-toggle-token-set-click [token-set-id] + (st/emit! (wdt/toggle-token-set {:token-set-id token-set-id}))) (defn on-select-token-set-click [id] (st/emit! (wdt/set-selected-token-set-id id))) diff --git a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs index 858183250..488c85bf4 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs @@ -12,6 +12,9 @@ (defn get-workspace-themes [state] (get-in state [:workspace-data :token-themes] [])) +(defn get-workspace-theme [id state] + (get-in state [:workspace-data :token-themes-index id])) + (defn get-workspace-themes-index [state] (get-in state [:workspace-data :token-themes-index] {})) From db1250a3158a9f9253f6d8b8a12b43e5ffbd80a6 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 17:07:47 +0200 Subject: [PATCH 11/48] Add footer buttons --- frontend/src/app/main/ui.cljs | 1 - .../ui/workspace/tokens/modals/themes.cljs | 26 +++++++++++++----- .../ui/workspace/tokens/modals/themes.scss | 27 +++++++++++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 345265587..b9c661c3a 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -192,7 +192,6 @@ [:& (mf/provider ctx/current-route) {:value route} [:& (mf/provider ctx/current-profile) {:value profile} - [:& wtmt/modal] (if edata [:& static/exception-page {:data edata :route route}] [:* diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 9720bb16a..9c8c4014f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -10,6 +10,7 @@ [app.main.data.modal :as modal] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [cuerdas.core :as str] + [app.main.ui.workspace.tokens.common :refer [labeled-input]] [app.main.ui.workspace.tokens.sets :as wts] [app.main.data.tokens :as wdt] [app.main.refs :as refs] @@ -108,13 +109,24 @@ (fn [token-set-id] (st/emit! (wdt/toggle-token-set {:token-set-id token-set-id :token-theme-id (:id theme)}))))] - [:div {:class (stl/css :sets-list-wrapper)} - [:& wts/controlled-sets-list - {:token-sets token-sets - :token-set-selected? (constantly false) - :token-set-active? token-set-active? - :on-select on-toggle-token-set - :on-toggle on-toggle-token-set}]])) + [:div {:class (stl/css :edit-theme-wrapper)} + [:div {:class (stl/css :edit-theme-inputs-wrapper)} + [:& labeled-input {:label "Group" + :input-props {:value (:group theme)}}] + [:& labeled-input {:label "Theme" + :input-props {:value (:name theme)}}]] + [:div {:class (stl/css :sets-list-wrapper)} + [:& wts/controlled-sets-list + {:token-sets token-sets + :token-set-selected? (constantly false) + :token-set-active? token-set-active? + :on-select on-toggle-token-set + :on-toggle on-toggle-token-set}]] + [:div {:class (stl/css :edit-theme-footer)} + [:button {:class (stl/css :button-secondary)} "Delete"] + [:div {:class (stl/css :button-footer)} + [:button {:class (stl/css :button-secondary)} "Cancel"] + [:button {:class (stl/css :button-primary)} "Save theme"]]]])) (mf/defc themes [{:keys [] :as _args}] diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index bb01cb0a0..b7085ccae 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -37,6 +37,22 @@ hr { .button-footer { display: flex; justify-content: flex-end; + gap: $s-6; +} + +.edit-theme-footer { + display: flex; + justify-content: space-between; +} + +.button-primary { + @extend .button-primary; + padding: $s-6; +} + +.button-secondary { + @extend .button-secondary; + padding: $s-6; } .create-theme-button { @@ -103,6 +119,17 @@ hr { } } +.edit-theme-wrapper { + display: flex; + flex-direction: column; + gap: $s-12; +} + +.edit-theme-inputs-wrapper { + display: flex; + gap: $s-12; +} + .sets-list-wrapper { border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent); border-radius: $s-8; From 3ce2531b427715c253371325adc382f9f33dff7c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 17:11:38 +0200 Subject: [PATCH 12/48] Design --- frontend/src/app/main/ui/workspace/tokens/modals/themes.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index b7085ccae..df1e611fd 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -126,7 +126,8 @@ hr { } .edit-theme-inputs-wrapper { - display: flex; + display: grid; + grid-template-columns: 0.6fr 1fr; gap: $s-12; } From 967fab416a2506d44d30c76454ecf1bca2ac9444 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 17:20:20 +0200 Subject: [PATCH 13/48] Add back button --- .../app/main/ui/workspace/tokens/modals/themes.cljs | 6 +++++- .../app/main/ui/workspace/tokens/modals/themes.scss | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 9c8c4014f..cd23c4ab3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -96,7 +96,7 @@ "Create theme"]]])) (mf/defc edit-theme - [{:keys [state]}] + [{:keys [state set-state]}] (let [{:keys [theme-id]} @state token-sets (mf/deref refs/workspace-token-sets) theme (mf/deref (refs/workspace-token-theme theme-id)) @@ -110,6 +110,10 @@ (st/emit! (wdt/toggle-token-set {:token-set-id token-set-id :token-theme-id (:id theme)}))))] [:div {:class (stl/css :edit-theme-wrapper)} + [:div + [:button {:class (stl/css :back-button) + :on-click #(set-state (constantly {:type :themes-overview}))} + chevron-icon "Back"]] [:div {:class (stl/css :edit-theme-inputs-wrapper)} [:& labeled-input {:label "Group" :input-props {:value (:group theme)}}] diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index df1e611fd..f374569fd 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -108,6 +108,19 @@ hr { gap: $s-6; } +.back-button { + @extend .button-tertiary; + padding: $s-6; + padding-left: 0; + display: flex; + svg { + scale: -1 1; + margin-left: 0; + @extend .button-icon; + stroke: var(--icon-foreground); + } +} + .sets-count-button { @extend .button-secondary; padding: $s-6; From a52e20f49db6313ccfdcd048658c184d8684196e Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 17:22:05 +0200 Subject: [PATCH 14/48] Cleanup --- frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index cd23c4ab3..f2f0b0420 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -134,8 +134,7 @@ (mf/defc themes [{:keys [] :as _args}] - (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) - themes (mf/deref refs/workspace-ordered-token-themes) + (let [themes (mf/deref refs/workspace-ordered-token-themes) state (mf/use-state (if (empty? themes) {:type :empty-themes} {:type :themes-overview})) From 12e915dec89ce6e24fd4bf636c10c6d7fa8d1cd1 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 23 Aug 2024 17:48:43 +0200 Subject: [PATCH 15/48] Style edit button --- .../app/main/ui/workspace/tokens/sidebar.cljs | 72 ++++++------------- .../app/main/ui/workspace/tokens/sidebar.scss | 24 +++++++ 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 59019201a..57a165f72 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -11,6 +11,7 @@ [app.main.data.modal :as modal] [app.main.data.tokens :as dt] [app.main.data.tokens :as wdt] + [app.main.ui.components.select :refer [select]] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar]] @@ -180,61 +181,32 @@ :name @name}))} "Create"]])) +(mf/defc edit-button + [{:keys []}] + [:button {:class (stl/css :themes-button) + :on-click (fn [e] + (dom/stop-propagation e) + (modal/show! :tokens/themes {}))} + "Edit"]) + (mf/defc themes-sidebar [_props] (let [open? (mf/use-state true) active-theme-ids (mf/deref refs/workspace-active-theme-ids) themes (mf/deref refs/workspace-ordered-token-themes)] - [:div {:class (stl/css :sets-sidebar)} - [:div {:class (stl/css :sidebar-header)} - [:& title-bar {:collapsable true - :collapsed (not @open?) - :all-clickable true - :title "THEMES" - :on-collapsed #(swap! open? not)}] - [:button {:class (stl/css :add-set) - :on-click (fn [event] - (modal/show! :tokens/themes {:x (.-clientX ^js event) - :y (.-clientY ^js event)}))} - i/add]] - (when @open? - [:div - [:style - (str "@scope {" - (str/join "\n" - ["ul { list-style-type: circle; margin-left: 20px; }" - ".spaced { display: flex; gap: 10px; justify-content: space-between; }" - ".spaced-y { display: flex; flex-direction: column; gap: 10px }" - ".selected { font-weight: 600; }" - "b { font-weight: 600; }"]) - "}")] - [:div.spaced-y - {:style {:padding "10px"}} - [:& tokene-theme-create] - [:div.spaced-y - [:b "Themes"] - [:ul - (for [[group themes] themes] - [:li - {:key (str "token-theme-group" group)} - group - [:ul - (for [{:keys [id name] :as _theme} themes] - [:li {:key (str "tokene-theme-" id)} - [:div.spaced - name - [:div.spaced - [:button - {:on-click (fn [e] - (dom/prevent-default e) - (dom/stop-propagation e) - (st/emit! (wdt/toggle-token-theme id)))} - (if (get active-theme-ids id) "✅" "❎")] - [:button {:on-click (fn [e] - (dom/prevent-default e) - (dom/stop-propagation e) - (st/emit! (wdt/delete-token-theme id)))} - "🗑️"]]]])]])]]]])])) + [:div {:class (stl/css :theme-sidebar)} + [:span {:class (stl/css :themes-header)} "Themes"] + [:div {:class (stl/css :theme-select-wrapper)} + [:& select + {:default-value (some-> active-theme-ids first) + :class (stl/css :select-format-wrapper) + :options (mapcat (fn [[_ xs]] + (map (fn [{:keys [id name] :as f}] + (js/console.log "f" f) + {:value id :label name}) + xs)) + themes)}] + [:& edit-button]]])) (mf/defc sets-sidebar [] diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss index e90b12d3c..ea10bc549 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss @@ -24,6 +24,11 @@ position: relative; } +.theme-sidebar { + padding: $s-12; + padding-bottom: 0; +} + .sidebar-header { display: flex; align-items: center; @@ -114,3 +119,22 @@ height: 20px; } } + +.theme-select-wrapper { + display: grid; + grid-template-columns: 1fr 0.28fr; + gap: $s-6; +} + +.themes-button { + @extend .button-secondary; + width: auto; +} + +.themes-header { + display: block; + @include headlineSmallTypography; + margin-bottom: $s-8; + padding-left: $s-8; + color: var(--title-foreground-color); +} From fe702988f9324a9e4c83a2d70d0ffbdb6a5e1c2b Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 13:40:49 +0200 Subject: [PATCH 16/48] Cleanup --- frontend/src/app/main/ui/workspace/tokens/sidebar.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 57a165f72..1451d5e39 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -202,7 +202,6 @@ :class (stl/css :select-format-wrapper) :options (mapcat (fn [[_ xs]] (map (fn [{:keys [id name] :as f}] - (js/console.log "f" f) {:value id :label name}) xs)) themes)}] From a0dd3f63bf543058d1d83982d29e61147de1af36 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 13:41:02 +0200 Subject: [PATCH 17/48] Allow controlling state of theme editing --- .../ui/workspace/tokens/modals/themes.cljs | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index f2f0b0420..e7b566803 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -9,6 +9,7 @@ (:require [app.main.data.modal :as modal] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] + [app.main.ui.workspace.tokens.token-set :as wtts] [cuerdas.core :as str] [app.main.ui.workspace.tokens.common :refer [labeled-input]] [app.main.ui.workspace.tokens.sets :as wts] @@ -96,23 +97,22 @@ "Create theme"]]])) (mf/defc edit-theme - [{:keys [state set-state]}] - (let [{:keys [theme-id]} @state - token-sets (mf/deref refs/workspace-token-sets) - theme (mf/deref (refs/workspace-token-theme theme-id)) + [{:keys [token-sets theme on-back] :as props}] + (let [theme-state (mf/use-state {:token-sets token-sets + :theme theme}) token-set-active? (mf/use-callback - (mf/deps (:sets theme)) + (mf/deps theme-state) (fn [id] - (get-in theme [:sets id]))) + (get-in @theme-state [:theme :sets id]))) on-toggle-token-set (mf/use-callback - (mf/deps (:id theme)) + (mf/deps theme-state) (fn [token-set-id] - (st/emit! (wdt/toggle-token-set {:token-set-id token-set-id - :token-theme-id (:id theme)}))))] + (swap! theme-state (fn [st] + (update st :theme #(wtts/toggle-token-set-to-token-theme token-set-id %))))))] [:div {:class (stl/css :edit-theme-wrapper)} [:div [:button {:class (stl/css :back-button) - :on-click #(set-state (constantly {:type :themes-overview}))} + :on-click on-back} chevron-icon "Back"]] [:div {:class (stl/css :edit-theme-inputs-wrapper)} [:& labeled-input {:label "Group" @@ -132,6 +132,16 @@ [:button {:class (stl/css :button-secondary)} "Cancel"] [:button {:class (stl/css :button-primary)} "Save theme"]]]])) +(mf/defc controlled-edit-theme + [{:keys [state set-state]}] + (let [{:keys [theme-id]} @state + token-sets (mf/deref refs/workspace-token-sets) + theme (mf/deref (refs/workspace-token-theme theme-id))] + [:& edit-theme + {:token-sets token-sets + :theme theme + :on-back #(set-state (constantly {:type :themes-overview}))}])) + (mf/defc themes [{:keys [] :as _args}] (let [themes (mf/deref refs/workspace-ordered-token-themes) @@ -145,7 +155,7 @@ component (case (:type @state) :empty-themes empty-themes :themes-overview themes-overview - :edit-theme edit-theme)] + :edit-theme controlled-edit-theme)] [:div [:div {:class (stl/css :modal-title)} title] From 36f92aa241efa3bfb0e3e7d700aad615151e5bbb Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 13:47:44 +0200 Subject: [PATCH 18/48] Allow group and name updating --- .../app/main/ui/workspace/tokens/modals/themes.cljs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index e7b566803..8c7eaecd5 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -108,7 +108,12 @@ (mf/deps theme-state) (fn [token-set-id] (swap! theme-state (fn [st] - (update st :theme #(wtts/toggle-token-set-to-token-theme token-set-id %))))))] + (update st :theme #(wtts/toggle-token-set-to-token-theme token-set-id %)))))) + on-update-field (fn [field] + (fn [e] + (swap! theme-state (fn [st] (assoc-in st field (dom/get-target-val e)))))) + on-update-group (on-update-field [:theme :group]) + on-update-name (on-update-field [:theme :name])] [:div {:class (stl/css :edit-theme-wrapper)} [:div [:button {:class (stl/css :back-button) @@ -116,9 +121,11 @@ chevron-icon "Back"]] [:div {:class (stl/css :edit-theme-inputs-wrapper)} [:& labeled-input {:label "Group" - :input-props {:value (:group theme)}}] + :input-props {:default-value (:group theme) + :on-change on-update-group}}] [:& labeled-input {:label "Theme" - :input-props {:value (:name theme)}}]] + :input-props {:default-value (:name theme) + :on-change on-update-name}}]] [:div {:class (stl/css :sets-list-wrapper)} [:& wts/controlled-sets-list {:token-sets token-sets From 70b570f112101157d76bc5cc101b6bb94c128122 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 13:49:57 +0200 Subject: [PATCH 19/48] Show only on create --- .../src/app/main/ui/workspace/tokens/modals/themes.cljs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 8c7eaecd5..adfc659b0 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -98,7 +98,8 @@ (mf/defc edit-theme [{:keys [token-sets theme on-back] :as props}] - (let [theme-state (mf/use-state {:token-sets token-sets + (let [edit? (some? (:id theme)) + theme-state (mf/use-state {:token-sets token-sets :theme theme}) token-set-active? (mf/use-callback (mf/deps theme-state) @@ -134,7 +135,8 @@ :on-select on-toggle-token-set :on-toggle on-toggle-token-set}]] [:div {:class (stl/css :edit-theme-footer)} - [:button {:class (stl/css :button-secondary)} "Delete"] + (when edit? + [:button {:class (stl/css :button-secondary)} "Delete"]) [:div {:class (stl/css :button-footer)} [:button {:class (stl/css :button-secondary)} "Cancel"] [:button {:class (stl/css :button-primary)} "Save theme"]]]])) From 7aff690e7be492f402b0f897bac0a1a7c340e02c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:17:30 +0200 Subject: [PATCH 20/48] Wire up theme updating --- frontend/src/app/main/data/tokens.cljs | 11 +++ .../ui/workspace/tokens/modals/themes.cljs | 86 +++++++++++-------- 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 58cc38f75..645542331 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -102,6 +102,17 @@ (rx/of (dch/commit-changes changes))))))) +(defn update-token-theme [token-theme] + (ptk/reify ::update-token-theme + ptk/WatchEvent + (watch [it state _] + (let [prev-token-theme (wtts/get-workspace-token-theme state (:id token-theme)) + changes (-> (pcb/empty-changes it) + (pcb/update-token-theme token-theme prev-token-theme))] + (js/console.log "changes" changes) + (rx/of + (dch/commit-changes changes)))))) + (defn ensure-token-theme-changes [changes state {:keys [id new-set?]}] (let [theme-id (wtts/update-theme-id state) theme (some-> theme-id (wtts/get-workspace-token-theme state))] diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index adfc659b0..6f3d27782 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -8,15 +8,14 @@ (:require-macros [app.main.style :as stl]) (:require [app.main.data.modal :as modal] - [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] - [app.main.ui.workspace.tokens.token-set :as wtts] - [cuerdas.core :as str] - [app.main.ui.workspace.tokens.common :refer [labeled-input]] - [app.main.ui.workspace.tokens.sets :as wts] [app.main.data.tokens :as wdt] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.icons :as i] + [app.main.ui.workspace.tokens.common :refer [labeled-input]] + [app.main.ui.workspace.tokens.sets :as wts] + [app.main.ui.workspace.tokens.token-set :as wtts] [app.util.dom :as dom] [rumext.v2 :as mf])) @@ -97,7 +96,7 @@ "Create theme"]]])) (mf/defc edit-theme - [{:keys [token-sets theme on-back] :as props}] + [{:keys [token-sets theme on-back on-submit] :as props}] (let [edit? (some? (:id theme)) theme-state (mf/use-state {:token-sets token-sets :theme theme}) @@ -110,36 +109,52 @@ (fn [token-set-id] (swap! theme-state (fn [st] (update st :theme #(wtts/toggle-token-set-to-token-theme token-set-id %)))))) - on-update-field (fn [field] + on-change-field (fn [field] (fn [e] (swap! theme-state (fn [st] (assoc-in st field (dom/get-target-val e)))))) - on-update-group (on-update-field [:theme :group]) - on-update-name (on-update-field [:theme :name])] - [:div {:class (stl/css :edit-theme-wrapper)} - [:div - [:button {:class (stl/css :back-button) - :on-click on-back} - chevron-icon "Back"]] - [:div {:class (stl/css :edit-theme-inputs-wrapper)} - [:& labeled-input {:label "Group" - :input-props {:default-value (:group theme) - :on-change on-update-group}}] - [:& labeled-input {:label "Theme" - :input-props {:default-value (:name theme) - :on-change on-update-name}}]] - [:div {:class (stl/css :sets-list-wrapper)} - [:& wts/controlled-sets-list - {:token-sets token-sets - :token-set-selected? (constantly false) - :token-set-active? token-set-active? - :on-select on-toggle-token-set - :on-toggle on-toggle-token-set}]] - [:div {:class (stl/css :edit-theme-footer)} - (when edit? - [:button {:class (stl/css :button-secondary)} "Delete"]) - [:div {:class (stl/css :button-footer)} - [:button {:class (stl/css :button-secondary)} "Cancel"] - [:button {:class (stl/css :button-primary)} "Save theme"]]]])) + on-update-group (on-change-field [:theme :group]) + on-update-name (on-change-field [:theme :name]) + on-save-form (mf/use-callback + (mf/deps theme-state on-submit) + (fn [e] + (dom/prevent-default e) + (on-submit (:theme @theme-state)) + (on-back)))] + [:form {:on-submit on-save-form} + [:div {:class (stl/css :edit-theme-wrapper)} + [:div + [:button {:class (stl/css :back-button) + :type "button" + :on-click on-back} + chevron-icon "Back"]] + [:div {:class (stl/css :edit-theme-inputs-wrapper)} + [:& labeled-input {:label "Group" + :input-props {:default-value (:group theme) + :on-change on-update-group}}] + [:& labeled-input {:label "Theme" + :input-props {:default-value (:name theme) + :on-change on-update-name}}]] + [:div {:class (stl/css :sets-list-wrapper)} + [:& wts/controlled-sets-list + {:token-sets token-sets + :token-set-selected? (constantly false) + :token-set-active? token-set-active? + :on-select on-toggle-token-set + :on-toggle on-toggle-token-set}]] + [:div {:class (stl/css :edit-theme-footer)} + (when edit? + [:button {:class (stl/css :button-secondary) + :type "button"} + "Delete"]) + [:div {:class (stl/css :button-footer)} + [:button {:class (stl/css :button-secondary) + :type "button" + :on-click #(st/emit! (modal/hide))} + "Cancel"] + [:button {:class (stl/css :button-primary) + :type "submit" + :on-click on-save-form} + "Save theme"]]]]])) (mf/defc controlled-edit-theme [{:keys [state set-state]}] @@ -149,7 +164,8 @@ [:& edit-theme {:token-sets token-sets :theme theme - :on-back #(set-state (constantly {:type :themes-overview}))}])) + :on-back #(set-state (constantly {:type :themes-overview})) + :on-submit #(st/emit! (wdt/update-token-theme %))}])) (mf/defc themes [{:keys [] :as _args}] From 84b5be5547884e9243e78f5b319de7f820beca23 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:17:37 +0200 Subject: [PATCH 21/48] Fix button being chosen as main button for form submit --- frontend/src/app/main/ui/workspace/tokens/sets.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index a7813a9ea..0e29b8a2d 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -51,7 +51,8 @@ (if set? i/document i/group)] [:div {:class (stl/css :set-name)} name] [:div {:class (stl/css :delete-set)} - [:button {:on-click #(on-delete-token-set-click id %)} + [:button {:on-click #(on-delete-token-set-click id %) + :type "button"} i/delete]] (when set? [:span {:class (stl/css :action-btn) From f37cf8be5e0503d3e14f2c3959d48455f98f1e76 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:31:34 +0200 Subject: [PATCH 22/48] Add defaults for theme form --- .../app/main/ui/workspace/tokens/modals/themes.cljs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 6f3d27782..58aa16c50 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -17,7 +17,8 @@ [app.main.ui.workspace.tokens.sets :as wts] [app.main.ui.workspace.tokens.token-set :as wtts] [app.util.dom :as dom] - [rumext.v2 :as mf])) + [rumext.v2 :as mf] + [cuerdas.core :as str])) (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) @@ -118,7 +119,15 @@ (mf/deps theme-state on-submit) (fn [e] (dom/prevent-default e) - (on-submit (:theme @theme-state)) + (let [theme (:theme @theme-state) + final-name (str/trim (:name theme)) + final-group (-> (:group theme) + (str/trim) + (str/lower))] + (cond-> theme + (empty final-name) (assoc :name "Theme") + (empty final-group) (dissoc :group) + :always on-submit)) (on-back)))] [:form {:on-submit on-save-form} [:div {:class (stl/css :edit-theme-wrapper)} From b5e08c5b8b3fa6f8c89b0ff2adbdefbb86e3a15a Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:32:01 +0200 Subject: [PATCH 23/48] Add theme creation form --- .../ui/workspace/tokens/modals/themes.cljs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 58aa16c50..5d6431c33 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -92,7 +92,11 @@ (st/emit! (wdt/delete-token-theme id)))} i/delete]]]])]])] [:div {:class (stl/css :button-footer)} - [:button {:class (stl/css :create-theme-button)} + [:button {:class (stl/css :create-theme-button) + :on-click (fn [e] + (dom/prevent-default e) + (dom/stop-propagation e) + (set-state (fn [_] {:type :create-theme})))} i/add "Create theme"]]])) @@ -176,6 +180,16 @@ :on-back #(set-state (constantly {:type :themes-overview})) :on-submit #(st/emit! (wdt/update-token-theme %))}])) +(mf/defc create-theme + [{:keys [set-state]}] + (let [token-sets (mf/deref refs/workspace-token-sets) + theme {:name "Theme" :sets #{}}] + [:& edit-theme + {:token-sets token-sets + :theme theme + :on-back #(set-state (constantly {:type :themes-overview})) + :on-submit #(st/emit! (wdt/create-token-theme %))}])) + (mf/defc themes [{:keys [] :as _args}] (let [themes (mf/deref refs/workspace-ordered-token-themes) @@ -189,7 +203,8 @@ component (case (:type @state) :empty-themes empty-themes :themes-overview themes-overview - :edit-theme controlled-edit-theme)] + :edit-theme controlled-edit-theme + :create-theme create-theme)] [:div [:div {:class (stl/css :modal-title)} title] From 1405720e0b4905bd946d57316835e40cd39b5442 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:32:21 +0200 Subject: [PATCH 24/48] Cleanup --- frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 5d6431c33..a55c508fb 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -206,7 +206,6 @@ :edit-theme controlled-edit-theme :create-theme create-theme)] [:div - [:div {:class (stl/css :modal-title)} title] [:div {:class (stl/css :modal-content)} [:& component {:state state From 5939db771ede2e57163cc8d0b3557e7bea915320 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:34:41 +0200 Subject: [PATCH 25/48] Link up delete button & fix create theme ui jumping --- .../app/main/ui/workspace/tokens/modals/themes.cljs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index a55c508fb..5ffee750b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -155,10 +155,14 @@ :on-select on-toggle-token-set :on-toggle on-toggle-token-set}]] [:div {:class (stl/css :edit-theme-footer)} - (when edit? + (if edit? [:button {:class (stl/css :button-secondary) - :type "button"} - "Delete"]) + :type "button" + :on-click (fn [] + (st/emit! (wdt/delete-token-theme (:id theme))) + (on-back))} + "Delete"] + [:div]) [:div {:class (stl/css :button-footer)} [:button {:class (stl/css :button-secondary) :type "button" From 7cd9c60fb6cec0fa415b6724a493d8fc35bfac3d Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 14:36:00 +0200 Subject: [PATCH 26/48] Disable user-selection --- frontend/src/app/main/ui/workspace/tokens/modals/themes.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index f374569fd..b0b834393 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -20,6 +20,7 @@ hr { grid-template-rows: auto 1fr auto; width: 100%; max-width: $s-468; + user-select: none; } .modal-title { From 4060b6d40f26f4848e5ee893b252f2f0f162fd7f Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 15:02:38 +0200 Subject: [PATCH 27/48] Style empty state, jump to create theme dialog when no themes exist --- .../ui/workspace/tokens/modals/themes.cljs | 16 +++++++++---- .../ui/workspace/tokens/modals/themes.scss | 24 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 5ffee750b..7148c7052 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -27,9 +27,15 @@ (i/icon-xref :close (stl/css :close-icon))) (mf/defc empty-themes - [{:keys []}] - "Empty") - + [{:keys [set-state]}] + [:div {:class (stl/css :empty-themes-wrapper)} + [:div {:class (stl/css :empty-themes-message)} + [:h1 "You currently have no themes."] + [:p "Create your first theme now."]] + [:div {:class (stl/css :button-footer)} + [:button {:class (stl/css :button-primary) + :on-click #(set-state (fn [_] {:type :create-theme}))} + "New theme"]]]) (mf/defc switch [{:keys [selected? name on-change]}] @@ -198,7 +204,7 @@ [{:keys [] :as _args}] (let [themes (mf/deref refs/workspace-ordered-token-themes) state (mf/use-state (if (empty? themes) - {:type :empty-themes} + {:type :create-theme} {:type :themes-overview})) set-state (mf/use-callback #(swap! state %)) title (case (:type @state) @@ -206,7 +212,7 @@ "Themes") component (case (:type @state) :empty-themes empty-themes - :themes-overview themes-overview + :themes-overview (if (empty? themes) empty-themes themes-overview) :edit-theme controlled-edit-theme :create-theme create-theme)] [:div diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index b0b834393..43844c392 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -56,6 +56,30 @@ hr { padding: $s-6; } +.empty-themes-wrapper { + display: flex; + flex-direction: column; + + .empty-themes-message { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: $s-12; + padding: $s-72 0; + + h1 { + @include headlineLargeTypography; + } + + p { + @include bodyMediumTypography; + font-weight: 500; + color: var(--color-foreground-secondary); + } + } +} + .create-theme-button { @extend .button-secondary; padding: $s-6; From 2e23543c112caae6366e3a042b58feb8e8f5cc46 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 15:04:45 +0200 Subject: [PATCH 28/48] Show create text when no theme is available --- frontend/src/app/main/ui/workspace/tokens/sidebar.cljs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 1451d5e39..d2be88e40 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -182,12 +182,12 @@ "Create"]])) (mf/defc edit-button - [{:keys []}] + [{:keys [create?]}] [:button {:class (stl/css :themes-button) :on-click (fn [e] (dom/stop-propagation e) (modal/show! :tokens/themes {}))} - "Edit"]) + (if create? "Create" "Edit")]) (mf/defc themes-sidebar [_props] @@ -205,7 +205,7 @@ {:value id :label name}) xs)) themes)}] - [:& edit-button]]])) + [:& edit-button {:create? (empty? themes)}]]])) (mf/defc sets-sidebar [] From f25db592a07f974482bae7bc7a01c4b42b7ee58c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 15:07:58 +0200 Subject: [PATCH 29/48] Clone over select --- .../app/main/ui/workspace/tokens/sidebar.cljs | 4 +- .../ui/workspace/tokens/theme_select.cljs | 129 ++++++++++++++++++ .../ui/workspace/tokens/theme_select.scss | 129 ++++++++++++++++++ 3 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 frontend/src/app/main/ui/workspace/tokens/theme_select.cljs create mode 100644 frontend/src/app/main/ui/workspace/tokens/theme_select.scss diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index d2be88e40..3998e049d 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -9,9 +9,9 @@ (:require [app.common.data :as d] [app.main.data.modal :as modal] + [app.main.ui.workspace.tokens.theme-select :refer [theme-select]] [app.main.data.tokens :as dt] [app.main.data.tokens :as wdt] - [app.main.ui.components.select :refer [select]] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar]] @@ -197,7 +197,7 @@ [:div {:class (stl/css :theme-sidebar)} [:span {:class (stl/css :themes-header)} "Themes"] [:div {:class (stl/css :theme-select-wrapper)} - [:& select + [:& theme-select {:default-value (some-> active-theme-ids first) :class (stl/css :select-format-wrapper) :options (mapcat (fn [[_ xs]] diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs new file mode 100644 index 000000000..f8ac1f403 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -0,0 +1,129 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.ui.workspace.tokens.theme-select + (:require-macros [app.main.style :as stl]) + (:require + [app.common.data :as d] + [app.common.data.macros :as dm] + [app.common.uuid :as uuid] + [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.icons :as i] + [app.util.dom :as dom] + [rumext.v2 :as mf])) + + +(defn- as-key-value + [item] + (if (map? item) + [(:value item) (:label item) (:icon item)] + [item item item])) + +(mf/defc theme-select + [{:keys [default-value options class dropdown-class is-open? on-change on-pointer-enter-option on-pointer-leave-option disabled]}] + (let [label-index (mf/with-memo [options] + (into {} (map as-key-value) options)) + + state* (mf/use-state + {:id (uuid/next) + :is-open? (or is-open? false) + :current-value default-value}) + + state (deref state*) + current-id (get state :id) + current-value (get state :current-value) + current-label (get label-index current-value) + is-open? (:is-open? state) + + dropdown-element* (mf/use-ref nil) + dropdown-direction* (mf/use-state "down") + dropdown-direction-change* (mf/use-ref 0) + + open-dropdown + (mf/use-fn + (mf/deps disabled) + (fn [] + (when-not disabled + (swap! state* assoc :is-open? true)))) + + close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false)) + + select-item + (mf/use-fn + (mf/deps on-change) + (fn [event] + (let [value (-> (dom/get-current-target event) + (dom/get-data "value") + (d/read-string))] + + (swap! state* assoc :current-value value) + (when (fn? on-change) + (on-change value))))) + + highlight-item + (mf/use-fn + (mf/deps on-pointer-enter-option) + (fn [event] + (when (fn? on-pointer-enter-option) + (let [value (-> (dom/get-current-target event) + (dom/get-data "value") + (d/read-string))] + (on-pointer-enter-option value))))) + + unhighlight-item + (mf/use-fn + (mf/deps on-pointer-leave-option) + (fn [event] + (when (fn? on-pointer-leave-option) + (let [value (-> (dom/get-current-target event) + (dom/get-data "value") + (d/read-string))] + (on-pointer-leave-option value)))))] + + (mf/with-effect [default-value] + (swap! state* assoc :current-value default-value)) + + (mf/with-effect [is-open? dropdown-element*] + (let [dropdown-element (mf/ref-val dropdown-element*)] + (when (and (= 0 (mf/ref-val dropdown-direction-change*)) dropdown-element) + (let [is-outside? (dom/is-element-outside? dropdown-element)] + (reset! dropdown-direction* (if is-outside? "up" "down")) + (mf/set-ref-val! dropdown-direction-change* (inc (mf/ref-val dropdown-direction-change*))))))) + + (let [selected-option (first (filter #(= (:value %) default-value) options)) + current-icon (:icon selected-option) + current-icon-ref (i/key->icon current-icon)] + [:div {:on-click open-dropdown + :class (dm/str (stl/css-case :custom-select true + :disabled disabled + :icon (some? current-icon-ref)) + " " class)} + (when (and current-icon current-icon-ref) + [:span {:class (stl/css :current-icon)} current-icon-ref]) + [:span {:class (stl/css :current-label)} current-label] + [:span {:class (stl/css :dropdown-button)} i/arrow] + [:& dropdown {:show is-open? :on-close close-dropdown} + [:ul {:ref dropdown-element* :data-direction @dropdown-direction* + :class (dm/str dropdown-class " " (stl/css :custom-select-dropdown))} + (for [[index item] (d/enumerate options)] + (if (= :separator item) + [:li {:class (dom/classnames (stl/css :separator) true) + :key (dm/str current-id "-" index)}] + (let [[value label icon] (as-key-value item) + icon-ref (i/key->icon icon)] + [:li + {:key (dm/str current-id "-" index) + :class (stl/css-case + :checked-element true + :disabled (:disabled item) + :is-selected (= value current-value)) + :data-value (pr-str value) + :on-pointer-enter highlight-item + :on-pointer-leave unhighlight-item + :on-click select-item} + (when (and icon icon-ref) [:span {:class (stl/css :icon)} icon-ref]) + [:span {:class (stl/css :label)} label] + [:span {:class (stl/css :check-icon)} i/tick]])))]]]))) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss new file mode 100644 index 000000000..68af4ae36 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss @@ -0,0 +1,129 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@import "refactor/common-refactor.scss"; + +.custom-select { + --border-color: var(--menu-background-color); + --bg-color: var(--menu-background-color); + --icon-color: var(--icon-foreground); + --text-color: var(--menu-foreground-color); + @extend .new-scrollbar; + @include bodySmallTypography; + position: relative; + display: grid; + grid-template-columns: 1fr auto; + align-items: center; + height: $s-32; + width: 100%; + margin: 0; + padding: $s-8; + border-radius: $br-8; + background-color: var(--bg-color); + border: $s-1 solid var(--border-color); + color: var(--text-color); + cursor: pointer; + + &.icon { + grid-template-columns: auto 1fr auto; + } + + &:hover { + --bg-color: var(--menu-background-color-hover); + --border-color: var(--menu-background-color); + --icon-color: var(--menu-foreground-color-hover); + } + + &:focus { + --bg-color: var(--menu-background-color-focus); + --border-color: var(--menu-background-focus); + } +} + +.disabled { + --bg-color: var(--menu-background-color-disabled); + --border-color: var(--menu-border-color-disabled); + --icon-color: var(--menu-foreground-color-disabled); + --text-color: var(--menu-foreground-color-disabled); + pointer-events: none; + cursor: default; +} + +.dropdown-button { + @include flexCenter; + svg { + @extend .button-icon-small; + transform: rotate(90deg); + stroke: var(--icon-color); + } +} + +.current-icon { + @include flexCenter; + width: $s-24; + padding-right: $s-4; + svg { + @extend .button-icon-small; + stroke: var(--icon-foreground); + } +} + +.custom-select-dropdown { + @extend .dropdown-wrapper; + .separator { + margin: 0; + height: $s-12; + border-block-start: $s-1 solid var(--dropdown-separator-color); + } +} + +.custom-select-dropdown[data-direction="up"] { + bottom: $s-32; + top: auto; +} + +.checked-element { + @extend .dropdown-element-base; + .icon { + @include flexCenter; + height: $s-24; + width: $s-24; + padding-right: $s-4; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } + } + + .label { + flex-grow: 1; + width: 100%; + } + + .check-icon { + @include flexCenter; + svg { + @extend .button-icon-small; + visibility: hidden; + stroke: var(--icon-foreground); + } + } + + &.is-selected { + color: var(--menu-foreground-color); + .check-icon svg { + stroke: var(--menu-foreground-color); + visibility: visible; + } + } + &.disabled { + display: none; + } +} + +.current-label { + @include textEllipsis; +} From c807baaf7a8ac757bd9cbca3052bb1866842a31c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 15:54:44 +0200 Subject: [PATCH 30/48] Add custom select with grouped options --- frontend/src/app/main/refs.cljs | 3 + .../app/main/ui/workspace/tokens/sidebar.cljs | 15 +- .../ui/workspace/tokens/theme_select.cljs | 165 ++++++------------ .../ui/workspace/tokens/theme_select.scss | 15 ++ 4 files changed, 73 insertions(+), 125 deletions(-) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index dcf7381f1..349dc2967 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -247,6 +247,9 @@ (def workspace-active-theme-ids (l/derived wtts/get-active-theme-ids st/state)) +(def workspace-temp-theme-id + (l/derived wtts/get-temp-theme-id st/state)) + (def workspace-active-set-ids (l/derived wtts/get-active-set-ids st/state)) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 3998e049d..9c1e536dd 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -191,21 +191,12 @@ (mf/defc themes-sidebar [_props] - (let [open? (mf/use-state true) - active-theme-ids (mf/deref refs/workspace-active-theme-ids) - themes (mf/deref refs/workspace-ordered-token-themes)] + (let [ordered-themes (mf/deref refs/workspace-ordered-token-themes)] [:div {:class (stl/css :theme-sidebar)} [:span {:class (stl/css :themes-header)} "Themes"] [:div {:class (stl/css :theme-select-wrapper)} - [:& theme-select - {:default-value (some-> active-theme-ids first) - :class (stl/css :select-format-wrapper) - :options (mapcat (fn [[_ xs]] - (map (fn [{:keys [id name] :as f}] - {:value id :label name}) - xs)) - themes)}] - [:& edit-button {:create? (empty? themes)}]]])) + [:& theme-select] + [:& edit-button {:create? (empty? ordered-themes)}]]])) (mf/defc sets-sidebar [] diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index f8ac1f403..8977dabc1 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -7,123 +7,62 @@ (ns app.main.ui.workspace.tokens.theme-select (:require-macros [app.main.style :as stl]) (:require - [app.common.data :as d] - [app.common.data.macros :as dm] [app.common.uuid :as uuid] + [app.main.refs :as refs] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.icons :as i] - [app.util.dom :as dom] [rumext.v2 :as mf])) - -(defn- as-key-value - [item] - (if (map? item) - [(:value item) (:label item) (:icon item)] - [item item item])) - -(mf/defc theme-select - [{:keys [default-value options class dropdown-class is-open? on-change on-pointer-enter-option on-pointer-leave-option disabled]}] - (let [label-index (mf/with-memo [options] - (into {} (map as-key-value) options)) - - state* (mf/use-state - {:id (uuid/next) - :is-open? (or is-open? false) - :current-value default-value}) - - state (deref state*) - current-id (get state :id) - current-value (get state :current-value) - current-label (get label-index current-value) - is-open? (:is-open? state) - - dropdown-element* (mf/use-ref nil) - dropdown-direction* (mf/use-state "down") - dropdown-direction-change* (mf/use-ref 0) - - open-dropdown - (mf/use-fn - (mf/deps disabled) - (fn [] - (when-not disabled - (swap! state* assoc :is-open? true)))) - - close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false)) - - select-item - (mf/use-fn - (mf/deps on-change) - (fn [event] - (let [value (-> (dom/get-current-target event) - (dom/get-data "value") - (d/read-string))] - - (swap! state* assoc :current-value value) - (when (fn? on-change) - (on-change value))))) - - highlight-item - (mf/use-fn - (mf/deps on-pointer-enter-option) - (fn [event] - (when (fn? on-pointer-enter-option) - (let [value (-> (dom/get-current-target event) - (dom/get-data "value") - (d/read-string))] - (on-pointer-enter-option value))))) - - unhighlight-item - (mf/use-fn - (mf/deps on-pointer-leave-option) - (fn [event] - (when (fn? on-pointer-leave-option) - (let [value (-> (dom/get-current-target event) - (dom/get-data "value") - (d/read-string))] - (on-pointer-leave-option value)))))] - - (mf/with-effect [default-value] - (swap! state* assoc :current-value default-value)) - - (mf/with-effect [is-open? dropdown-element*] - (let [dropdown-element (mf/ref-val dropdown-element*)] - (when (and (= 0 (mf/ref-val dropdown-direction-change*)) dropdown-element) - (let [is-outside? (dom/is-element-outside? dropdown-element)] - (reset! dropdown-direction* (if is-outside? "up" "down")) - (mf/set-ref-val! dropdown-direction-change* (inc (mf/ref-val dropdown-direction-change*))))))) - - (let [selected-option (first (filter #(= (:value %) default-value) options)) - current-icon (:icon selected-option) - current-icon-ref (i/key->icon current-icon)] - [:div {:on-click open-dropdown - :class (dm/str (stl/css-case :custom-select true - :disabled disabled - :icon (some? current-icon-ref)) - " " class)} - (when (and current-icon current-icon-ref) - [:span {:class (stl/css :current-icon)} current-icon-ref]) - [:span {:class (stl/css :current-label)} current-label] - [:span {:class (stl/css :dropdown-button)} i/arrow] - [:& dropdown {:show is-open? :on-close close-dropdown} - [:ul {:ref dropdown-element* :data-direction @dropdown-direction* - :class (dm/str dropdown-class " " (stl/css :custom-select-dropdown))} - (for [[index item] (d/enumerate options)] - (if (= :separator item) - [:li {:class (dom/classnames (stl/css :separator) true) - :key (dm/str current-id "-" index)}] - (let [[value label icon] (as-key-value item) - icon-ref (i/key->icon icon)] - [:li - {:key (dm/str current-id "-" index) +(mf/defc theme-options + [{:keys []}] + (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) + ordered-themes (mf/deref refs/workspace-ordered-token-themes)] + [:ul + (for [[group themes] ordered-themes] + [:li {:key group} + (when group + [:span {:class (stl/css :group)} group]) + [:ul + (for [{:keys [id name]} themes + :let [selected? (get active-theme-ids id)]] + [:li {:key id :class (stl/css-case :checked-element true - :disabled (:disabled item) - :is-selected (= value current-value)) - :data-value (pr-str value) - :on-pointer-enter highlight-item - :on-pointer-leave unhighlight-item - :on-click select-item} - (when (and icon icon-ref) [:span {:class (stl/css :icon)} icon-ref]) - [:span {:class (stl/css :label)} label] - [:span {:class (stl/css :check-icon)} i/tick]])))]]]))) + :is-selected selected?)} + [:span {:class (stl/css :label)} name] + [:span {:class (stl/css :check-icon)} i/tick]])]])])) + +(mf/defc theme-select + [{:keys []}] + (let [;; Store + temp-theme-id (mf/deref refs/workspace-temp-theme-id) + active-theme-ids (-> (mf/deref refs/workspace-active-theme-ids) + (disj temp-theme-id)) + active-themes-count (count active-theme-ids) + themes (mf/deref refs/workspace-token-themes) + + ;; Data + current-label (cond + (> active-themes-count 1) (str active-themes-count " themes active") + (pos? active-themes-count) (get-in themes [(first active-theme-ids) :name]) + :else "No theme active") + + ;; State + state* (mf/use-state + {:id (uuid/next) + :is-open? false}) + state (deref state*) + is-open? (:is-open? state) + + ;; Dropdown + dropdown-element* (mf/use-ref nil) + on-close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false)) + on-open-dropdown (mf/use-fn #(swap! state* assoc :is-open? true))] + [:div {:on-click on-open-dropdown + :class (stl/css :custom-select)} + [:span {:class (stl/css :current-label)} current-label] + [:span {:class (stl/css :dropdown-button)} i/arrow] + [:& dropdown {:show is-open? :on-close on-close-dropdown} + [:div {:ref dropdown-element* + :class (stl/css :custom-select-dropdown)} + [:& theme-options]]]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss index 68af4ae36..0c97b2721 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss @@ -27,6 +27,18 @@ color: var(--text-color); cursor: pointer; + ul { + margin-bottom: 0; + } + + .group { + display: block; + @include headlineSmallTypography; + padding: $s-8; + color: var(--color-foreground-secondary); + font-weight: 600; + } + &.icon { grid-template-columns: auto 1fr auto; } @@ -87,6 +99,9 @@ .checked-element { @extend .dropdown-element-base; + + padding-left: $s-16; + .icon { @include flexCenter; height: $s-24; From cb46e111622abfb09cf805d85dbb5f0223d5168c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 16:14:27 +0200 Subject: [PATCH 31/48] Add edit button --- .../ui/workspace/tokens/theme_select.cljs | 7 ++++- .../ui/workspace/tokens/theme_select.scss | 27 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index 8977dabc1..ff8ed5b7e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -28,9 +28,14 @@ [:li {:key id :class (stl/css-case :checked-element true + :sub-item true :is-selected selected?)} [:span {:class (stl/css :label)} name] - [:span {:class (stl/css :check-icon)} i/tick]])]])])) + [:span {:class (stl/css :check-icon)} i/tick]])]]) + [:li {:class (stl/css-case :checked-element true + :checked-element-button true)} + [:span "Edit themes"] + [:span {:class (stl/css :icon)} i/arrow]]])) (mf/defc theme-select [{:keys []}] diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss index 0c97b2721..da8a7b5a3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss @@ -97,11 +97,34 @@ top: auto; } +.sub-item { + padding-left: $s-16; +} + +.checked-element-button { + @extend .dropdown-element-base; + position: relative; + display: flex; + justify-content: space-between; + padding-right: 0; +} + +li + .checked-element-button { + margin-top: $s-8; + &:before { + content: ""; + position: absolute; + top: -$s-4; + left: 0; + right: 0; + height: 1px; + background-color: color-mix(in hsl, var(--color-foreground-secondary) 20%, transparent); + } +} + .checked-element { @extend .dropdown-element-base; - padding-left: $s-16; - .icon { @include flexCenter; height: $s-24; From 0d2d1a8b8a6609a8965c360e05b6d6f6ac93e86f Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 16:23:23 +0200 Subject: [PATCH 32/48] Link up actions --- .../main/ui/workspace/tokens/theme_select.cljs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index ff8ed5b7e..7b97f0588 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -8,13 +8,17 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.uuid :as uuid] + [app.main.data.modal :as modal] + [app.main.data.tokens :as wdt] [app.main.refs :as refs] + [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.icons :as i] + [app.util.dom :as dom] [rumext.v2 :as mf])) (mf/defc theme-options - [{:keys []}] + [{:keys [on-close]}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) ordered-themes (mf/deref refs/workspace-ordered-token-themes)] [:ul @@ -29,11 +33,16 @@ :class (stl/css-case :checked-element true :sub-item true - :is-selected selected?)} + :is-selected selected?) + :on-click (fn [e] + (dom/stop-propagation e) + (st/emit! (wdt/toggle-token-theme id)) + (on-close))} [:span {:class (stl/css :label)} name] [:span {:class (stl/css :check-icon)} i/tick]])]]) [:li {:class (stl/css-case :checked-element true - :checked-element-button true)} + :checked-element-button true) + :on-click #(modal/show! :tokens/themes {})} [:span "Edit themes"] [:span {:class (stl/css :icon)} i/arrow]]])) @@ -70,4 +79,4 @@ [:& dropdown {:show is-open? :on-close on-close-dropdown} [:div {:ref dropdown-element* :class (stl/css :custom-select-dropdown)} - [:& theme-options]]]])) + [:& theme-options {:on-close on-close-dropdown}]]]])) From 1d599cbf7d78d5706f4d97a7ef742fa9bc5e0154 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 16:33:07 +0200 Subject: [PATCH 33/48] Always render ungroupd themes first --- .../ui/workspace/tokens/theme_select.cljs | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index 7b97f0588..f297538be 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -17,29 +17,42 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) +(mf/defc list-items + [{:keys [themes active-theme-ids on-close grouped?]}] + (when (seq themes) + [:ul + (for [{:keys [id name]} themes + :let [selected? (get active-theme-ids id)]] + [:li {:key id + :class (stl/css-case + :checked-element true + :sub-item grouped? + :is-selected selected?) + :on-click (fn [e] + (dom/stop-propagation e) + (st/emit! (wdt/toggle-token-theme id)) + (on-close))} + [:span {:class (stl/css :label)} name] + [:span {:class (stl/css :check-icon)} i/tick]])])) + (mf/defc theme-options [{:keys [on-close]}] (let [active-theme-ids (mf/deref refs/workspace-active-theme-ids) - ordered-themes (mf/deref refs/workspace-ordered-token-themes)] + ordered-themes (mf/deref refs/workspace-ordered-token-themes) + grouped-themes (dissoc ordered-themes nil) + ungrouped-themes (get ordered-themes nil)] [:ul - (for [[group themes] ordered-themes] + [:& list-items {:themes ungrouped-themes + :active-theme-ids active-theme-ids + :on-close on-close}] + (for [[group themes] grouped-themes] [:li {:key group} (when group [:span {:class (stl/css :group)} group]) - [:ul - (for [{:keys [id name]} themes - :let [selected? (get active-theme-ids id)]] - [:li {:key id - :class (stl/css-case - :checked-element true - :sub-item true - :is-selected selected?) - :on-click (fn [e] - (dom/stop-propagation e) - (st/emit! (wdt/toggle-token-theme id)) - (on-close))} - [:span {:class (stl/css :label)} name] - [:span {:class (stl/css :check-icon)} i/tick]])]]) + [:& list-items {:themes themes + :active-theme-ids active-theme-ids + :on-close on-close + :grouped? true}]]) [:li {:class (stl/css-case :checked-element true :checked-element-button true) :on-click #(modal/show! :tokens/themes {})} From 293250a30d86a67415d2d3b133cd296a1edc3aff Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 26 Aug 2024 16:35:49 +0200 Subject: [PATCH 34/48] Rename --- .../main/ui/workspace/tokens/theme_select.cljs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index f297538be..0f0cc2a4e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -17,7 +17,7 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) -(mf/defc list-items +(mf/defc themes-list [{:keys [themes active-theme-ids on-close grouped?]}] (when (seq themes) [:ul @@ -42,17 +42,17 @@ grouped-themes (dissoc ordered-themes nil) ungrouped-themes (get ordered-themes nil)] [:ul - [:& list-items {:themes ungrouped-themes - :active-theme-ids active-theme-ids - :on-close on-close}] + [:& themes-list {:themes ungrouped-themes + :active-theme-ids active-theme-ids + :on-close on-close}] (for [[group themes] grouped-themes] [:li {:key group} (when group [:span {:class (stl/css :group)} group]) - [:& list-items {:themes themes - :active-theme-ids active-theme-ids - :on-close on-close - :grouped? true}]]) + [:& themes-list {:themes themes + :active-theme-ids active-theme-ids + :on-close on-close + :grouped? true}]]) [:li {:class (stl/css-case :checked-element true :checked-element-button true) :on-click #(modal/show! :tokens/themes {})} From 965016b63f405dd82bd79a2ae9f1cbf906e4fcd6 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 10:04:12 +0200 Subject: [PATCH 35/48] Allow token renaming --- frontend/src/app/main/data/tokens.cljs | 10 ++ .../app/main/ui/workspace/tokens/sets.cljs | 117 +++++++++++++----- .../app/main/ui/workspace/tokens/sets.scss | 18 +++ 3 files changed, 115 insertions(+), 30 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 645542331..b333a5827 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -168,6 +168,16 @@ (rx/of (dch/commit-changes changes))))))) +(defn update-token-set [token-set] + (ptk/reify ::update-token-set + ptk/WatchEvent + (watch [it state _] + (let [prev-token-set (wtts/get-token-set (:id token-set) state) + changes (-> (pcb/empty-changes it) + (pcb/update-token-set token-set prev-token-set))] + (rx/of + (dch/commit-changes changes)))))) + (defn toggle-token-set [{:keys [token-set-id token-theme-id]}] (ptk/reify ::toggle-token-set ptk/WatchEvent diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 0e29b8a2d..4c671b307 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -12,6 +12,8 @@ [app.main.store :as st] [app.main.ui.icons :as i] [app.util.dom :as dom] + [app.util.keyboard :as kbd] + [cuerdas.core :as str] [rumext.v2 :as mf])) (def ^:private chevron-icon @@ -27,18 +29,57 @@ (dom/stop-propagation event) (st/emit! (wdt/delete-token-set id))) +(defn on-rename-token-set [name token-set] + (let [new-token-set (assoc token-set :name name)] + (st/emit! (wdt/update-token-set new-token-set)))) + +(mf/defc editing-node + [{:keys [default-value on-cancel on-submit]}] + (let [ref (mf/use-ref) + on-submit-valid (mf/use-fn + (fn [event] + (let [value (str/trim (dom/get-target-val event))] + (if (or (str/empty? value) + (= value default-value)) + (on-cancel) + (on-submit value))))) + on-key-down (mf/use-fn + (fn [event] + (cond + (kbd/enter? event) (on-submit-valid event) + (kbd/esc? event) (on-cancel))))] + [:input + {:class (stl/css :editing-node) + :type "text" + :ref ref + :on-blur on-submit-valid + :on-key-down on-key-down + :auto-focus true + :default-value default-value}])) + (mf/defc sets-tree - [{:keys [token-set token-set-active? token-set-selected? on-select on-toggle] :as _props}] + [{:keys [token-set token-set-active? token-set-selected? on-select on-toggle editing? set-editing-node on-rename] :as _props}] (let [{:keys [id name _children]} token-set selected? (and set? (token-set-selected? id)) visible? (token-set-active? id) collapsed? (mf/use-state false) set? true #_(= type :set) - group? false #_(= type :group)] + group? false #_(= type :group) + editing-node? (editing? id) + on-select (mf/use-callback + (mf/deps editing-node?) + (fn [event] + (dom/stop-propagation event) + (when-not editing-node? + (on-select id)))) + on-edit (mf/use-callback + (mf/deps editing-node?) + (fn [event] + (dom/stop-propagation event) + (set-editing-node id)))] [:div {:class (stl/css :set-item-container) - :on-click (fn [event] - (dom/stop-propagation event) - (on-select id))} + :on-click on-select + :on-double-click on-edit} [:div {:class (stl/css-case :set-item-group group? :set-item-set set? :selected-set selected?)} @@ -49,33 +90,48 @@ chevron-icon]) [:span {:class (stl/css :icon)} (if set? i/document i/group)] - [:div {:class (stl/css :set-name)} name] - [:div {:class (stl/css :delete-set)} - [:button {:on-click #(on-delete-token-set-click id %) - :type "button"} - i/delete]] - (when set? - [:span {:class (stl/css :action-btn) - :on-click (fn [event] - (dom/stop-propagation event) - (on-toggle id))} - (if visible? i/shown i/hide)])] - #_(when (and children (not @collapsed?)) - [:div {:class (stl/css :set-children)} - (for [child-id children] - [:& sets-tree (assoc props :key child-id - {:key child-id} - :set-id child-id - :selected-set-id selected-token-set-id)])])])) + (if editing-node? + [:& editing-node {:default-value name + :on-submit #(do + (on-rename % token-set) + (set-editing-node nil)) + :on-cancel #(set-editing-node nil)}] + [:* + [:div {:class (stl/css :set-name)} name] + [:div {:class (stl/css :delete-set)} + [:button {:on-click #(on-delete-token-set-click id %) + :type "button"} + i/delete]] + (if set? + [:span {:class (stl/css :action-btn) + :on-click (fn [event] + (dom/stop-propagation event) + (on-toggle id))} + (if visible? i/shown i/hide)] + nil + #_(when (and children (not @collapsed?)) + [:div {:class (stl/css :set-children)} + (for [child-id children] + [:& sets-tree (assoc props :key child-id + {:key child-id} + :set-id child-id + :selected-set-id selected-token-set-id)])]))])]])) (mf/defc controlled-sets-list [{:keys [token-sets] :as props}] - [:ul {:class (stl/css :sets-list)} - (for [[id token-set] token-sets] - [:& sets-tree (-> (assoc props - :key id - :token-set token-set) - (dissoc :token-sets))])]) + (let [editing-id (mf/use-state nil) + editing? (mf/use-callback + (mf/deps editing-id) + #(= @editing-id %)) + set-editing-node #(reset! editing-id %)] + [:ul {:class (stl/css :sets-list)} + (for [[id token-set] token-sets] + [:& sets-tree (-> (assoc props + :key id + :token-set token-set + :editing? editing? + :set-editing-node set-editing-node) + (dissoc :token-sets))])])) (mf/defc sets-list [{:keys []}] @@ -96,4 +152,5 @@ :token-set-selected? token-set-selected? :token-set-active? token-set-active? :on-select on-select-token-set-click - :on-toggle on-toggle-token-set-click}])) + :on-toggle on-toggle-token-set-click + :on-rename on-rename-token-set}])) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.scss b/frontend/src/app/main/ui/workspace/tokens/sets.scss index a2049236e..c65fdd2c3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sets.scss @@ -126,3 +126,21 @@ transform: rotate(var(--chevron-icon-rotation)); stroke: var(--icon-foreground); } + +.editing-node { + @include textEllipsis; + color: var(--layer-row-foreground-color-focus); +} + +input.editing-node { + @include textEllipsis; + @include bodySmallTypography; + @include removeInputStyle; + flex-grow: 1; + height: $s-28; + padding-left: $s-6; + margin: 0; + border-radius: $br-8; + border: $s-1 solid var(--input-border-color-focus); + color: var(--layer-row-foreground-color); +} From db22beb857bdf1b3edced74828815bea6ec52d2f Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 10:20:38 +0200 Subject: [PATCH 36/48] Fix iterating over unordered sets --- frontend/src/app/main/refs.cljs | 4 ++-- .../src/app/main/ui/workspace/tokens/modals/themes.cljs | 4 ++-- frontend/src/app/main/ui/workspace/tokens/sets.cljs | 2 +- frontend/src/app/main/ui/workspace/tokens/token_set.cljs | 7 +++++++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 349dc2967..3c09ed541 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -259,10 +259,10 @@ (def workspace-ordered-token-themes (l/derived wtts/get-workspace-ordered-themes st/state)) -(def workspace-token-sets +(def workspace-ordered-token-sets (l/derived (fn [data] - (or (wtts/get-workspace-sets data) {})) + (or (wtts/get-workspace-ordered-sets data) {})) st/state =)) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 7148c7052..f4cb4da8c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -182,7 +182,7 @@ (mf/defc controlled-edit-theme [{:keys [state set-state]}] (let [{:keys [theme-id]} @state - token-sets (mf/deref refs/workspace-token-sets) + token-sets (mf/deref refs/workspace-ordered-token-sets) theme (mf/deref (refs/workspace-token-theme theme-id))] [:& edit-theme {:token-sets token-sets @@ -192,7 +192,7 @@ (mf/defc create-theme [{:keys [set-state]}] - (let [token-sets (mf/deref refs/workspace-token-sets) + (let [token-sets (mf/deref refs/workspace-ordered-token-sets) theme {:name "Theme" :sets #{}}] [:& edit-theme {:token-sets token-sets diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 4c671b307..31a7e90db 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -135,7 +135,7 @@ (mf/defc sets-list [{:keys []}] - (let [token-sets (mf/deref refs/workspace-token-sets) + (let [token-sets (mf/deref refs/workspace-ordered-token-sets) selected-token-set-id (mf/deref refs/workspace-selected-token-set-id) token-set-selected? (mf/use-callback (mf/deps selected-token-set-id) diff --git a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs index 488c85bf4..dab231665 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs @@ -115,6 +115,13 @@ (defn get-workspace-sets [state] (get-in state [:workspace-data :token-sets-index])) +(defn get-workspace-ordered-sets [state] + ;; TODO Include groups + (let [top-level-set-ids (get-in state [:workspace-data :token-set-groups]) + token-sets (get-workspace-sets state)] + (->> (map (fn [id] [id (get token-sets id)]) top-level-set-ids) + (into (ordered-map))))) + (defn get-token-set [set-id state] (some-> (get-workspace-sets state) (get set-id))) From 4f96550bca264fa4a06441d3993407a079db4340 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:13:29 +0200 Subject: [PATCH 37/48] Use context --- frontend/src/app/main/ui/context.cljs | 2 + .../app/main/ui/workspace/tokens/sets.cljs | 52 ++++++++++--------- .../ui/workspace/tokens/sets_context.cljs | 34 ++++++++++++ .../app/main/ui/workspace/tokens/sidebar.cljs | 41 +++++++++------ 4 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 frontend/src/app/main/ui/workspace/tokens/sets_context.cljs diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index 1aa4b532b..009366257 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -31,3 +31,5 @@ (def workspace-read-only? (mf/create-context nil)) (def is-component? (mf/create-context false)) (def sidebar (mf/create-context nil)) + +(def token-sets (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 31a7e90db..463a6f72f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -14,7 +14,8 @@ [app.util.dom :as dom] [app.util.keyboard :as kbd] [cuerdas.core :as str] - [rumext.v2 :as mf])) + [rumext.v2 :as mf] + [app.main.ui.workspace.tokens.sets-context :as sets-context])) (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) @@ -29,9 +30,8 @@ (dom/stop-propagation event) (st/emit! (wdt/delete-token-set id))) -(defn on-rename-token-set [name token-set] - (let [new-token-set (assoc token-set :name name)] - (st/emit! (wdt/update-token-set new-token-set)))) +(defn on-update-token-set [token-set] + (st/emit! (wdt/update-token-set token-set))) (mf/defc editing-node [{:keys [default-value on-cancel on-submit]}] @@ -58,7 +58,7 @@ :default-value default-value}])) (mf/defc sets-tree - [{:keys [token-set token-set-active? token-set-selected? on-select on-toggle editing? set-editing-node on-rename] :as _props}] + [{:keys [token-set token-set-active? token-set-selected? editing? on-select on-toggle on-edit on-submit on-cancel] :as _props}] (let [{:keys [id name _children]} token-set selected? (and set? (token-set-selected? id)) visible? (token-set-active? id) @@ -71,15 +71,10 @@ (fn [event] (dom/stop-propagation event) (when-not editing-node? - (on-select id)))) - on-edit (mf/use-callback - (mf/deps editing-node?) - (fn [event] - (dom/stop-propagation event) - (set-editing-node id)))] + (on-select id))))] [:div {:class (stl/css :set-item-container) :on-click on-select - :on-double-click on-edit} + :on-double-click #(on-edit id)} [:div {:class (stl/css-case :set-item-group group? :set-item-set set? :selected-set selected?)} @@ -92,10 +87,8 @@ (if set? i/document i/group)] (if editing-node? [:& editing-node {:default-value name - :on-submit #(do - (on-rename % token-set) - (set-editing-node nil)) - :on-cancel #(set-editing-node nil)}] + :on-submit #(on-submit (assoc token-set :name %)) + :on-cancel on-cancel}] [:* [:div {:class (stl/css :set-name)} name] [:div {:class (stl/css :delete-set)} @@ -118,20 +111,29 @@ :selected-set-id selected-token-set-id)])]))])]])) (mf/defc controlled-sets-list - [{:keys [token-sets] :as props}] - (let [editing-id (mf/use-state nil) - editing? (mf/use-callback - (mf/deps editing-id) - #(= @editing-id %)) - set-editing-node #(reset! editing-id %)] + [{:keys [token-sets on-rename] :as props}] + (let [{:keys [editing? new? on-edit on-reset]} (sets-context/use-context)] [:ul {:class (stl/css :sets-list)} (for [[id token-set] token-sets] [:& sets-tree (-> (assoc props :key id :token-set token-set :editing? editing? - :set-editing-node set-editing-node) - (dissoc :token-sets))])])) + :set-editing-node on-edit + :on-edit on-edit + :on-submit #(do + (on-rename %) + (on-reset)) + :on-cancel on-reset) + (dissoc :token-sets))]) + (when new? + [:& sets-tree {:token-set {} + :token-set-active? (constantly true) + :token-set-selected? (constantly true) + :on-select identity + :editing? (constantly true) + :set-editing-node on-edit}])])) + (mf/defc sets-list [{:keys []}] @@ -153,4 +155,4 @@ :token-set-active? token-set-active? :on-select on-select-token-set-click :on-toggle on-toggle-token-set-click - :on-rename on-rename-token-set}])) + :on-rename on-update-token-set}])) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs b/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs new file mode 100644 index 000000000..0d08ab297 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs @@ -0,0 +1,34 @@ +(ns app.main.ui.workspace.tokens.sets-context + (:require + [rumext.v2 :as mf])) + +(def initial {:editing-id nil + :new? false}) + +(def context (mf/create-context initial)) + +(mf/defc provider + {::mf/wrap-props false} + [props] + (let [children (unchecked-get props "children") + state (mf/use-state initial)] + [:& (mf/provider context) {:value state} + children])) + +(defn use-context [] + (let [ctx (mf/use-ctx context) + {:keys [editing-id new?]} @ctx + editing? (mf/use-callback + (mf/deps editing-id) + #(= editing-id %)) + on-edit (mf/use-fn + #(swap! ctx assoc :editing-id %)) + on-create (mf/use-fn + #(swap! ctx assoc :editing-id (random-uuid) :new? true)) + on-reset (mf/use-fn + #(reset! ctx initial))] + {:editing? editing? + :new? new? + :on-edit on-edit + :on-create on-create + :on-reset on-reset})) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 9c1e536dd..b26a69956 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -9,12 +9,12 @@ (:require [app.common.data :as d] [app.main.data.modal :as modal] - [app.main.ui.workspace.tokens.theme-select :refer [theme-select]] [app.main.data.tokens :as dt] [app.main.data.tokens :as wdt] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar]] + [app.main.ui.context :as muc] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.tokens.changes :as wtch] @@ -22,7 +22,9 @@ [app.main.ui.workspace.tokens.context-menu :refer [token-context-menu]] [app.main.ui.workspace.tokens.core :as wtc] [app.main.ui.workspace.tokens.sets :refer [sets-list]] + [app.main.ui.workspace.tokens.sets-context :as sets-context] [app.main.ui.workspace.tokens.style-dictionary :as sd] + [app.main.ui.workspace.tokens.theme-select :refer [theme-select]] [app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token-types :as wtty] [app.util.dom :as dom] @@ -198,23 +200,30 @@ [:& theme-select] [:& edit-button {:create? (empty? ordered-themes)}]]])) +(mf/defc add-set-button + [{:keys [on-open]}] + (let [{:keys [on-create]} (sets-context/use-context)] + [:button {:class (stl/css :add-set) + :on-click #(do + (on-open) + (on-create))} + i/add])) + (mf/defc sets-sidebar [] - (let [open? (mf/use-state true)] - [:div {:class (stl/css :sets-sidebar)} - [:div {:class (stl/css :sidebar-header)} - [:& title-bar {:collapsable true - :collapsed (not @open?) - :all-clickable true - :title "SETS" - :on-collapsed #(swap! open? not)}] - [:button {:class (stl/css :add-set) - :on-click #(do - (reset! open? true) - (on-set-add-click %))} - i/add]] - (when @open? - [:& sets-list])])) + (let [open? (mf/use-state true) + on-open (mf/use-fn #(reset! open? true))] + [:& sets-context/provider {} + [:div {:class (stl/css :sets-sidebar)} + [:div {:class (stl/css :sidebar-header)} + [:& title-bar {:collapsable true + :collapsed (not @open?) + :all-clickable true + :title "SETS" + :on-collapsed #(swap! open? not)} + [:& add-set-button {:on-open on-open}]]] + (when @open? + [:& sets-list])]])) (mf/defc tokens-explorer [_props] From d4910ce2fc56d5dd5c4f730c8b20ff9a2ddcc221 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:25:52 +0200 Subject: [PATCH 38/48] Auto select new token sets --- frontend/src/app/main/data/tokens.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index b333a5827..39297ba1c 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -166,6 +166,7 @@ (ensure-token-theme-changes state {:id (:id new-token-set) :new-set? true}))] (rx/of + (set-selected-token-set-id (:id new-token-set)) (dch/commit-changes changes))))))) (defn update-token-set [token-set] From 4dd3367bdda6ff509a25e01c0297bdc4c26503fd Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:26:06 +0200 Subject: [PATCH 39/48] Allow creating token sets --- .../app/main/ui/workspace/tokens/sets.cljs | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 463a6f72f..9f9c6daa9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -33,6 +33,9 @@ (defn on-update-token-set [token-set] (st/emit! (wdt/update-token-set token-set))) +(defn on-create-token-set [token-set] + (st/emit! (wdt/create-token-set token-set))) + (mf/defc editing-node [{:keys [default-value on-cancel on-submit]}] (let [ref (mf/use-ref) @@ -58,7 +61,16 @@ :default-value default-value}])) (mf/defc sets-tree - [{:keys [token-set token-set-active? token-set-selected? editing? on-select on-toggle on-edit on-submit on-cancel] :as _props}] + [{:keys [token-set + token-set-active? + token-set-selected? + editing? + on-select + on-toggle + on-edit + on-submit + on-cancel] + :as _props}] (let [{:keys [id name _children]} token-set selected? (and set? (token-set-selected? id)) visible? (token-set-active? id) @@ -111,29 +123,38 @@ :selected-set-id selected-token-set-id)])]))])]])) (mf/defc controlled-sets-list - [{:keys [token-sets on-rename] :as props}] - (let [{:keys [editing? new? on-edit on-reset]} (sets-context/use-context)] + [{:keys [token-sets + on-update-token-set + token-set-selected? + token-set-active? + on-create-token-set + on-select] + :as _props}] + (let [{:keys [editing? new? on-edit on-create on-reset]} (sets-context/use-context)] [:ul {:class (stl/css :sets-list)} (for [[id token-set] token-sets] - [:& sets-tree (-> (assoc props - :key id - :token-set token-set - :editing? editing? - :set-editing-node on-edit - :on-edit on-edit - :on-submit #(do - (on-rename %) - (on-reset)) - :on-cancel on-reset) - (dissoc :token-sets))]) + [:& sets-tree {:key id + :token-set token-set + :token-set-selected? (if new? (constantly false) token-set-selected?) + :token-set-active? token-set-active? + :editing? editing? + :on-select on-select + :on-edit on-edit + :on-submit #(do + (on-update-token-set %) + (on-reset)) + :on-cancel on-reset}]) (when new? - [:& sets-tree {:token-set {} - :token-set-active? (constantly true) + [:& sets-tree {:token-set {:name ""} :token-set-selected? (constantly true) - :on-select identity + :token-set-active? (constantly true) :editing? (constantly true) - :set-editing-node on-edit}])])) - + :on-select (constantly nil) + :on-edit on-create + :on-submit #(do + (on-create-token-set %) + (on-reset)) + :on-cancel on-reset}])])) (mf/defc sets-list [{:keys []}] @@ -150,9 +171,9 @@ (get active-token-set-ids id)))] [:& controlled-sets-list {:token-sets token-sets - :selected-token-set-id selected-token-set-id :token-set-selected? token-set-selected? :token-set-active? token-set-active? :on-select on-select-token-set-click :on-toggle on-toggle-token-set-click - :on-rename on-update-token-set}])) + :on-update-token-set on-update-token-set + :on-create-token-set on-create-token-set}])) From 3b7432a859796d0a5421df3801e5eeca021567ef Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:32:26 +0200 Subject: [PATCH 40/48] Use non editable context in form --- .../src/app/main/ui/workspace/tokens/modals/themes.cljs | 6 ++++-- frontend/src/app/main/ui/workspace/tokens/sets.cljs | 5 +++-- .../src/app/main/ui/workspace/tokens/sets_context.cljs | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index f4cb4da8c..b72831efa 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -18,7 +18,8 @@ [app.main.ui.workspace.tokens.token-set :as wtts] [app.util.dom :as dom] [rumext.v2 :as mf] - [cuerdas.core :as str])) + [cuerdas.core :as str] + [app.main.ui.workspace.tokens.sets-context :as sets-context])) (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon))) @@ -159,7 +160,8 @@ :token-set-selected? (constantly false) :token-set-active? token-set-active? :on-select on-toggle-token-set - :on-toggle on-toggle-token-set}]] + :on-toggle on-toggle-token-set + :context sets-context/static-context}]] [:div {:class (stl/css :edit-theme-footer)} (if edit? [:button {:class (stl/css :button-secondary) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 9f9c6daa9..9f5603efb 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -128,9 +128,10 @@ token-set-selected? token-set-active? on-create-token-set - on-select] + on-select + context] :as _props}] - (let [{:keys [editing? new? on-edit on-create on-reset]} (sets-context/use-context)] + (let [{:keys [editing? new? on-edit on-create on-reset]} (or context (sets-context/use-context))] [:ul {:class (stl/css :sets-list)} (for [[id token-set] token-sets] [:& sets-tree {:key id diff --git a/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs b/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs index 0d08ab297..b5920f335 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets_context.cljs @@ -7,6 +7,13 @@ (def context (mf/create-context initial)) +(def static-context + {:editing? (constantly false) + :new? false + :on-edit (constantly nil) + :on-create (constantly nil) + :on-reset (constantly nil)}) + (mf/defc provider {::mf/wrap-props false} [props] From 3bb99e8f7cffb3f2a8bb5fca755ac0a5aca8d245 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:37:24 +0200 Subject: [PATCH 41/48] Remove default theme name, disable empty themen name submit --- .../main/ui/workspace/tokens/modals/themes.cljs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index b72831efa..c5dded93e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -112,6 +112,9 @@ (let [edit? (some? (:id theme)) theme-state (mf/use-state {:token-sets token-sets :theme theme}) + disabled? (-> (get-in @theme-state [:theme :name]) + (str/trim) + (str/empty?)) token-set-active? (mf/use-callback (mf/deps theme-state) (fn [id] @@ -135,10 +138,10 @@ final-group (-> (:group theme) (str/trim) (str/lower))] - (cond-> theme - (empty final-name) (assoc :name "Theme") - (empty final-group) (dissoc :group) - :always on-submit)) + (when-not (str/empty? final-name) + (cond-> theme + (empty final-group) (dissoc :group) + :always on-submit))) (on-back)))] [:form {:on-submit on-save-form} [:div {:class (stl/css :edit-theme-wrapper)} @@ -178,7 +181,8 @@ "Cancel"] [:button {:class (stl/css :button-primary) :type "submit" - :on-click on-save-form} + :on-click on-save-form + :disabled disabled?} "Save theme"]]]]])) (mf/defc controlled-edit-theme @@ -195,7 +199,7 @@ (mf/defc create-theme [{:keys [set-state]}] (let [token-sets (mf/deref refs/workspace-ordered-token-sets) - theme {:name "Theme" :sets #{}}] + theme {:name "" :sets #{}}] [:& edit-theme {:token-sets token-sets :theme theme From d6823e8583100f744a0ac660818f608395e7e526 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 14:49:11 +0200 Subject: [PATCH 42/48] Always switch to temporary theme when toggling sets in sidebar --- frontend/src/app/main/data/tokens.cljs | 11 ++++++----- .../app/main/ui/workspace/tokens/modals/themes.cljs | 2 +- frontend/src/app/main/ui/workspace/tokens/sets.cljs | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 39297ba1c..e13527db0 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -179,18 +179,19 @@ (rx/of (dch/commit-changes changes)))))) -(defn toggle-token-set [{:keys [token-set-id token-theme-id]}] +(defn toggle-token-set [{:keys [token-set-id]}] (ptk/reify ::toggle-token-set ptk/WatchEvent (watch [it state _] - (js/console.log "token-set-id token-theme-id" token-set-id token-theme-id) - (let [theme (some-> (or token-theme-id (wtts/update-theme-id state)) - (wtts/get-workspace-token-theme state)) + (let [target-theme-id (wtts/get-temp-theme-id state) + active-set-ids (wtts/get-active-set-ids state) + theme (-> (wtts/get-workspace-token-theme target-theme-id state) + (assoc :sets active-set-ids)) changes (-> (pcb/empty-changes it) (pcb/update-token-theme (wtts/toggle-token-set-to-token-theme token-set-id theme) theme) - (pcb/update-active-token-themes #{(wtts/update-theme-id state)} (wtts/get-active-theme-ids state)))] + (pcb/update-active-token-themes #{target-theme-id} (wtts/get-active-theme-ids state)))] (rx/of (dch/commit-changes changes) (wtu/update-workspace-tokens)))))) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index c5dded93e..91c949826 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -163,7 +163,7 @@ :token-set-selected? (constantly false) :token-set-active? token-set-active? :on-select on-toggle-token-set - :on-toggle on-toggle-token-set + :on-toggle-token-set on-toggle-token-set :context sets-context/static-context}]] [:div {:class (stl/css :edit-theme-footer)} (if edit? diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 9f5603efb..aee24445c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -128,6 +128,7 @@ token-set-selected? token-set-active? on-create-token-set + on-toggle-token-set on-select context] :as _props}] @@ -141,6 +142,7 @@ :editing? editing? :on-select on-select :on-edit on-edit + :on-toggle on-toggle-token-set :on-submit #(do (on-update-token-set %) (on-reset)) @@ -175,6 +177,6 @@ :token-set-selected? token-set-selected? :token-set-active? token-set-active? :on-select on-select-token-set-click - :on-toggle on-toggle-token-set-click + :on-toggle-token-set on-toggle-token-set-click :on-update-token-set on-update-token-set :on-create-token-set on-create-token-set}])) From b24b178e29b42232ed29d6cfd96be083ca778d84 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 15:00:15 +0200 Subject: [PATCH 43/48] Make resizable --- .../app/main/ui/workspace/tokens/sidebar.cljs | 17 ++++++++++++++--- .../app/main/ui/workspace/tokens/sidebar.scss | 9 +++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index b26a69956..45a12a5cd 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -14,7 +14,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar]] - [app.main.ui.context :as muc] + [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.tokens.changes :as wtch] @@ -283,13 +283,24 @@ {::mf/wrap [mf/memo] ::mf/wrap-props false} [_props] - (let [show-sets-section? (deref (temp-use-themes-flag))] + (let [show-sets-section? (deref (temp-use-themes-flag)) + {on-pointer-down-pages :on-pointer-down + on-lost-pointer-capture-pages :on-lost-pointer-capture + on-pointer-move-pages :on-pointer-move + size-pages-opened :size} + (use-resize-hook :sitemap 200 38 400 :y false nil)] [:div {:class (stl/css :sidebar-tab-wrapper)} (when show-sets-section? - [:div {:class (stl/css :sets-section-wrapper)} + [:div {:class (stl/css :sets-section-wrapper) + :style {:height (str size-pages-opened "px")}} [:& themes-sidebar] [:& sets-sidebar]]) [:div {:class (stl/css :tokens-section-wrapper)} + (when show-sets-section? + [:div {:class (stl/css :resize-area-horiz) + :on-pointer-down on-pointer-down-pages + :on-lost-pointer-capture on-lost-pointer-capture-pages + :on-pointer-move on-pointer-move-pages}]) [:& tokens-explorer]] [:button {:class (stl/css :download-json-button) :on-click wtc/download-tokens-as-json} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss index ea10bc549..092a8bc86 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss @@ -18,6 +18,7 @@ display: flex; flex-direction: column; margin-bottom: $s-8; + overflow-y: auto; } .sets-sidebar { @@ -138,3 +139,11 @@ padding-left: $s-8; color: var(--title-foreground-color); } + +.resize-area-horiz { + position: absolute; + left: 0; + width: 100%; + border-bottom: $s-2 solid var(--resize-area-border-color); + cursor: ns-resize; +} From e363b58774620c5170486ea887f154b78d391894 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 27 Aug 2024 15:22:02 +0200 Subject: [PATCH 44/48] HACK: Fix empty sets showing up in listing --- .../app/main/ui/workspace/tokens/sets.cljs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index aee24445c..184c38cce 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -132,21 +132,22 @@ on-select context] :as _props}] - (let [{:keys [editing? new? on-edit on-create on-reset]} (or context (sets-context/use-context))] + (let [{:keys [editing? new? on-edit on-create on-reset] :as ctx} (or context (sets-context/use-context))] [:ul {:class (stl/css :sets-list)} (for [[id token-set] token-sets] - [:& sets-tree {:key id - :token-set token-set - :token-set-selected? (if new? (constantly false) token-set-selected?) - :token-set-active? token-set-active? - :editing? editing? - :on-select on-select - :on-edit on-edit - :on-toggle on-toggle-token-set - :on-submit #(do - (on-update-token-set %) - (on-reset)) - :on-cancel on-reset}]) + (when token-set + [:& sets-tree {:key id + :token-set token-set + :token-set-selected? (if new? (constantly false) token-set-selected?) + :token-set-active? token-set-active? + :editing? editing? + :on-select on-select + :on-edit on-edit + :on-toggle on-toggle-token-set + :on-submit #(do + (on-update-token-set %) + (on-reset)) + :on-cancel on-reset}])) (when new? [:& sets-tree {:token-set {:name ""} :token-set-selected? (constantly true) From 6bae2efe9dc703cc070dabc8757c097a69fc0f92 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 29 Aug 2024 14:26:11 +0200 Subject: [PATCH 45/48] Validate against names in all token sets --- frontend/src/app/main/refs.cljs | 3 +++ frontend/src/app/main/ui/workspace/tokens/form.cljs | 7 ++++--- .../src/app/main/ui/workspace/tokens/token_set.cljs | 11 +++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 3c09ed541..3e6dbf02c 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -269,6 +269,9 @@ (def workspace-active-theme-sets-tokens (l/derived wtts/get-active-theme-sets-tokens-names-map st/state =)) +(def workspace-ordered-token-sets-tokens + (l/derived wtts/get-workspace-ordered-sets-tokens st/state =)) + (def workspace-selected-token-set-tokens (l/derived (fn [data] diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index c02783ac0..e60ac4170 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -144,7 +144,8 @@ Token names should only contain letters and digits separated by . characters.")} (mf/defc form {::mf/wrap-props false} [{:keys [token token-type] :as _args}] - (let [selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens) + (let [tokens (mf/deref refs/workspace-ordered-token-sets-tokens) + _ (js/console.log "tokens" tokens) active-theme-tokens (mf/deref refs/workspace-active-theme-sets-tokens) resolved-tokens (sd/use-resolved-tokens active-theme-tokens {:names-map? true :cache-atom form-token-cache-atom}) @@ -152,9 +153,9 @@ Token names should only contain letters and digits separated by . characters.")} (mf/deps (:name token)) #(wtt/token-name->path (:name token))) selected-set-tokens-tree (mf/use-memo - (mf/deps token-path selected-set-tokens) + (mf/deps token-path tokens) (fn [] - (-> (wtt/token-names-tree selected-set-tokens) + (-> (wtt/token-names-tree tokens) ;; Allow setting editing token to it's own path (d/dissoc-in token-path)))) diff --git a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs index dab231665..62eb5def4 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_set.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_set.cljs @@ -122,6 +122,17 @@ (->> (map (fn [id] [id (get token-sets id)]) top-level-set-ids) (into (ordered-map))))) +(defn get-workspace-ordered-sets-tokens [state] + (let [sets (get-workspace-ordered-sets state)] + (reduce + (fn [acc [_ {:keys [tokens] :as sets}]] + (reduce (fn [acc' token-id] + (if-let [token (wtt/get-workspace-token token-id state)] + (assoc acc' (wtt/token-identifier token) token) + acc')) + acc tokens)) + {} sets))) + (defn get-token-set [set-id state] (some-> (get-workspace-sets state) (get set-id))) From ca611c66684f7c7a084652107f32aa25cf043406 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 29 Aug 2024 15:59:58 +0200 Subject: [PATCH 46/48] Cleanup --- frontend/src/app/main/ui/workspace/tokens/form.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index e60ac4170..265016a93 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -145,7 +145,6 @@ Token names should only contain letters and digits separated by . characters.")} {::mf/wrap-props false} [{:keys [token token-type] :as _args}] (let [tokens (mf/deref refs/workspace-ordered-token-sets-tokens) - _ (js/console.log "tokens" tokens) active-theme-tokens (mf/deref refs/workspace-active-theme-sets-tokens) resolved-tokens (sd/use-resolved-tokens active-theme-tokens {:names-map? true :cache-atom form-token-cache-atom}) From 54b754c38c475ca2fe2ead19df56bb2f8e4641c0 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 29 Aug 2024 16:01:31 +0200 Subject: [PATCH 47/48] Cleanup --- frontend/src/app/main/ui/context.cljs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index 009366257..1aa4b532b 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -31,5 +31,3 @@ (def workspace-read-only? (mf/create-context nil)) (def is-component? (mf/create-context false)) (def sidebar (mf/create-context nil)) - -(def token-sets (mf/create-context nil)) From ae5aaf83327aeb6ce06d9b869a66bc13ba65fafe Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 29 Aug 2024 16:02:22 +0200 Subject: [PATCH 48/48] Cleanup --- frontend/src/app/main/ui/components/title_bar.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/ui/components/title_bar.cljs b/frontend/src/app/main/ui/components/title_bar.cljs index 49a996570..04e621133 100644 --- a/frontend/src/app/main/ui/components/title_bar.cljs +++ b/frontend/src/app/main/ui/components/title_bar.cljs @@ -10,6 +10,7 @@ [app.common.data.macros :as dm] [app.main.ui.icons :as i] [rumext.v2 :as mf])) + (def ^:private chevron-icon (i/icon-xref :arrow (stl/css :chevron-icon)))