diff --git a/frontend/resources/images/icons/arrow-down.svg b/frontend/resources/images/icons/arrow-down.svg
new file mode 100644
index 000000000..c947ef5b7
--- /dev/null
+++ b/frontend/resources/images/icons/arrow-down.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/resources/images/icons/arrow-left.svg b/frontend/resources/images/icons/arrow-left.svg
new file mode 100644
index 000000000..5fd7250b7
--- /dev/null
+++ b/frontend/resources/images/icons/arrow-left.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/resources/images/icons/arrow-right.svg b/frontend/resources/images/icons/arrow-right.svg
new file mode 100644
index 000000000..d95bda1ad
--- /dev/null
+++ b/frontend/resources/images/icons/arrow-right.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/resources/images/icons/arrow-up.svg b/frontend/resources/images/icons/arrow-up.svg
new file mode 100644
index 000000000..505e91dcf
--- /dev/null
+++ b/frontend/resources/images/icons/arrow-up.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/src/app/main/ui/ds/foundations/assets/icon.cljs b/frontend/src/app/main/ui/ds/foundations/assets/icon.cljs
index 50545e1e2..077083f28 100644
--- a/frontend/src/app/main/ui/ds/foundations/assets/icon.cljs
+++ b/frontend/src/app/main/ui/ds/foundations/assets/icon.cljs
@@ -50,6 +50,10 @@
(def ^:icon-id align-top "align-top")
(def ^:icon-id align-vertical-center "align-vertical-center")
(def ^:icon-id arrow "arrow")
+(def ^:icon-id arrow-up "arrow-up")
+(def ^:icon-id arrow-down "arrow-down")
+(def ^:icon-id arrow-left "arrow-left")
+(def ^:icon-id arrow-right "arrow-right")
(def ^:icon-id asc-sort "asc-sort")
(def ^:icon-id board "board")
(def ^:icon-id boards-thumbnail "boards-thumbnail")
diff --git a/frontend/src/app/main/ui/ds/foundations/typography/heading.cljs b/frontend/src/app/main/ui/ds/foundations/typography/heading.cljs
index 515b529e6..9b3898b6c 100644
--- a/frontend/src/app/main/ui/ds/foundations/typography/heading.cljs
+++ b/frontend/src/app/main/ui/ds/foundations/typography/heading.cljs
@@ -32,17 +32,17 @@
(let [level (or level "1")
tag (dm/str "h" level)
- class (dm/str (or class "") " " (stl/css-case :display-typography (= typography t/display)
- :title-large-typography (= typography t/title-large)
- :title-medium-typography (= typography t/title-medium)
- :title-small-typography (= typography t/title-small)
- :headline-large-typography (= typography t/headline-large)
- :headline-medium-typography (= typography t/headline-medium)
- :headline-small-typography (= typography t/headline-small)
- :body-large-typography (= typography t/body-large)
- :body-medium-typography (= typography t/body-medium)
- :body-small-typography (= typography t/body-small)
- :code-font-typography (= typography t/code-font)))
+ class (dm/str class " " (stl/css-case :display-typography (= typography t/display)
+ :title-large-typography (= typography t/title-large)
+ :title-medium-typography (= typography t/title-medium)
+ :title-small-typography (= typography t/title-small)
+ :headline-large-typography (= typography t/headline-large)
+ :headline-medium-typography (= typography t/headline-medium)
+ :headline-small-typography (= typography t/headline-small)
+ :body-large-typography (= typography t/body-large)
+ :body-medium-typography (= typography t/body-medium)
+ :body-small-typography (= typography t/body-small)
+ :code-font-typography (= typography t/code-font)))
props (mf/spread-props props {:class class})]
[:> tag props
children]))
diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs
index 677439a04..1593f632d 100644
--- a/frontend/src/app/main/ui/workspace/tokens/form.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs
@@ -19,6 +19,7 @@
[app.main.ui.components.color-bullet :refer [color-bullet]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
+ [app.main.ui.ds.foundations.typography.heading :refer [heading*]]
[app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.workspace.colorpicker :as colorpicker]
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector]]
@@ -353,14 +354,14 @@ Token names should only contain letters and digits separated by . characters.")}
[:form {:class (stl/css :form-wrapper)
:on-submit on-submit}
[:div {:class (stl/css :token-rows)}
- [:> text* {:as "span" :typography "headline-medium"}
+ [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :form-modal-title)}
(if (= action "edit")
(tr "workspace.token.edit-token")
(tr "workspace.token.create-token" token-type))]
[:div {:class (stl/css :input-row)}
;; This should be remove when labeled-imput is modified
- [:span "Name"]
+ [:span {:class (stl/css :labeled-input-label)} "Name"]
[:& tokens.common/labeled-input {:label "Name"
:error? @name-errors
:input-props {:default-value @name-ref
@@ -378,7 +379,7 @@ Token names should only contain letters and digits separated by . characters.")}
[:div {:class (stl/css :input-row)}
;; This should be remove when labeled-imput is modified
- [:span "value"]
+ [:span {:class (stl/css :labeled-input-label)} "value"]
[:& tokens.common/labeled-input {:label "Value"
:input-props {:default-value @value-ref
:on-blur on-update-value
@@ -401,7 +402,7 @@ Token names should only contain letters and digits separated by . characters.")}
[:div {:class (stl/css :input-row)}
;; This should be remove when labeled-imput is modified
- [:span "Description"]
+ [:span {:class (stl/css :labeled-input-label)} "Description"]
[:& tokens.common/labeled-input {:label "Description"
:input-props {:default-value @description-ref
:on-change on-update-description}}]
@@ -416,10 +417,12 @@ Token names should only contain letters and digits separated by . characters.")}
(when (= action "edit")
[:> button* {:on-click on-delete-token
:class (stl/css :delete-btn)
+ :type "button"
:icon i/delete
:variant "secondary"}
(tr "labels.delete")])
[:> button* {:on-click on-cancel
+ :type "button"
:variant "secondary"}
(tr "labels.cancel")]
[:> button* {:type "submit"
diff --git a/frontend/src/app/main/ui/workspace/tokens/form.scss b/frontend/src/app/main/ui/workspace/tokens/form.scss
index dd35014ac..0c0dfff67 100644
--- a/frontend/src/app/main/ui/workspace/tokens/form.scss
+++ b/frontend/src/app/main/ui/workspace/tokens/form.scss
@@ -39,6 +39,10 @@
gap: $s-4;
}
+.labeled-input-label {
+ color: var(--color-foreground-primary);
+}
+
.error {
padding: $s-4 $s-6;
margin-bottom: 0;
@@ -75,3 +79,7 @@
border-radius: $br-4;
cursor: pointer;
}
+
+.form-modal-title {
+ color: var(--color-foreground-primary);
+}
diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.cljs b/frontend/src/app/main/ui/workspace/tokens/modals.cljs
index 06ef35af9..a34ccfe61 100644
--- a/frontend/src/app/main/ui/workspace/tokens/modals.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/modals.cljs
@@ -12,7 +12,6 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.workspace.tokens.form :refer [form]]
- [app.main.ui.workspace.tokens.modals.themes :as wtmt]
[app.util.i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf]))
@@ -60,12 +59,6 @@
:selected-token-set-id selected-token-set-id
: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
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 c70105df3..b90be4331 100644
--- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs
@@ -7,36 +7,49 @@
(ns app.main.ui.workspace.tokens.modals.themes
(:require-macros [app.main.style :as stl])
(:require
+ [app.common.data.macros :as dm]
[app.common.types.tokens-lib :as ctob]
[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.radio-buttons :refer [radio-button radio-buttons]]
+ [app.main.ui.ds.buttons.button :refer [button*]]
+ [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
+ [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as ic]
+ [app.main.ui.ds.foundations.typography.heading :refer [heading*]]
+ [app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.tokens.common :refer [labeled-input] :as wtco]
[app.main.ui.workspace.tokens.sets :as wts]
[app.main.ui.workspace.tokens.sets-context :as sets-context]
[app.util.dom :as dom]
+ [app.util.i18n :refer [tr]]
[cuerdas.core :as str]
[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)))
-
(mf/defc empty-themes
[{: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"]]])
+ (let [create-theme
+ (mf/use-fn
+ (mf/deps set-state)
+ #(set-state (fn [_] {:type :create-theme})))]
+ [:div {:class (stl/css :themes-modal-wrapper)}
+ [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
+ (tr "workspace.token.themes")]
+ [:div {:class (stl/css :empty-themes-wrapper)}
+ [:div {:class (stl/css :empty-themes-message)}
+ [:> text* {:as "span" :typography "title-medium" :class (stl/css :empty-theme-title)}
+ (tr "workspace.token.no-themes-currently")]
+ [:> text* {:as "span"
+ :class (stl/css :empty-theme-subtitle)
+ :typography "body-medium"}
+ (tr "workspace.token.create-new-theme")]]
+ [:div {:class (stl/css :button-footer)}
+ [:> button* {:variant "primary"
+ :type "button"
+ :on-click create-theme}
+ (tr "workspace.token.new-theme")]]]]))
(mf/defc switch
[{:keys [selected? name on-change]}]
@@ -57,60 +70,195 @@
[{:keys [set-state]}]
(let [active-theme-ids (mf/deref refs/workspace-active-theme-paths)
themes-groups (mf/deref refs/workspace-token-theme-tree-no-hidden)
- on-edit-theme (fn [theme e]
- (dom/prevent-default e)
- (dom/stop-propagation e)
- (set-state (fn [_] {:type :edit-theme
- :theme-path [(:id theme) (:group theme) (:name theme)]})))]
- [:div
+
+ create-theme
+ (mf/use-fn
+ (mf/deps set-state)
+ (fn [e]
+ (dom/prevent-default e)
+ (dom/stop-propagation e)
+ (set-state (fn [_] {:type :create-theme}))))]
+
+ [:div {:class (stl/css :themes-modal-wrapper)}
+ [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
+ (tr "workspace.token.themes")]
[:ul {:class (stl/css :theme-group-wrapper)}
(for [[group themes] themes-groups]
- [:li {:key (str "token-theme-group" group)}
+ [:li {:key (dm/str "token-theme-group" group)}
(when (seq group)
- [:span {:class (stl/css :theme-group-label)} group])
+ [:> heading* {:level 3
+ :class (stl/css :theme-group-label)
+ :typography "body-large"}
+ [:span {:class (stl/css :group-title)}
+ [:> icon* {:id "group"}]
+ group]])
[:ul {:class (stl/css :theme-group-rows-wrapper)}
(for [[_ {:keys [group name] :as theme}] themes
:let [theme-id (ctob/theme-path theme)
- selected? (some? (get active-theme-ids theme-id))]]
+ selected? (some? (get active-theme-ids theme-id))
+ delete-theme
+ (fn [e]
+ (dom/prevent-default e)
+ (dom/stop-propagation e)
+ (st/emit! (wdt/delete-token-theme group name)))
+ on-edit-theme
+ (fn [e]
+ (dom/prevent-default e)
+ (dom/stop-propagation e)
+ (set-state (fn [_] {:type :edit-theme
+ :theme-path [(:id theme) (:group theme) (:name theme)]})))]]
[:li {:key theme-id
:class (stl/css :theme-row)}
[:div {:class (stl/css :theme-row-left)}
+
+ ;; FIREEEEEEEEEE THIS
[:div {:on-click (fn [e]
(dom/prevent-default e)
(dom/stop-propagation e)
(st/emit! (wdt/toggle-token-theme-active? group name)))}
- [:& switch {:name (str "Theme" name)
+ [:& switch {:name (tr "workspace.token.theme" name)
:on-change (constantly nil)
:selected? selected?}]]
- [:span {:class (stl/css :theme-row-label)} name]]
+ [:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name)} name]]
+
+
[:div {:class (stl/css :theme-row-right)}
(if-let [sets-count (some-> theme :sets seq count)]
- [: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)
- :on-click #(on-edit-theme theme %)}
- "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 group name)))}
- i/delete]]]])]])]
- [:div {:class (stl/css :button-footer)}
- [: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"]]]))
+ [:> button* {:class (stl/css :sets-count-button)
+ :variant "secondary"
+ :type "button"
+ :on-click on-edit-theme}
+ [:div {:class (stl/css :label-wrapper)}
+ [:> text* {:as "span" :typography "body-medium"}
+ (tr "workspace.token.num-sets" sets-count)]
+ [:> icon* {:id "arrow-right"}]]]
-(mf/defc edit-theme
- [{:keys [edit? token-sets theme theme-groups on-back on-submit]}]
- (let [{:keys [dropdown-open? on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
+ [:> button* {:class (stl/css :sets-count-empty-button)
+ :type "button"
+ :variant "secondary"
+ :on-click on-edit-theme}
+ [:div {:class (stl/css :label-wrapper)}
+ [:> text* {:as "span" :typography "body-medium"}
+ (tr "workspace.token.no-sets")]
+ [:> icon* {:id "arrow-right"}]]])
+
+ [:> icon-button* {:on-click delete-theme
+ :variant "ghost"
+ :aria-label (tr "workspace.token.delete-theme-title")
+ :icon "delete"}]]])]])]
+
+ [:div {:class (stl/css :button-footer)}
+ [:> button* {:variant "primary"
+ :type "button"
+ :icon "add"
+ :on-click create-theme}
+ (tr "workspace.token.create-theme-title")]]]))
+
+(mf/defc theme-inputs
+ [{:keys [theme dropdown-open? on-close-dropdown on-toggle-dropdown on-change-field]}]
+ (let [theme-groups (mf/deref refs/workspace-token-theme-groups)
+ group-input-ref (mf/use-ref)
+ on-update-group (partial on-change-field :group)
+ on-update-name (partial on-change-field :name)]
+ [:div {:class (stl/css :edit-theme-inputs-wrapper)}
+ [:div {:class (stl/css :group-input-wrapper)}
+ (when dropdown-open?
+ [:& wtco/dropdown-select {:id ::groups-dropdown
+ :shortcuts-key ::groups-dropdown
+ :options (map (fn [group]
+ {:label group
+ :value group})
+ theme-groups)
+ :on-select (fn [{:keys [value]}]
+ (set! (.-value (mf/ref-val group-input-ref)) value)
+ (on-update-group value))
+ :on-close on-close-dropdown}])
+ ;; TODO: This span should be remove when labeled-input is updated
+ [:span {:class (stl/css :labeled-input-label)} "Theme group"]
+ [:& labeled-input {:label "Group"
+ :input-props {:ref group-input-ref
+ :default-value (:group theme)
+ :on-change (comp on-update-group dom/get-target-val)}
+ :render-right (when (seq theme-groups)
+ (mf/fnc []
+ [:button {:class (stl/css :group-drop-down-button)
+ :type "button"
+ :on-click (fn [e]
+ (dom/stop-propagation e)
+ (on-toggle-dropdown))}
+ [:> icon* {:id "arrow-down"}]]))}]]
+ [:div {:class (stl/css :group-input-wrapper)}
+ ;; TODO: This span should be remove when labeled-input is updated
+ [:span {:class (stl/css :labeled-input-label)} "Theme"]
+ [:& labeled-input {:label "Theme"
+ :input-props {:default-value (:name theme)
+ :on-change (comp on-update-name dom/get-target-val)}}]]]))
+
+(mf/defc theme-modal-buttons
+ [{:keys [close-modal on-save-form disabled?] :as props}]
+ [:*
+ [:> button* {:variant "secondary"
+ :type "button"
+ :on-click close-modal}
+ (tr "labels.cancel")]
+ [:> button* {:variant "primary"
+ :type "submit"
+ :on-click on-save-form
+ :disabled disabled?}
+ (tr "workspace.token.save-theme")]])
+
+(mf/defc create-theme
+ [{:keys [set-state]}]
+ (let [{:keys [dropdown-open? _on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
+ theme (ctob/make-token-theme :name "")
+ on-back #(set-state (constantly {:type :themes-overview}))
+ on-submit #(st/emit! (wdt/create-token-theme %))
+ theme-state (mf/use-state theme)
+ disabled? (-> (:name @theme-state)
+ (str/trim)
+ (str/empty?))
+ on-change-field (fn [field value]
+ (swap! theme-state #(assoc % field value)))
+ on-save-form (mf/use-callback
+ (mf/deps theme-state on-submit)
+ (fn [e]
+ (dom/prevent-default e)
+ (let [theme (-> @theme-state
+ (update :name str/trim)
+ (update :group str/trim)
+ (update :description str/trim))]
+ (when-not (str/empty? (:name theme))
+ (on-submit theme)))
+ (on-back)))
+ close-modal (mf/use-fn
+ (fn [e]
+ (dom/prevent-default e)
+ (st/emit! (modal/hide))))]
+ [:div {:class (stl/css :themes-modal-wrapper)}
+ [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
+ (tr "workspace.token.create-theme-title")]
+ [:form {:on-submit on-save-form}
+ [:div {:class (stl/css :create-theme-wrapper)}
+ [:& theme-inputs {:dropdown-open? dropdown-open?
+ :on-close-dropdown on-close-dropdown
+ :on-toggle-dropdown on-toggle-dropdown
+ :theme theme
+ :on-change-field on-change-field}]
+
+ [:div {:class (stl/css :button-footer)}
+ [:& theme-modal-buttons {:close-modal close-modal
+ :on-save-form on-save-form
+ :disabled? disabled?}]]]]]))
+
+(mf/defc controlled-edit-theme
+ [{:keys [state set-state]}]
+ (let [{:keys [theme-path]} @state
+ [_ theme-group theme-name] theme-path
+ token-sets (mf/deref refs/workspace-ordered-token-sets)
+ theme (mf/deref (refs/workspace-token-theme theme-group theme-name))
+ on-back #(set-state (constantly {:type :themes-overview}))
+ on-submit #(st/emit! (wdt/update-token-theme [(:group theme) (:name theme)] %))
+ {:keys [dropdown-open? _on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
theme-state (mf/use-state theme)
disabled? (-> (:name @theme-state)
(str/trim)
@@ -125,9 +273,6 @@
(swap! theme-state #(ctob/toggle-set % set-name))))
on-change-field (fn [field value]
(swap! theme-state #(assoc % field value)))
- group-input-ref (mf/use-ref)
- on-update-group (partial on-change-field :group)
- on-update-name (partial on-change-field :name)
on-save-form (mf/use-callback
(mf/deps theme-state on-submit)
(fn [e]
@@ -138,124 +283,83 @@
(update :description str/trim))]
(when-not (str/empty? (:name theme))
(on-submit theme)))
- (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)}
- [:div {:class (stl/css :group-input-wrapper)}
- (when dropdown-open?
- [:& wtco/dropdown-select {:id ::groups-dropdown
- :shortcuts-key ::groups-dropdown
- :options (map (fn [group]
- {:label group
- :value group})
- theme-groups)
- :on-select (fn [{:keys [value]}]
- (set! (.-value (mf/ref-val group-input-ref)) value)
- (on-update-group value))
- :on-close on-close-dropdown}])
- [:& labeled-input {:label "Group"
- :input-props {:ref group-input-ref
- :default-value (:group theme)
- :on-change (comp on-update-group dom/get-target-val)}
- :render-right (when (seq theme-groups)
- (mf/fnc []
- [:button {:class (stl/css :group-drop-down-button)
- :type "button"
- :on-click (fn [e]
- (dom/stop-propagation e)
- (on-toggle-dropdown))}
- i/arrow]))}]]
- [:& labeled-input {:label "Theme"
- :input-props {:default-value (:name theme)
- :on-change (comp on-update-name dom/get-target-val)}}]]
- [: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-token-set on-toggle-token-set
- :context sets-context/static-context}]]
- [:div {:class (stl/css :edit-theme-footer)}
- (if edit?
- [:button {:class (stl/css :button-secondary)
- :type "button"
- :on-click (fn []
- (st/emit! (wdt/delete-token-theme (:group theme) (:name theme)))
- (on-back))}
- "Delete"]
- [:div])
- [: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
- :disabled disabled?}
- "Save theme"]]]]]))
+ (on-back)))
+ close-modal
+ (mf/use-fn
+ (fn [e]
+ (dom/prevent-default e)
+ (st/emit! (modal/hide))))
-(mf/defc controlled-edit-theme
- [{:keys [state set-state]}]
- (let [{:keys [theme-path]} @state
- [_ theme-group theme-name] theme-path
- token-sets (mf/deref refs/workspace-ordered-token-sets)
- theme (mf/deref (refs/workspace-token-theme theme-group theme-name))
- theme-groups (mf/deref refs/workspace-token-theme-groups)]
- [:& edit-theme
- {:edit? true
- :token-sets token-sets
- :theme theme
- :theme-groups theme-groups
- :on-back #(set-state (constantly {:type :themes-overview}))
- :on-submit #(st/emit! (wdt/update-token-theme [(:group theme) (:name theme)] %))}]))
+ on-delete-token
+ (mf/use-fn
+ (mf/deps theme on-back)
+ (fn []
+ (st/emit! (wdt/delete-token-theme (:group theme) (:name theme)))
+ (on-back)))]
-(mf/defc create-theme
- [{:keys [set-state]}]
- (let [token-sets (mf/deref refs/workspace-ordered-token-sets)
- theme (ctob/make-token-theme :name "")
- theme-groups (mf/deref refs/workspace-token-theme-groups)]
- [:& edit-theme
- {:edit? false
- :token-sets token-sets
- :theme theme
- :theme-groups theme-groups
- :on-back #(set-state (constantly {:type :themes-overview}))
- :on-submit #(st/emit! (wdt/create-token-theme %))}]))
+ [:div {:class (stl/css :themes-modal-wrapper)}
+ [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
+ (tr "workspace.token.edit-theme-title")]
-(mf/defc themes
+ [:form {:on-submit on-save-form}
+ [:div {:class (stl/css :edit-theme-wrapper)}
+ [:button {:on-click on-back
+ :class (stl/css :back-btn)
+ :type "button"}
+ [:> icon* {:id ic/arrow-left :aria-hidden true}]
+ (tr "workspace.token.back-to-themes")]
+
+ [:& theme-inputs {:dropdown-open? dropdown-open?
+ :on-close-dropdown on-close-dropdown
+ :on-toggle-dropdown on-toggle-dropdown
+ :theme theme
+ :on-change-field on-change-field}]
+
+ [: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-token-set on-toggle-token-set
+ :context sets-context/static-context}]]
+
+ [:div {:class (stl/css :edit-theme-footer)}
+ [:> button* {:variant "secondary"
+ :type "button"
+ :on-click on-delete-token}
+ (tr "labels.delete")]
+ [:div {:class (stl/css :button-footer)}
+ [:& theme-modal-buttons {:close-modal close-modal
+ :on-save-form on-save-form
+ :disabled? disabled?}]]]]]]))
+
+(mf/defc themes-modal-body
[_]
(let [themes (mf/deref refs/workspace-token-themes-no-hidden)
state (mf/use-state (if (empty? themes)
{:type :create-theme}
{: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 (if (empty? themes) empty-themes themes-overview)
: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
- :set-state set-state}]]]))
+ [:& component {:state state
+ :set-state set-state}]))
-(mf/defc modal
- {::mf/wrap-props false}
- [_]
+(mf/defc token-themes-modal
+ {::mf/wrap-props false
+ ::mf/register modal/components
+ ::mf/register-as :tokens/themes}
+ [_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]
- [:& themes]]]))
+ [:> icon-button* {:class (stl/css :close-btn)
+ :on-click handle-close-dialog
+ :aria-label (tr "labels.close")
+ :variant "action"
+ :icon "close"}]
+ [:& themes-modal-body]]]))
\ No newline at end of file
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 ca41bd82e..ca3d2e845 100644
--- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss
+++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss
@@ -10,10 +10,6 @@
@extend .modal-overlay-base;
}
-hr {
- border-color: var(--color-background-tertiary);
-}
-
.modal-dialog {
@extend .modal-container-base;
display: grid;
@@ -23,16 +19,43 @@ hr {
user-select: none;
}
-.modal-title {
- @include headlineMediumTypography;
- font-weight: 500;
- margin-block-end: $s-16;
- color: var(--color-foreground-secondary);
-}
-
-.modal-content {
+.empty-themes-message {
display: flex;
flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: $s-12;
+ padding: $s-72 0;
+}
+
+.themes-modal-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: $s-24;
+}
+
+.themes-modal-title {
+ color: var(--color-foreground-primary);
+}
+
+.back-btn {
+ background-color: transparent;
+ border: none;
+ appearance: none;
+ color: var(--color-foreground-secondary);
+ width: fit-content;
+ display: grid;
+ grid-template-columns: auto auto;
+ gap: $s-4;
+ align-items: center;
+ padding: 0;
+ &:hover {
+ color: var(--color-accent-primary);
+ }
+}
+
+.labeled-input-label {
+ color: var(--color-foreground-primary);
}
.button-footer {
@@ -46,60 +69,41 @@ hr {
justify-content: space-between;
}
-.button-primary {
- @extend .button-primary;
- padding: $s-6;
-}
-
-.button-secondary {
- @extend .button-secondary;
- 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);
- }
- }
+ color: var(--color-foreground-secondary);
}
-.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);
- }
+.empty-theme-subtitle {
+ color: var(--color-foreground-secondary);
+}
+
+.empty-theme-title {
+ color: var(--color-foreground-primary);
+}
+
+.create-theme-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: $s-24;
}
.close-btn {
- @extend .modal-close-btn-base;
+ position: absolute;
+ top: $s-8;
+ right: $s-6;
}
.theme-group-label {
- display: block;
- @include headlineMediumTypography;
color: var(--color-foreground-secondary);
- margin-bottom: $s-8;
+}
+
+.group-title {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: $s-4;
}
.theme-group-rows-wrapper {
@@ -127,34 +131,26 @@ hr {
gap: $s-16;
}
+.theme-name {
+ color: var(--color-foreground-primary);
+}
+
.theme-row-right {
display: flex;
align-items: center;
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;
+ text-transform: lowercase;
padding: $s-6;
padding-left: $s-12;
- svg {
- margin-left: $s-6;
- @extend .button-icon;
- stroke: var(--icon-foreground);
- }
+}
+
+.label-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
.edit-theme-wrapper {
@@ -163,12 +159,6 @@ hr {
gap: $s-12;
}
-.edit-theme-inputs-wrapper {
- display: grid;
- grid-template-columns: 0.6fr 1fr;
- gap: $s-12;
-}
-
.sets-list-wrapper {
border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent);
border-radius: $s-8;
@@ -176,57 +166,29 @@ hr {
}
.sets-count-empty-button {
- @extend .button-secondary;
+ text-transform: lowercase;
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 {
- @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);
- }
- }
}
.group-input-wrapper {
position: relative;
+ display: flex;
+ flex-direction: column;
+ gap: $s-4;
+}
+
+.edit-theme-inputs-wrapper {
+ display: grid;
+ grid-template-columns: 0.6fr 1fr;
+ gap: $s-12;
}
.group-drop-down-button {
@include buttonStyle;
+ color: var(--color-foreground-secondary);
width: $s-24;
height: 100%;
-
padding: 0;
margin: 0 $s-6;
-
- svg {
- @extend .button-icon-small;
- transform: rotate(90deg);
- fill: var(--icon-foreground);
- }
}
diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
index e2c522f4c..9331def22 100644
--- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
@@ -16,9 +16,10 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.color-bullet :refer [color-bullet]]
- [app.main.ui.components.dropdown-menu :refer [dropdown-menu
- dropdown-menu-item*]]
+ [app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]]
[app.main.ui.components.title-bar :refer [title-bar]]
+ [app.main.ui.ds.buttons.button :refer [button*]]
+ [app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.icons :as i]
@@ -173,22 +174,26 @@
{:empty (sort-by :token-key empty)
:filled (sort-by :token-key filled)}))
-(mf/defc edit-button
- [{:keys [create?]}]
- [:button {:class (stl/css :themes-button)
- :on-click (fn [e]
- (dom/stop-propagation e)
- (modal/show! :tokens/themes {}))}
- (if create? (tr "labels.create") (tr "labels.edit"))])
-
(mf/defc themes-header
[_props]
- (let [ordered-themes (mf/deref refs/workspace-token-themes-no-hidden)]
+ (let [ordered-themes (mf/deref refs/workspace-token-themes-no-hidden)
+ open-modal
+ (mf/use-fn
+ (fn [e]
+ (dom/stop-propagation e)
+ (modal/show! :tokens/themes {})))]
[:div {:class (stl/css :themes-wrapper)}
[:span {:class (stl/css :themes-header)} (tr "labels.themes")]
- [:div {:class (stl/css :theme-select-wrapper)}
- [:& theme-select]
- [:& edit-button {:create? (empty? ordered-themes)}]]]))
+ (if (empty? ordered-themes)
+ [:div {:class (stl/css :empty-theme-wrapper)}
+ [:> text* {:as "span" :typography "body-small"} (tr "workspace.token.no-themes")]
+ [:button {:on-click open-modal
+ :class (stl/css :create-theme-button)} (tr "workspace.token.create-a-theme")]]
+ [:div {:class (stl/css :theme-select-wrapper)}
+ [:& theme-select]
+ [:> button* {:variant "secondary"
+ :on-click open-modal}
+ (tr "labels.edit")]])]))
(mf/defc add-set-button
[{:keys [on-open]}]
diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss
index aede52260..f3608a903 100644
--- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss
+++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss
@@ -4,6 +4,7 @@
//
// Copyright (c) KALEIDOS INC
+@use "../../ds/typography.scss" as *;
@import "refactor/common-refactor.scss";
@import "./common.scss";
@@ -37,9 +38,21 @@
position: relative;
}
+.themes-header {
+ display: block;
+ @include headlineSmallTypography;
+ margin-bottom: $s-8;
+ padding-left: $s-8;
+ color: var(--title-foreground-color);
+}
+
.themes-wrapper {
+ padding: $s-12 0 0 $s-12;
+}
+
+.empty-theme-wrapper {
padding: $s-12;
- padding-bottom: 0;
+ color: var(--color-foreground-secondary);
}
.sidebar-header {
@@ -168,12 +181,13 @@
width: auto;
}
-.themes-header {
- display: block;
- @include headlineSmallTypography;
- margin-bottom: $s-8;
- padding-left: $s-8;
- color: var(--title-foreground-color);
+.create-theme-button {
+ @include use-typography("body-small");
+ background-color: transparent;
+ border: none;
+ appearance: none;
+ color: var(--color-accent-primary);
+ cursor: pointer;
}
.resize-area-horiz {
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 2805949b7..484c806c5 100644
--- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs
@@ -7,6 +7,7 @@
(ns app.main.ui.workspace.tokens.theme-select
(:require-macros [app.main.style :as stl])
(:require
+ [app.common.data.macros :as dm]
[app.common.types.tokens-lib :as ctob]
[app.common.uuid :as uuid]
[app.main.data.modal :as modal]
@@ -14,46 +15,62 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
- [app.main.ui.icons :as i]
+ [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
+ [app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.util.dom :as dom]
+ [app.util.i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(mf/defc themes-list
[{:keys [themes active-theme-paths on-close grouped?]}]
(when (seq themes)
- [:ul
+ [:ul {:class (stl/css :theme-options)}
(for [[_ {:keys [group name] :as theme}] themes
:let [theme-id (ctob/theme-path theme)
- selected? (get active-theme-paths theme-id)]]
+ selected? (get active-theme-paths theme-id)
+ select-theme (fn [e]
+ (dom/stop-propagation e)
+ (st/emit! (wdt/toggle-token-theme-active? group name))
+ (on-close))]]
[:li {:key theme-id
+ :role "option"
+ :aria-selected selected?
: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-active? group name))
- (on-close))}
- [:span {:class (stl/css :label)} name]
- [:span {:class (stl/css :check-icon)} i/tick]])]))
+ :on-click select-theme}
+ [:> text* {:as "span" :typography "body-small" :class (stl/css :label)} name]
+ [:> icon* {:id i/tick
+ :aria-hidden true
+ :class (stl/css-case :check-icon true
+ :check-icon-visible selected?)}]])]))
(mf/defc theme-options
[{:keys [active-theme-paths themes on-close]}]
- [:ul
- (for [[group themes] themes]
- [:li {:key group}
- (when (seq group)
- [:span {:class (stl/css :group)} group])
- [:& themes-list {:themes themes
- :active-theme-paths active-theme-paths
- :on-close on-close
- :grouped? true}]])
- [:li {:class (stl/css-case :checked-element true
- :checked-element-button true)
- :on-click #(modal/show! :tokens/themes {})}
- [:span "Edit themes"]
- [:span {:class (stl/css :icon)} i/arrow]]])
+ (let []
+ (let [on-edit-click #(modal/show! :tokens/themes {})]
+ [:ul {:class (stl/css :theme-options :custom-select-dropdown)
+ :role "listbox"}
+ (for [[group themes] themes]
+ [:li {:key group
+ :aria-labelledby (dm/str group "-label")
+ :role "group"}
+ (when (seq group)
+ [:> text* {:as "span" :typography "headline-small" :class (stl/css :group) :id (dm/str group "-label")} group])
+ [:& themes-list {:themes themes
+ :active-theme-paths active-theme-paths
+ :on-close on-close
+ :grouped? true}]])
+ [:li {:class (stl/css :separator)
+ :aria-hidden true}]
+ [:li {:class (stl/css-case :checked-element true
+ :checked-element-button true)
+ :role "option"
+ :on-click on-edit-click}
+ [:> text* {:as "span" :typography "body-small"} (tr "workspace.token.edit-themes")]
+ [:> icon* {:id i/arrow-right :aria-hidden true}]]])))
(mf/defc theme-select
[{:keys []}]
@@ -64,11 +81,11 @@
;; Data
current-label (cond
- (> active-themes-count 1) (str active-themes-count " themes active")
+ (> active-themes-count 1) (tr "workspace.token.active-themes" active-themes-count)
(= active-themes-count 1) (some->> (first active-theme-paths)
(ctob/split-token-theme-path)
(str/join " / "))
- :else "No theme active")
+ :else (tr "workspace.token.no-active-theme"))
;; State
state* (mf/use-state
@@ -81,13 +98,20 @@
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))]
+
+ ;; TODO: This element should be accessible by keyboard
[:div {:on-click on-open-dropdown
+ :aria-expanded is-open?
+ :aria-haspopup "listbox"
+ :tab-index "0"
+ :role "combobox"
: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 {:active-theme-paths active-theme-paths
- :themes themes
- :on-close on-close-dropdown}]]]]))
+ [:> text* {:as "span" :typography "body-small" :class (stl/css :current-label)}
+ current-label]
+ [:> icon* {:id i/arrow-down :class (stl/css :dropdown-button) :aria-hidden true}]
+ [:& dropdown {:show is-open?
+ :on-close on-close-dropdown
+ :ref dropdown-element*}
+ [:& theme-options {:active-theme-paths active-theme-paths
+ :themes themes
+ :on-close on-close-dropdown}]]]))
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 da8a7b5a3..79c0f3fc2 100644
--- a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss
+++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss
@@ -7,12 +7,11 @@
@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);
+ --custom-select-border-color: var(--menu-background-color);
+ --custom-select-bg-color: var(--menu-background-color);
+ --custom-select-icon-color: var(--color-foreground-secondary);
+ --custom-select-text-color: var(--menu-foreground-color);
@extend .new-scrollbar;
- @include bodySmallTypography;
position: relative;
display: grid;
grid-template-columns: 1fr auto;
@@ -22,74 +21,60 @@
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);
+ background-color: var(--custom-select-bg-color);
+ border: $s-1 solid var(--custom-select-border-color);
+ color: var(--custom-select-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;
- }
-
&:hover {
- --bg-color: var(--menu-background-color-hover);
- --border-color: var(--menu-background-color);
- --icon-color: var(--menu-foreground-color-hover);
+ --custom-select-bg-color: var(--menu-background-color-hover);
+ --custom-select-border-color: var(--menu-background-color);
+ --custom-select-icon-color: var(--menu-foreground-color-hover);
}
&:focus {
- --bg-color: var(--menu-background-color-focus);
- --border-color: var(--menu-background-focus);
+ --custom-select-bg-color: var(--menu-background-color-focus);
+ --custom-select-border-color: var(--menu-background-focus);
}
}
+.theme-options {
+ margin-bottom: 0;
+}
+
+.group {
+ display: block;
+ padding: $s-8;
+ color: var(--color-foreground-secondary);
+}
+
.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);
+ --custom-select-bg-color: var(--menu-background-color-disabled);
+ --custom-select-border-color: var(--menu-border-color-disabled);
+ --custom-select-icon-color: var(--menu-foreground-color-disabled);
+ --custom-select-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);
- }
+ color: var(--color-foreground-secondary);
}
.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);
- }
+}
+
+.separator {
+ margin: 0;
+ height: $s-2;
+ border-block-start: $s-1 solid color-mix(in hsl, var(--color-foreground-secondary) 20%, transparent);
}
.custom-select-dropdown[data-direction="up"] {
@@ -109,59 +94,31 @@
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;
-
- .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;
}
}
+.check-icon {
+ @include flexCenter;
+ color: var(--icon-foreground-primary);
+ visibility: hidden;
+}
+
+.label {
+ flex-grow: 1;
+ width: 100%;
+}
+
+.check-icon-visible {
+ visibility: visible;
+}
+
.current-label {
@include textEllipsis;
}
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index bdec8767d..2df74f258 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -6163,4 +6163,72 @@ msgstr "Resolved value: "
#: src/app/main/ui/workspace/tokens/sidebar.cljs
msgid "workspace.token.original-value"
-msgstr "Original value: "
\ No newline at end of file
+msgstr "Original value: "
+
+#: src/app/main/ui/workspace/tokens/sidebar.cljs
+msgid "workspace.token.no-themes"
+msgstr "There are no themes."
+
+#: src/app/main/ui/workspace/tokens/sidebar.cljs
+msgid "workspace.token.create-a-theme"
+msgstr "Create one."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.save-theme"
+msgstr "Save theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.create-theme-title"
+msgstr "Create theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.edit-theme-title"
+msgstr "Edit theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.delete-theme-title"
+msgstr "Delete theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.no-themes-currently"
+msgstr "You currently have no themes."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.create-new-theme"
+msgstr "Create your first theme now."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.new-theme"
+msgstr "New theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.themes"
+msgstr "Themes"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.theme-name"
+msgstr "Theme %s"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.no-sets"
+msgstr "No sets defined"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.num-sets"
+msgstr "%s sets"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.back-to-themes"
+msgstr "Back to theme list"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.edit-themes"
+msgstr "Edit themes"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.no-active-theme"
+msgstr "No theme active"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.active-themes"
+msgstr "%s active themes"
\ No newline at end of file
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index 02b19d584..f8c2afa04 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -6150,4 +6150,72 @@ msgstr "Valor resuelto: "
#: src/app/main/ui/workspace/tokens/sidebar.cljs
msgid "workspace.token.original-value"
-msgstr "Valor original: "
\ No newline at end of file
+msgstr "Valor original: "
+
+#: src/app/main/ui/workspace/tokens/sidebar.cljs
+msgid "workspace.token.no-themes"
+msgstr "No hay temas."
+
+#: src/app/main/ui/workspace/tokens/sidebar.cljs
+msgid "workspace.token.create-a-theme"
+msgstr "Crear uno."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.save-theme"
+msgstr "Guardar tema"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.create-theme-title"
+msgstr "Crear tema"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.edit-theme-title"
+msgstr "Editar tema"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.delete-theme-title"
+msgstr "Borrar theme"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.no-themes-currently"
+msgstr "Actualmente no existen temas."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.create-new-theme"
+msgstr "Crea un nuevo tema ahora."
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.new-theme"
+msgstr "Nuevo tema"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.themes"
+msgstr "Temas"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.theme-name"
+msgstr "Tema %s"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.no-sets"
+msgstr "No hay sets definidos"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.num-sets"
+msgstr "%s sets"
+
+#: src/app/main/ui/workspace/tokens/modals/themes.cljs
+msgid "workspace.token.back-to-themes"
+msgstr "Volver al listado de temas"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.edit-themes"
+msgstr "Editar temas"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.no-active-theme"
+msgstr "No hay temas activos"
+
+#: src/app/main/ui/workspace/tokens/theme_select.cljs
+msgid "workspace.token.active-themes"
+msgstr "%s temas activos"
\ No newline at end of file