mirror of
https://github.com/penpot/penpot.git
synced 2025-06-04 14:31:37 +02:00
Merge pull request #313 from tokens-studio/eva-review-themes
♻️ Review themes section
This commit is contained in:
commit
cd7763ca08
17 changed files with 665 additions and 443 deletions
3
frontend/resources/images/icons/arrow-down.svg
Normal file
3
frontend/resources/images/icons/arrow-down.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="m4 6 4 4 4-4"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 144 B |
3
frontend/resources/images/icons/arrow-left.svg
Normal file
3
frontend/resources/images/icons/arrow-left.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M10 12 6 8l4-4"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 145 B |
3
frontend/resources/images/icons/arrow-right.svg
Normal file
3
frontend/resources/images/icons/arrow-right.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="m6 12 4-4-4-4"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 144 B |
3
frontend/resources/images/icons/arrow-up.svg
Normal file
3
frontend/resources/images/icons/arrow-up.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="m4 10 4-4 4 4"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 140 B |
|
@ -50,6 +50,10 @@
|
||||||
(def ^:icon-id align-top "align-top")
|
(def ^:icon-id align-top "align-top")
|
||||||
(def ^:icon-id align-vertical-center "align-vertical-center")
|
(def ^:icon-id align-vertical-center "align-vertical-center")
|
||||||
(def ^:icon-id arrow "arrow")
|
(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 asc-sort "asc-sort")
|
||||||
(def ^:icon-id board "board")
|
(def ^:icon-id board "board")
|
||||||
(def ^:icon-id boards-thumbnail "boards-thumbnail")
|
(def ^:icon-id boards-thumbnail "boards-thumbnail")
|
||||||
|
|
|
@ -32,17 +32,17 @@
|
||||||
|
|
||||||
(let [level (or level "1")
|
(let [level (or level "1")
|
||||||
tag (dm/str "h" level)
|
tag (dm/str "h" level)
|
||||||
class (dm/str (or class "") " " (stl/css-case :display-typography (= typography t/display)
|
class (dm/str class " " (stl/css-case :display-typography (= typography t/display)
|
||||||
:title-large-typography (= typography t/title-large)
|
:title-large-typography (= typography t/title-large)
|
||||||
:title-medium-typography (= typography t/title-medium)
|
:title-medium-typography (= typography t/title-medium)
|
||||||
:title-small-typography (= typography t/title-small)
|
:title-small-typography (= typography t/title-small)
|
||||||
:headline-large-typography (= typography t/headline-large)
|
:headline-large-typography (= typography t/headline-large)
|
||||||
:headline-medium-typography (= typography t/headline-medium)
|
:headline-medium-typography (= typography t/headline-medium)
|
||||||
:headline-small-typography (= typography t/headline-small)
|
:headline-small-typography (= typography t/headline-small)
|
||||||
:body-large-typography (= typography t/body-large)
|
:body-large-typography (= typography t/body-large)
|
||||||
:body-medium-typography (= typography t/body-medium)
|
:body-medium-typography (= typography t/body-medium)
|
||||||
:body-small-typography (= typography t/body-small)
|
:body-small-typography (= typography t/body-small)
|
||||||
:code-font-typography (= typography t/code-font)))
|
:code-font-typography (= typography t/code-font)))
|
||||||
props (mf/spread-props props {:class class})]
|
props (mf/spread-props props {:class class})]
|
||||||
[:> tag props
|
[:> tag props
|
||||||
children]))
|
children]))
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
[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.ds.foundations.typography.text :refer [text*]]
|
||||||
[app.main.ui.workspace.colorpicker :as colorpicker]
|
[app.main.ui.workspace.colorpicker :as colorpicker]
|
||||||
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector]]
|
[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)
|
[:form {:class (stl/css :form-wrapper)
|
||||||
:on-submit on-submit}
|
:on-submit on-submit}
|
||||||
[:div {:class (stl/css :token-rows)}
|
[: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")
|
(if (= action "edit")
|
||||||
(tr "workspace.token.edit-token")
|
(tr "workspace.token.edit-token")
|
||||||
(tr "workspace.token.create-token" token-type))]
|
(tr "workspace.token.create-token" token-type))]
|
||||||
|
|
||||||
[:div {:class (stl/css :input-row)}
|
[:div {:class (stl/css :input-row)}
|
||||||
;; This should be remove when labeled-imput is modified
|
;; 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"
|
[:& tokens.common/labeled-input {:label "Name"
|
||||||
:error? @name-errors
|
:error? @name-errors
|
||||||
:input-props {:default-value @name-ref
|
: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)}
|
[:div {:class (stl/css :input-row)}
|
||||||
;; This should be remove when labeled-imput is modified
|
;; 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"
|
[:& tokens.common/labeled-input {:label "Value"
|
||||||
:input-props {:default-value @value-ref
|
:input-props {:default-value @value-ref
|
||||||
:on-blur on-update-value
|
: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)}
|
[:div {:class (stl/css :input-row)}
|
||||||
;; This should be remove when labeled-imput is modified
|
;; 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"
|
[:& tokens.common/labeled-input {:label "Description"
|
||||||
:input-props {:default-value @description-ref
|
:input-props {:default-value @description-ref
|
||||||
:on-change on-update-description}}]
|
:on-change on-update-description}}]
|
||||||
|
@ -416,10 +417,12 @@ Token names should only contain letters and digits separated by . characters.")}
|
||||||
(when (= action "edit")
|
(when (= action "edit")
|
||||||
[:> button* {:on-click on-delete-token
|
[:> button* {:on-click on-delete-token
|
||||||
:class (stl/css :delete-btn)
|
:class (stl/css :delete-btn)
|
||||||
|
:type "button"
|
||||||
:icon i/delete
|
:icon i/delete
|
||||||
:variant "secondary"}
|
:variant "secondary"}
|
||||||
(tr "labels.delete")])
|
(tr "labels.delete")])
|
||||||
[:> button* {:on-click on-cancel
|
[:> button* {:on-click on-cancel
|
||||||
|
:type "button"
|
||||||
:variant "secondary"}
|
:variant "secondary"}
|
||||||
(tr "labels.cancel")]
|
(tr "labels.cancel")]
|
||||||
[:> button* {:type "submit"
|
[:> button* {:type "submit"
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
gap: $s-4;
|
gap: $s-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.labeled-input-label {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
padding: $s-4 $s-6;
|
padding: $s-4 $s-6;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
@ -75,3 +79,7 @@
|
||||||
border-radius: $br-4;
|
border-radius: $br-4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-modal-title {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||||
[app.main.ui.workspace.tokens.form :refer [form]]
|
[app.main.ui.workspace.tokens.form :refer [form]]
|
||||||
[app.main.ui.workspace.tokens.modals.themes :as wtmt]
|
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
@ -60,12 +59,6 @@
|
||||||
:selected-token-set-id selected-token-set-id
|
:selected-token-set-id selected-token-set-id
|
||||||
:token-type token-type}]]))
|
:token-type token-type}]]))
|
||||||
|
|
||||||
(mf/defc token-themes-modal
|
|
||||||
{::mf/register modal/components
|
|
||||||
::mf/register-as :tokens/themes}
|
|
||||||
[args]
|
|
||||||
[:& wtmt/modal args])
|
|
||||||
|
|
||||||
;; Modals ----------------------------------------------------------------------
|
;; Modals ----------------------------------------------------------------------
|
||||||
|
|
||||||
(mf/defc boolean-modal
|
(mf/defc boolean-modal
|
||||||
|
|
|
@ -7,36 +7,49 @@
|
||||||
(ns app.main.ui.workspace.tokens.modals.themes
|
(ns app.main.ui.workspace.tokens.modals.themes
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.tokens :as wdt]
|
[app.main.data.tokens :as wdt]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
[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.icons :as i]
|
||||||
[app.main.ui.workspace.tokens.common :refer [labeled-input] :as wtco]
|
[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 :as wts]
|
||||||
[app.main.ui.workspace.tokens.sets-context :as sets-context]
|
[app.main.ui.workspace.tokens.sets-context :as sets-context]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
|
[app.util.i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[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
|
(mf/defc empty-themes
|
||||||
[{:keys [set-state]}]
|
[{:keys [set-state]}]
|
||||||
[:div {:class (stl/css :empty-themes-wrapper)}
|
(let [create-theme
|
||||||
[:div {:class (stl/css :empty-themes-message)}
|
(mf/use-fn
|
||||||
[:h1 "You currently have no themes."]
|
(mf/deps set-state)
|
||||||
[:p "Create your first theme now."]]
|
#(set-state (fn [_] {:type :create-theme})))]
|
||||||
[:div {:class (stl/css :button-footer)}
|
[:div {:class (stl/css :themes-modal-wrapper)}
|
||||||
[:button {:class (stl/css :button-primary)
|
[:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
|
||||||
:on-click #(set-state (fn [_] {:type :create-theme}))}
|
(tr "workspace.token.themes")]
|
||||||
"New theme"]]])
|
[: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
|
(mf/defc switch
|
||||||
[{:keys [selected? name on-change]}]
|
[{:keys [selected? name on-change]}]
|
||||||
|
@ -57,60 +70,195 @@
|
||||||
[{:keys [set-state]}]
|
[{:keys [set-state]}]
|
||||||
(let [active-theme-ids (mf/deref refs/workspace-active-theme-paths)
|
(let [active-theme-ids (mf/deref refs/workspace-active-theme-paths)
|
||||||
themes-groups (mf/deref refs/workspace-token-theme-tree-no-hidden)
|
themes-groups (mf/deref refs/workspace-token-theme-tree-no-hidden)
|
||||||
on-edit-theme (fn [theme e]
|
|
||||||
(dom/prevent-default e)
|
create-theme
|
||||||
(dom/stop-propagation e)
|
(mf/use-fn
|
||||||
(set-state (fn [_] {:type :edit-theme
|
(mf/deps set-state)
|
||||||
:theme-path [(:id theme) (:group theme) (:name theme)]})))]
|
(fn [e]
|
||||||
[:div
|
(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)}
|
[:ul {:class (stl/css :theme-group-wrapper)}
|
||||||
(for [[group themes] themes-groups]
|
(for [[group themes] themes-groups]
|
||||||
[:li {:key (str "token-theme-group" group)}
|
[:li {:key (dm/str "token-theme-group" group)}
|
||||||
(when (seq 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)}
|
[:ul {:class (stl/css :theme-group-rows-wrapper)}
|
||||||
(for [[_ {:keys [group name] :as theme}] themes
|
(for [[_ {:keys [group name] :as theme}] themes
|
||||||
:let [theme-id (ctob/theme-path theme)
|
: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
|
[:li {:key theme-id
|
||||||
:class (stl/css :theme-row)}
|
:class (stl/css :theme-row)}
|
||||||
[:div {:class (stl/css :theme-row-left)}
|
[:div {:class (stl/css :theme-row-left)}
|
||||||
|
|
||||||
|
;; FIREEEEEEEEEE THIS
|
||||||
[:div {:on-click (fn [e]
|
[:div {:on-click (fn [e]
|
||||||
(dom/prevent-default e)
|
(dom/prevent-default e)
|
||||||
(dom/stop-propagation e)
|
(dom/stop-propagation e)
|
||||||
(st/emit! (wdt/toggle-token-theme-active? group name)))}
|
(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)
|
:on-change (constantly nil)
|
||||||
:selected? selected?}]]
|
: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)}
|
[:div {:class (stl/css :theme-row-right)}
|
||||||
(if-let [sets-count (some-> theme :sets seq count)]
|
(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 %)}
|
:variant "secondary"
|
||||||
(str sets-count " sets")
|
:type "button"
|
||||||
chevron-icon]
|
:on-click on-edit-theme}
|
||||||
[:button {:class (stl/css :sets-count-empty-button)
|
[:div {:class (stl/css :label-wrapper)}
|
||||||
:on-click #(on-edit-theme theme %)}
|
[:> text* {:as "span" :typography "body-medium"}
|
||||||
"No sets defined"
|
(tr "workspace.token.num-sets" sets-count)]
|
||||||
chevron-icon])
|
[:> icon* {:id "arrow-right"}]]]
|
||||||
[: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"]]]))
|
|
||||||
|
|
||||||
(mf/defc edit-theme
|
[:> button* {:class (stl/css :sets-count-empty-button)
|
||||||
[{:keys [edit? token-sets theme theme-groups on-back on-submit]}]
|
:type "button"
|
||||||
(let [{:keys [dropdown-open? on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
|
: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)
|
theme-state (mf/use-state theme)
|
||||||
disabled? (-> (:name @theme-state)
|
disabled? (-> (:name @theme-state)
|
||||||
(str/trim)
|
(str/trim)
|
||||||
|
@ -125,9 +273,6 @@
|
||||||
(swap! theme-state #(ctob/toggle-set % set-name))))
|
(swap! theme-state #(ctob/toggle-set % set-name))))
|
||||||
on-change-field (fn [field value]
|
on-change-field (fn [field value]
|
||||||
(swap! theme-state #(assoc % 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
|
on-save-form (mf/use-callback
|
||||||
(mf/deps theme-state on-submit)
|
(mf/deps theme-state on-submit)
|
||||||
(fn [e]
|
(fn [e]
|
||||||
|
@ -138,124 +283,83 @@
|
||||||
(update :description str/trim))]
|
(update :description str/trim))]
|
||||||
(when-not (str/empty? (:name theme))
|
(when-not (str/empty? (:name theme))
|
||||||
(on-submit theme)))
|
(on-submit theme)))
|
||||||
(on-back)))]
|
(on-back)))
|
||||||
[:form {:on-submit on-save-form}
|
close-modal
|
||||||
[:div {:class (stl/css :edit-theme-wrapper)}
|
(mf/use-fn
|
||||||
[:div
|
(fn [e]
|
||||||
[:button {:class (stl/css :back-button)
|
(dom/prevent-default e)
|
||||||
:type "button"
|
(st/emit! (modal/hide))))
|
||||||
: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"]]]]]))
|
|
||||||
|
|
||||||
(mf/defc controlled-edit-theme
|
on-delete-token
|
||||||
[{:keys [state set-state]}]
|
(mf/use-fn
|
||||||
(let [{:keys [theme-path]} @state
|
(mf/deps theme on-back)
|
||||||
[_ theme-group theme-name] theme-path
|
(fn []
|
||||||
token-sets (mf/deref refs/workspace-ordered-token-sets)
|
(st/emit! (wdt/delete-token-theme (:group theme) (:name theme)))
|
||||||
theme (mf/deref (refs/workspace-token-theme theme-group theme-name))
|
(on-back)))]
|
||||||
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)] %))}]))
|
|
||||||
|
|
||||||
(mf/defc create-theme
|
[:div {:class (stl/css :themes-modal-wrapper)}
|
||||||
[{:keys [set-state]}]
|
[:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
|
||||||
(let [token-sets (mf/deref refs/workspace-ordered-token-sets)
|
(tr "workspace.token.edit-theme-title")]
|
||||||
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 %))}]))
|
|
||||||
|
|
||||||
(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)
|
(let [themes (mf/deref refs/workspace-token-themes-no-hidden)
|
||||||
state (mf/use-state (if (empty? themes)
|
state (mf/use-state (if (empty? themes)
|
||||||
{:type :create-theme}
|
{:type :create-theme}
|
||||||
{:type :themes-overview}))
|
{:type :themes-overview}))
|
||||||
set-state (mf/use-callback #(swap! state %))
|
set-state (mf/use-callback #(swap! state %))
|
||||||
title (case (:type @state)
|
|
||||||
:edit-theme "Edit Theme"
|
|
||||||
"Themes")
|
|
||||||
component (case (:type @state)
|
component (case (:type @state)
|
||||||
:empty-themes empty-themes
|
:empty-themes empty-themes
|
||||||
:themes-overview (if (empty? themes) empty-themes themes-overview)
|
:themes-overview (if (empty? themes) empty-themes themes-overview)
|
||||||
:edit-theme controlled-edit-theme
|
:edit-theme controlled-edit-theme
|
||||||
:create-theme create-theme)]
|
:create-theme create-theme)]
|
||||||
[:div
|
[:& component {:state state
|
||||||
[:div {:class (stl/css :modal-title)} title]
|
:set-state set-state}]))
|
||||||
[:div {:class (stl/css :modal-content)}
|
|
||||||
[:& component {:state state
|
|
||||||
:set-state set-state}]]]))
|
|
||||||
|
|
||||||
(mf/defc modal
|
(mf/defc token-themes-modal
|
||||||
{::mf/wrap-props false}
|
{::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)))]
|
(let [handle-close-dialog (mf/use-callback #(st/emit! (modal/hide)))]
|
||||||
[:div {:class (stl/css :modal-overlay)}
|
[:div {:class (stl/css :modal-overlay)}
|
||||||
[:div {:class (stl/css :modal-dialog)}
|
[:div {:class (stl/css :modal-dialog)}
|
||||||
[:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon]
|
[:> icon-button* {:class (stl/css :close-btn)
|
||||||
[:& themes]]]))
|
:on-click handle-close-dialog
|
||||||
|
:aria-label (tr "labels.close")
|
||||||
|
:variant "action"
|
||||||
|
:icon "close"}]
|
||||||
|
[:& themes-modal-body]]]))
|
|
@ -10,10 +10,6 @@
|
||||||
@extend .modal-overlay-base;
|
@extend .modal-overlay-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
|
||||||
border-color: var(--color-background-tertiary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
@extend .modal-container-base;
|
@extend .modal-container-base;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -23,16 +19,43 @@ hr {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-title {
|
.empty-themes-message {
|
||||||
@include headlineMediumTypography;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-block-end: $s-16;
|
|
||||||
color: var(--color-foreground-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
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 {
|
.button-footer {
|
||||||
|
@ -46,60 +69,41 @@ hr {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-primary {
|
|
||||||
@extend .button-primary;
|
|
||||||
padding: $s-6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-secondary {
|
|
||||||
@extend .button-secondary;
|
|
||||||
padding: $s-6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-themes-wrapper {
|
.empty-themes-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
color: var(--color-foreground-secondary);
|
||||||
.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 {
|
.empty-theme-subtitle {
|
||||||
@extend .button-secondary;
|
color: var(--color-foreground-secondary);
|
||||||
padding: $s-6;
|
}
|
||||||
padding-right: $s-8;
|
|
||||||
svg {
|
.empty-theme-title {
|
||||||
margin-right: $s-6;
|
color: var(--color-foreground-primary);
|
||||||
@extend .button-icon;
|
}
|
||||||
stroke: var(--icon-foreground);
|
|
||||||
}
|
.create-theme-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-24;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-btn {
|
.close-btn {
|
||||||
@extend .modal-close-btn-base;
|
position: absolute;
|
||||||
|
top: $s-8;
|
||||||
|
right: $s-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-group-label {
|
.theme-group-label {
|
||||||
display: block;
|
|
||||||
@include headlineMediumTypography;
|
|
||||||
color: var(--color-foreground-secondary);
|
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 {
|
.theme-group-rows-wrapper {
|
||||||
|
@ -127,34 +131,26 @@ hr {
|
||||||
gap: $s-16;
|
gap: $s-16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-name {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
|
||||||
.theme-row-right {
|
.theme-row-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: $s-6;
|
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 {
|
.sets-count-button {
|
||||||
@extend .button-secondary;
|
text-transform: lowercase;
|
||||||
padding: $s-6;
|
padding: $s-6;
|
||||||
padding-left: $s-12;
|
padding-left: $s-12;
|
||||||
svg {
|
}
|
||||||
margin-left: $s-6;
|
|
||||||
@extend .button-icon;
|
.label-wrapper {
|
||||||
stroke: var(--icon-foreground);
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-theme-wrapper {
|
.edit-theme-wrapper {
|
||||||
|
@ -163,12 +159,6 @@ hr {
|
||||||
gap: $s-12;
|
gap: $s-12;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-theme-inputs-wrapper {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 0.6fr 1fr;
|
|
||||||
gap: $s-12;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sets-list-wrapper {
|
.sets-list-wrapper {
|
||||||
border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent);
|
border: 1px solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent);
|
||||||
border-radius: $s-8;
|
border-radius: $s-8;
|
||||||
|
@ -176,57 +166,29 @@ hr {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sets-count-empty-button {
|
.sets-count-empty-button {
|
||||||
@extend .button-secondary;
|
text-transform: lowercase;
|
||||||
padding: $s-6;
|
padding: $s-6;
|
||||||
padding-left: $s-12;
|
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 {
|
.group-input-wrapper {
|
||||||
position: relative;
|
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 {
|
.group-drop-down-button {
|
||||||
@include buttonStyle;
|
@include buttonStyle;
|
||||||
|
color: var(--color-foreground-secondary);
|
||||||
width: $s-24;
|
width: $s-24;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0 $s-6;
|
margin: 0 $s-6;
|
||||||
|
|
||||||
svg {
|
|
||||||
@extend .button-icon-small;
|
|
||||||
transform: rotate(90deg);
|
|
||||||
fill: var(--icon-foreground);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||||
[app.main.ui.components.dropdown-menu :refer [dropdown-menu
|
[app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]]
|
||||||
dropdown-menu-item*]]
|
|
||||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
[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 :as h]
|
||||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
|
@ -173,22 +174,26 @@
|
||||||
{:empty (sort-by :token-key empty)
|
{:empty (sort-by :token-key empty)
|
||||||
:filled (sort-by :token-key filled)}))
|
: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
|
(mf/defc themes-header
|
||||||
[_props]
|
[_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)}
|
[:div {:class (stl/css :themes-wrapper)}
|
||||||
[:span {:class (stl/css :themes-header)} (tr "labels.themes")]
|
[:span {:class (stl/css :themes-header)} (tr "labels.themes")]
|
||||||
[:div {:class (stl/css :theme-select-wrapper)}
|
(if (empty? ordered-themes)
|
||||||
[:& theme-select]
|
[:div {:class (stl/css :empty-theme-wrapper)}
|
||||||
[:& edit-button {:create? (empty? ordered-themes)}]]]))
|
[:> 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
|
(mf/defc add-set-button
|
||||||
[{:keys [on-open]}]
|
[{:keys [on-open]}]
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) KALEIDOS INC
|
// Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
@use "../../ds/typography.scss" as *;
|
||||||
@import "refactor/common-refactor.scss";
|
@import "refactor/common-refactor.scss";
|
||||||
@import "./common.scss";
|
@import "./common.scss";
|
||||||
|
|
||||||
|
@ -37,9 +38,21 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.themes-header {
|
||||||
|
display: block;
|
||||||
|
@include headlineSmallTypography;
|
||||||
|
margin-bottom: $s-8;
|
||||||
|
padding-left: $s-8;
|
||||||
|
color: var(--title-foreground-color);
|
||||||
|
}
|
||||||
|
|
||||||
.themes-wrapper {
|
.themes-wrapper {
|
||||||
|
padding: $s-12 0 0 $s-12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-theme-wrapper {
|
||||||
padding: $s-12;
|
padding: $s-12;
|
||||||
padding-bottom: 0;
|
color: var(--color-foreground-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header {
|
.sidebar-header {
|
||||||
|
@ -168,12 +181,13 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.themes-header {
|
.create-theme-button {
|
||||||
display: block;
|
@include use-typography("body-small");
|
||||||
@include headlineSmallTypography;
|
background-color: transparent;
|
||||||
margin-bottom: $s-8;
|
border: none;
|
||||||
padding-left: $s-8;
|
appearance: none;
|
||||||
color: var(--title-foreground-color);
|
color: var(--color-accent-primary);
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resize-area-horiz {
|
.resize-area-horiz {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.main.ui.workspace.tokens.theme-select
|
(ns app.main.ui.workspace.tokens.theme-select
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
|
@ -14,46 +15,62 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
[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.dom :as dom]
|
||||||
|
[app.util.i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc themes-list
|
(mf/defc themes-list
|
||||||
[{:keys [themes active-theme-paths on-close grouped?]}]
|
[{:keys [themes active-theme-paths on-close grouped?]}]
|
||||||
(when (seq themes)
|
(when (seq themes)
|
||||||
[:ul
|
[:ul {:class (stl/css :theme-options)}
|
||||||
(for [[_ {:keys [group name] :as theme}] themes
|
(for [[_ {:keys [group name] :as theme}] themes
|
||||||
:let [theme-id (ctob/theme-path theme)
|
: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
|
[:li {:key theme-id
|
||||||
|
:role "option"
|
||||||
|
:aria-selected selected?
|
||||||
:class (stl/css-case
|
:class (stl/css-case
|
||||||
:checked-element true
|
:checked-element true
|
||||||
:sub-item grouped?
|
:sub-item grouped?
|
||||||
:is-selected selected?)
|
:is-selected selected?)
|
||||||
:on-click (fn [e]
|
:on-click select-theme}
|
||||||
(dom/stop-propagation e)
|
[:> text* {:as "span" :typography "body-small" :class (stl/css :label)} name]
|
||||||
(st/emit! (wdt/toggle-token-theme-active? group name))
|
[:> icon* {:id i/tick
|
||||||
(on-close))}
|
:aria-hidden true
|
||||||
[:span {:class (stl/css :label)} name]
|
:class (stl/css-case :check-icon true
|
||||||
[:span {:class (stl/css :check-icon)} i/tick]])]))
|
:check-icon-visible selected?)}]])]))
|
||||||
|
|
||||||
(mf/defc theme-options
|
(mf/defc theme-options
|
||||||
[{:keys [active-theme-paths themes on-close]}]
|
[{:keys [active-theme-paths themes on-close]}]
|
||||||
[:ul
|
(let []
|
||||||
(for [[group themes] themes]
|
(let [on-edit-click #(modal/show! :tokens/themes {})]
|
||||||
[:li {:key group}
|
[:ul {:class (stl/css :theme-options :custom-select-dropdown)
|
||||||
(when (seq group)
|
:role "listbox"}
|
||||||
[:span {:class (stl/css :group)} group])
|
(for [[group themes] themes]
|
||||||
[:& themes-list {:themes themes
|
[:li {:key group
|
||||||
:active-theme-paths active-theme-paths
|
:aria-labelledby (dm/str group "-label")
|
||||||
:on-close on-close
|
:role "group"}
|
||||||
:grouped? true}]])
|
(when (seq group)
|
||||||
[:li {:class (stl/css-case :checked-element true
|
[:> text* {:as "span" :typography "headline-small" :class (stl/css :group) :id (dm/str group "-label")} group])
|
||||||
:checked-element-button true)
|
[:& themes-list {:themes themes
|
||||||
:on-click #(modal/show! :tokens/themes {})}
|
:active-theme-paths active-theme-paths
|
||||||
[:span "Edit themes"]
|
:on-close on-close
|
||||||
[:span {:class (stl/css :icon)} i/arrow]]])
|
: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
|
(mf/defc theme-select
|
||||||
[{:keys []}]
|
[{:keys []}]
|
||||||
|
@ -64,11 +81,11 @@
|
||||||
|
|
||||||
;; Data
|
;; Data
|
||||||
current-label (cond
|
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)
|
(= active-themes-count 1) (some->> (first active-theme-paths)
|
||||||
(ctob/split-token-theme-path)
|
(ctob/split-token-theme-path)
|
||||||
(str/join " / "))
|
(str/join " / "))
|
||||||
:else "No theme active")
|
:else (tr "workspace.token.no-active-theme"))
|
||||||
|
|
||||||
;; State
|
;; State
|
||||||
state* (mf/use-state
|
state* (mf/use-state
|
||||||
|
@ -81,13 +98,20 @@
|
||||||
dropdown-element* (mf/use-ref nil)
|
dropdown-element* (mf/use-ref nil)
|
||||||
on-close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false))
|
on-close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false))
|
||||||
on-open-dropdown (mf/use-fn #(swap! state* assoc :is-open? true))]
|
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
|
[:div {:on-click on-open-dropdown
|
||||||
|
:aria-expanded is-open?
|
||||||
|
:aria-haspopup "listbox"
|
||||||
|
:tab-index "0"
|
||||||
|
:role "combobox"
|
||||||
:class (stl/css :custom-select)}
|
:class (stl/css :custom-select)}
|
||||||
[:span {:class (stl/css :current-label)} current-label]
|
[:> text* {:as "span" :typography "body-small" :class (stl/css :current-label)}
|
||||||
[:span {:class (stl/css :dropdown-button)} i/arrow]
|
current-label]
|
||||||
[:& dropdown {:show is-open? :on-close on-close-dropdown}
|
[:> icon* {:id i/arrow-down :class (stl/css :dropdown-button) :aria-hidden true}]
|
||||||
[:div {:ref dropdown-element*
|
[:& dropdown {:show is-open?
|
||||||
:class (stl/css :custom-select-dropdown)}
|
:on-close on-close-dropdown
|
||||||
[:& theme-options {:active-theme-paths active-theme-paths
|
:ref dropdown-element*}
|
||||||
:themes themes
|
[:& theme-options {:active-theme-paths active-theme-paths
|
||||||
:on-close on-close-dropdown}]]]]))
|
:themes themes
|
||||||
|
:on-close on-close-dropdown}]]]))
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
@import "refactor/common-refactor.scss";
|
@import "refactor/common-refactor.scss";
|
||||||
|
|
||||||
.custom-select {
|
.custom-select {
|
||||||
--border-color: var(--menu-background-color);
|
--custom-select-border-color: var(--menu-background-color);
|
||||||
--bg-color: var(--menu-background-color);
|
--custom-select-bg-color: var(--menu-background-color);
|
||||||
--icon-color: var(--icon-foreground);
|
--custom-select-icon-color: var(--color-foreground-secondary);
|
||||||
--text-color: var(--menu-foreground-color);
|
--custom-select-text-color: var(--menu-foreground-color);
|
||||||
@extend .new-scrollbar;
|
@extend .new-scrollbar;
|
||||||
@include bodySmallTypography;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
|
@ -22,74 +21,60 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: $s-8;
|
padding: $s-8;
|
||||||
border-radius: $br-8;
|
border-radius: $br-8;
|
||||||
background-color: var(--bg-color);
|
background-color: var(--custom-select-bg-color);
|
||||||
border: $s-1 solid var(--border-color);
|
border: $s-1 solid var(--custom-select-border-color);
|
||||||
color: var(--text-color);
|
color: var(--custom-select-text-color);
|
||||||
cursor: pointer;
|
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 {
|
&:hover {
|
||||||
--bg-color: var(--menu-background-color-hover);
|
--custom-select-bg-color: var(--menu-background-color-hover);
|
||||||
--border-color: var(--menu-background-color);
|
--custom-select-border-color: var(--menu-background-color);
|
||||||
--icon-color: var(--menu-foreground-color-hover);
|
--custom-select-icon-color: var(--menu-foreground-color-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
--bg-color: var(--menu-background-color-focus);
|
--custom-select-bg-color: var(--menu-background-color-focus);
|
||||||
--border-color: var(--menu-background-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 {
|
.disabled {
|
||||||
--bg-color: var(--menu-background-color-disabled);
|
--custom-select-bg-color: var(--menu-background-color-disabled);
|
||||||
--border-color: var(--menu-border-color-disabled);
|
--custom-select-border-color: var(--menu-border-color-disabled);
|
||||||
--icon-color: var(--menu-foreground-color-disabled);
|
--custom-select-icon-color: var(--menu-foreground-color-disabled);
|
||||||
--text-color: var(--menu-foreground-color-disabled);
|
--custom-select-text-color: var(--menu-foreground-color-disabled);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-button {
|
.dropdown-button {
|
||||||
@include flexCenter;
|
@include flexCenter;
|
||||||
svg {
|
color: var(--color-foreground-secondary);
|
||||||
@extend .button-icon-small;
|
|
||||||
transform: rotate(90deg);
|
|
||||||
stroke: var(--icon-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-icon {
|
.current-icon {
|
||||||
@include flexCenter;
|
@include flexCenter;
|
||||||
width: $s-24;
|
width: $s-24;
|
||||||
padding-right: $s-4;
|
padding-right: $s-4;
|
||||||
svg {
|
|
||||||
@extend .button-icon-small;
|
|
||||||
stroke: var(--icon-foreground);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select-dropdown {
|
.custom-select-dropdown {
|
||||||
@extend .dropdown-wrapper;
|
@extend .dropdown-wrapper;
|
||||||
.separator {
|
}
|
||||||
margin: 0;
|
|
||||||
height: $s-12;
|
.separator {
|
||||||
border-block-start: $s-1 solid var(--dropdown-separator-color);
|
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"] {
|
.custom-select-dropdown[data-direction="up"] {
|
||||||
|
@ -109,59 +94,31 @@
|
||||||
padding-right: 0;
|
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 {
|
.checked-element {
|
||||||
@extend .dropdown-element-base;
|
@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 {
|
&.is-selected {
|
||||||
color: var(--menu-foreground-color);
|
color: var(--menu-foreground-color);
|
||||||
.check-icon svg {
|
|
||||||
stroke: var(--menu-foreground-color);
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&.disabled {
|
&.disabled {
|
||||||
display: none;
|
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 {
|
.current-label {
|
||||||
@include textEllipsis;
|
@include textEllipsis;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6163,4 +6163,72 @@ msgstr "Resolved value: "
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
||||||
msgid "workspace.token.original-value"
|
msgid "workspace.token.original-value"
|
||||||
msgstr "Original value: "
|
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"
|
|
@ -6150,4 +6150,72 @@ msgstr "Valor resuelto: "
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
||||||
msgid "workspace.token.original-value"
|
msgid "workspace.token.original-value"
|
||||||
msgstr "Valor original: "
|
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"
|
Loading…
Add table
Add a link
Reference in a new issue