mirror of
https://github.com/penpot/penpot.git
synced 2026-08-29 08:08:46 +00:00
🎉 Layout updates
This commit is contained in:
parent
d18e8b9221
commit
d6896664a2
@ -36,7 +36,8 @@
|
||||
[app.main.ui.context :as ctx]
|
||||
[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 :as i]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]]
|
||||
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
||||
[app.main.ui.ds.product.empty-state :refer [empty-state*]]
|
||||
[app.main.ui.hooks :as h]
|
||||
@ -130,43 +131,54 @@
|
||||
|
||||
(mf/defc library-description*
|
||||
{::mf/private true}
|
||||
[{:keys [summary]}]
|
||||
[{:keys [summary hint-name]}]
|
||||
(let [components-count (get summary :components)
|
||||
graphics-count (get summary :graphics)
|
||||
typography-count (get summary :typographies)
|
||||
colors-count (get summary :colors)
|
||||
tokens-count (get summary :tokens)
|
||||
token-sets-count (get summary :token-sets)
|
||||
token-themes-count (get summary :token-themes)]
|
||||
token-themes-count (get summary :token-themes)
|
||||
|
||||
elements-line
|
||||
(str/join " · "
|
||||
(cond-> []
|
||||
(pos? components-count)
|
||||
(conj (tr "workspace.libraries.components" (c components-count)))
|
||||
|
||||
(pos? graphics-count)
|
||||
(conj (tr "workspace.libraries.graphics" (c graphics-count)))
|
||||
|
||||
(pos? colors-count)
|
||||
(conj (tr "workspace.libraries.colors" (c colors-count)))
|
||||
|
||||
(pos? typography-count)
|
||||
(conj (tr "workspace.libraries.typography" (c typography-count)))))
|
||||
|
||||
tokens-line
|
||||
(str/join " · "
|
||||
(cond-> []
|
||||
(pos? tokens-count)
|
||||
(conj (tr "workspace.libraries.tokens" (c tokens-count)))
|
||||
|
||||
(pos? token-sets-count)
|
||||
(conj (tr "workspace.libraries.token-sets" (c token-sets-count)))
|
||||
|
||||
(pos? token-themes-count)
|
||||
(conj (tr "workspace.libraries.token-themes" (c token-themes-count)))))]
|
||||
|
||||
[:*
|
||||
(when (pos? components-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.components" (c components-count))])
|
||||
(when-not (str/empty? elements-line)
|
||||
[:li {:class (stl/css :element-count-line)} elements-line])
|
||||
|
||||
(when (pos? graphics-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.graphics" (c graphics-count))])
|
||||
(when-not (str/empty? tokens-line)
|
||||
[:li {:class (stl/css :element-count-line)} tokens-line])
|
||||
|
||||
(when (pos? colors-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.colors" (c colors-count))])
|
||||
|
||||
(when (pos? typography-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.typography" (c typography-count))])
|
||||
|
||||
(when (pos? tokens-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.tokens" (c tokens-count))])
|
||||
|
||||
(when (pos? token-sets-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.token-sets" (c token-sets-count))])
|
||||
|
||||
(when (pos? token-themes-count)
|
||||
[:li {:class (stl/css :element-count)}
|
||||
(tr "workspace.libraries.token-themes" (c token-themes-count))])]))
|
||||
(when hint-name
|
||||
[:li {:class (stl/css :hint-line)}
|
||||
"(" (tr "workspace.libraries.connected-through") " "
|
||||
[:span {:class (stl/css :hint-library-name)} hint-name ]
|
||||
")"])]))
|
||||
|
||||
(mf/defc sample-library-entry*
|
||||
{::mf/private true}
|
||||
@ -221,16 +233,11 @@
|
||||
|
||||
(mf/defc libraries-tab*
|
||||
{::mf/private true}
|
||||
[{:keys [is-shared linked-libraries shared-libraries]}]
|
||||
[{:keys [linked-libraries shared-libraries]}]
|
||||
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||
search-term* (mf/use-state "")
|
||||
search-term (deref search-term*)
|
||||
|
||||
;; The summary of the current/local library
|
||||
;; NOTE: we only need a snapshot of current library
|
||||
local-library (deref refs/workspace-data)
|
||||
summary (get-library-summary local-library)
|
||||
empty-library? (empty-library? summary)
|
||||
|
||||
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
||||
dependencies (mf/with-memo [shared-libraries]
|
||||
@ -253,24 +260,13 @@
|
||||
(when shared-libraries
|
||||
(->> (vals shared-libraries)
|
||||
(remove #(= (:id %) file-id))
|
||||
(remove #(contains? linked-libraries (:id %)))
|
||||
(filter #(matches-search (:name %) search-term))
|
||||
(map #(assoc % :connected-to (find-connected-to (:id %))))
|
||||
(map #(assoc % :connected-to-names (->> (:connected-to %)
|
||||
(keep library-names))))
|
||||
(map #(assoc % :linked? (contains? linked-libraries (:id %))))
|
||||
(sort-by (comp str/lower :name)))))
|
||||
|
||||
linked-libraries
|
||||
(mf/with-memo [linked-libraries find-connected-to library-names]
|
||||
(->> (vals linked-libraries)
|
||||
(map #(assoc % :connected-to (find-connected-to (:id %))))
|
||||
(map #(assoc % :connected-to-names (->> (:connected-to %)
|
||||
(keep library-names))))
|
||||
(sort-by (comp str/lower :name))))
|
||||
|
||||
linked-libraries-ids
|
||||
(mf/with-memo [linked-libraries]
|
||||
(into #{} d/xf:map-id linked-libraries))
|
||||
|
||||
importing*
|
||||
(mf/use-state nil)
|
||||
@ -295,166 +291,9 @@
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(reset! selected library-id)
|
||||
(st/emit! (dwl/link-file-to-library file-id library-id)))))
|
||||
|
||||
unlink-library
|
||||
(mf/use-fn
|
||||
(mf/deps file-id local-library)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(when (= library-id @selected)
|
||||
(reset! selected :file))
|
||||
(st/emit! (dwl/unlink-file-from-library file-id library-id)
|
||||
(dwl/sync-file file-id library-id))
|
||||
;; When the unlinked library is the current tokens source,
|
||||
;; we must reset it to the local library.
|
||||
(when (cfo/tokens-source? local-library library-id)
|
||||
(st/emit! (dwtl/set-tokens-source (:id local-library)))))))
|
||||
|
||||
import-tokens
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(st/emit! (modal/show
|
||||
:tokens/import-from-library {:file-id file-id
|
||||
:library-id library-id})))))
|
||||
|
||||
set-as-tokens-source
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(st/emit! (dwtl/set-tokens-source library-id)))))
|
||||
|
||||
on-delete-accept
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
#(st/emit! (dwl/set-file-shared file-id false)
|
||||
(modal/show :libraries-dialog {:file-id file-id})))
|
||||
|
||||
on-delete-cancel
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
#(st/emit! (modal/show :libraries-dialog {:file-id file-id})))
|
||||
|
||||
publish
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [input-node (dom/get-target event)
|
||||
publish-library #(st/emit! (dwl/set-file-shared file-id true))
|
||||
cancel-publish #(st/emit! (modal/show :libraries-dialog {:file-id file-id}))]
|
||||
(if empty-library?
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.publish-empty-library.title")
|
||||
:message (tr "modals.publish-empty-library.message")
|
||||
:accept-label (tr "modals.publish-empty-library.accept")
|
||||
:on-accept publish-library
|
||||
:on-cancel cancel-publish}))
|
||||
(publish-library))
|
||||
(dom/blur! input-node))))
|
||||
|
||||
unpublish
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [_]
|
||||
(st/emit! (modal/show
|
||||
{:type :delete-shared-libraries
|
||||
:ids #{file-id}
|
||||
:origin :unpublish
|
||||
:on-accept on-delete-accept
|
||||
:on-cancel on-delete-cancel
|
||||
:count-libraries 1}))))]
|
||||
(st/emit! (dwl/link-file-to-library file-id library-id)))))]
|
||||
|
||||
[:div {:class (stl/css :libraries-content)}
|
||||
[:div {:class (stl/css :lib-section)}
|
||||
[:> title-bar* {:collapsable false
|
||||
:title (tr "workspace.libraries.in-this-file")
|
||||
:class (stl/css :title-spacing-lib)}]
|
||||
[:div {:class (stl/css :section-list)}
|
||||
|
||||
[:div {:class (stl/css :section-list-publish)}
|
||||
[:div {:class (stl/css :item-content)}
|
||||
[:div {:class (stl/css :item-title)} (tr "workspace.libraries.file-library")]
|
||||
[:ul {:class (stl/css :item-contents)}
|
||||
[:> library-description* {:summary summary}]]
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(if (cfo/tokens-source? local-library (:id local-library))
|
||||
[:div (tr "workspace.libraries.tokens-source")]
|
||||
(when (not= (cfo/get-tokens-source local-library) (:id local-library))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str (:id local-library))
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")])))]
|
||||
|
||||
(if ^boolean is-shared
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:on-click unpublish}
|
||||
(tr "common.unpublish")]
|
||||
|
||||
[:> button* {:variant "primary"
|
||||
:type "button"
|
||||
:on-click publish}
|
||||
(tr "common.publish")])]
|
||||
|
||||
(for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries]
|
||||
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)
|
||||
has-tokens? (and (has-tokens? library)
|
||||
(contains? cf/flags :token-import-from-library))]
|
||||
[:div {:class (stl/css :section-list-item)
|
||||
:key (dm/str id)
|
||||
:data-testid "library-item"}
|
||||
[:div {:class (stl/css :item-content)}
|
||||
[:div {:class (stl/css-case :item-name true
|
||||
:item-name-short has-tokens?)} name]
|
||||
[:ul {:class (stl/css :item-contents)}
|
||||
(let [summary (get-library-summary data)]
|
||||
[:*
|
||||
[:> library-description* {:summary summary}]
|
||||
(when (seq connected-to)
|
||||
[:div {:class (stl/css :connected-to-wrapper)}
|
||||
[:span "(" (tr "workspace.libraries.connected-to") " "]
|
||||
[:span {:class (stl/css :connected-to-values)} (str/join ", " connected-to-names)]
|
||||
[:span ")"]])])]
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(when (cfo/tokens-source? local-library id)
|
||||
[:div (tr "workspace.libraries.tokens-source")]))]
|
||||
|
||||
[:div {:class (stl/css :library-actions)}
|
||||
(if (contains? cf/flags :token-lib-sync)
|
||||
(when (and (cfo/tokens-provider? (:data library))
|
||||
(not (cfo/tokens-source? local-library id)))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str id)
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")])
|
||||
(when ^boolean has-tokens?
|
||||
[:> icon-button*
|
||||
{:type "button"
|
||||
:aria-label (tr "workspace.tokens.import-tokens")
|
||||
:icon i/import-export
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:on-click import-tokens}]))
|
||||
|
||||
[:> icon-button* {:type "button"
|
||||
:aria-label (tr "workspace.libraries.unlink-library-btn")
|
||||
:icon i/detach
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:disabled disabled?
|
||||
:on-click unlink-library}]]]))]]
|
||||
|
||||
[:div {:class (stl/css :shared-section)}
|
||||
[:> title-bar* {:collapsable false
|
||||
:title (tr "workspace.libraries.shared-libraries")
|
||||
@ -466,7 +305,7 @@
|
||||
|
||||
(if (seq shared-libraries)
|
||||
[:div {:class (stl/css :section-list-shared)}
|
||||
(for [{:keys [id name] :as library} shared-libraries]
|
||||
(for [{:keys [id name linked?] :as library} shared-libraries]
|
||||
[:div {:class (stl/css :section-list-item)
|
||||
:key (dm/str id)
|
||||
:data-testid "library-item"}
|
||||
@ -477,12 +316,19 @@
|
||||
(adapt-backend-summary))]
|
||||
[:> library-description* {:summary summary}])]]
|
||||
|
||||
[:> icon-button* {:class (stl/css :item-button-shared)
|
||||
:variant "secondary"
|
||||
:data-library-id (dm/str id)
|
||||
:icon "add"
|
||||
:aria-label (tr "workspace.libraries.shared-library-btn")
|
||||
:on-click link-library}]])]
|
||||
(if ^boolean linked?
|
||||
[:> text* {:class (stl/css :shared-library-added)
|
||||
:as "span"
|
||||
:typography "body-medium"}
|
||||
[:> icon* {:icon-id i/tick
|
||||
:class (stl/css :shared-library-added-icon)}]
|
||||
(tr "workspace.libraries.shared-library-added")]
|
||||
[:> icon-button* {:class (stl/css :item-button-shared)
|
||||
:variant "secondary"
|
||||
:data-library-id (dm/str id)
|
||||
:icon "add"
|
||||
:aria-label (tr "workspace.libraries.shared-library-btn")
|
||||
:on-click link-library}])])]
|
||||
|
||||
(when (empty? shared-libraries)
|
||||
[:div {:class (stl/css :section-list-empty)}
|
||||
@ -509,6 +355,248 @@
|
||||
:else
|
||||
(tr "workspace.libraries.no-matches-for" search-term))]))]]))
|
||||
|
||||
(mf/defc file-tab*
|
||||
{::mf/private true}
|
||||
[{:keys [is-shared linked-libraries shared-libraries on-change-tab]}]
|
||||
(let [file-id (mf/use-ctx ctx/current-file-id)
|
||||
|
||||
;; The summary of the current/local library
|
||||
;; NOTE: we only need a snapshot of current library
|
||||
local-library (deref refs/workspace-data)
|
||||
summary (get-library-summary local-library)
|
||||
empty-library? (empty-library? summary)
|
||||
|
||||
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
||||
dependencies (mf/with-memo [shared-libraries]
|
||||
(into {} (map (juxt :id :library-file-ids) (vals shared-libraries))))
|
||||
|
||||
library-names (mf/with-memo [shared-libraries]
|
||||
(into {} (map (fn [{:keys [id name]}]
|
||||
[id name])
|
||||
(vals shared-libraries))))
|
||||
|
||||
find-connected-to
|
||||
(mf/use-fn
|
||||
(mf/deps dependencies)
|
||||
(fn [library-id]
|
||||
(->> dependencies
|
||||
(keep (fn [[k v]] (when (contains? v library-id) k))))))
|
||||
|
||||
linked-libraries
|
||||
(mf/with-memo [linked-libraries find-connected-to library-names]
|
||||
(let [libs
|
||||
(->> (vals linked-libraries)
|
||||
(map #(assoc % :connected-to (find-connected-to (:id %)))))
|
||||
|
||||
linked-ids
|
||||
(into #{} (map :id) libs)
|
||||
|
||||
sort-by-name
|
||||
(partial sort-by (comp str/lower :name))
|
||||
|
||||
parent-id
|
||||
(fn [{:keys [connected-to]}]
|
||||
(first (filter linked-ids connected-to)))
|
||||
|
||||
nested-by-parent
|
||||
(->> libs
|
||||
(filter parent-id)
|
||||
(map #(assoc %
|
||||
:nested? true
|
||||
:parent-name (library-names (parent-id %))))
|
||||
(group-by parent-id)
|
||||
(d/mapm (fn [_ v] (sort-by-name v))))]
|
||||
|
||||
(->> libs
|
||||
(remove parent-id)
|
||||
(map #(assoc % :nested? false))
|
||||
(sort-by-name)
|
||||
(mapcat (fn [{:keys [id] :as library}]
|
||||
(cons library (get nested-by-parent id [])))))))
|
||||
|
||||
linked-libraries-ids
|
||||
(mf/with-memo [linked-libraries]
|
||||
(into #{} d/xf:map-id linked-libraries))
|
||||
|
||||
unlink-library
|
||||
(mf/use-fn
|
||||
(mf/deps file-id local-library)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(when (= library-id @selected)
|
||||
(reset! selected :file))
|
||||
(st/emit! (dwl/unlink-file-from-library file-id library-id)
|
||||
(dwl/sync-file file-id library-id))
|
||||
;; When the unlinked library is the current tokens source,
|
||||
;; we must reset it to the local library.
|
||||
(when (cfo/tokens-source? local-library library-id)
|
||||
(st/emit! (dwtl/set-tokens-source (:id local-library)))))))
|
||||
|
||||
import-tokens
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(st/emit! (modal/show
|
||||
:tokens/import-from-library {:file-id file-id
|
||||
:library-id library-id})))))
|
||||
|
||||
set-as-tokens-source
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(uuid/parse))]
|
||||
(st/emit! (dwtl/set-tokens-source library-id)))))
|
||||
|
||||
on-delete-accept
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
#(st/emit! (dwl/set-file-shared file-id false)
|
||||
(modal/show :libraries-dialog {:file-id file-id})))
|
||||
|
||||
on-delete-cancel
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
#(st/emit! (modal/show :libraries-dialog {:file-id file-id})))
|
||||
|
||||
publish
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [input-node (dom/get-target event)
|
||||
publish-library #(st/emit! (dwl/set-file-shared file-id true))
|
||||
cancel-publish #(st/emit! (modal/show :libraries-dialog {:file-id file-id}))]
|
||||
(if empty-library?
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.publish-empty-library.title")
|
||||
:message (tr "modals.publish-empty-library.message")
|
||||
:accept-label (tr "modals.publish-empty-library.accept")
|
||||
:on-accept publish-library
|
||||
:on-cancel cancel-publish}))
|
||||
(publish-library))
|
||||
(dom/blur! input-node))))
|
||||
|
||||
unpublish
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [_]
|
||||
(st/emit! (modal/show
|
||||
{:type :delete-shared-libraries
|
||||
:ids #{file-id}
|
||||
:origin :unpublish
|
||||
:on-accept on-delete-accept
|
||||
:on-cancel on-delete-cancel
|
||||
:count-libraries 1}))))
|
||||
|
||||
go-to-shared
|
||||
(mf/use-fn
|
||||
(mf/deps on-change-tab)
|
||||
(fn [_]
|
||||
(on-change-tab "libraries")))]
|
||||
|
||||
[:div {:class (stl/css :lib-section)}
|
||||
[:> title-bar* {:collapsable false
|
||||
:title "ASSETS IN THIS FILE"
|
||||
:class (stl/css :title-spacing-lib)}]
|
||||
[:div {:class (stl/css :section-list)}
|
||||
[:div {:class (stl/css :section-list-publish)}
|
||||
[:div {:class (stl/css :item-content)}
|
||||
[:div {:class (stl/css :item-title)} (tr "workspace.libraries.file-library")]
|
||||
[:ul {:class (stl/css :item-contents)}
|
||||
[:> library-description* {:summary summary}]]
|
||||
]
|
||||
(when (and (contains? cf/flags :token-lib-sync)
|
||||
(cfo/tokens-source? local-library (:id local-library)))
|
||||
[:> text* {:class (stl/css :tokens-source-label)
|
||||
:as "span"
|
||||
:typography "body-medium"}
|
||||
(tr "workspace.libraries.tokens-source")])
|
||||
(when (contains? cf/flags :token-lib-sync)
|
||||
(when (not= (cfo/get-tokens-source local-library) (:id local-library))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str (:id local-library))
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")]))
|
||||
|
||||
(if ^boolean is-shared
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:on-click unpublish}
|
||||
(tr "common.unpublish")]
|
||||
|
||||
[:> button* {:variant "primary"
|
||||
:type "button"
|
||||
:on-click publish}
|
||||
(tr "common.publish")])]
|
||||
|
||||
[:div {:class (stl/css :section-list-linked)}
|
||||
[:> title-bar* {:collapsable false
|
||||
:title (tr "workspace.libraries.connected-libraries")
|
||||
:class (stl/css :title-spacing-lib)
|
||||
:title-class (stl/css :connected-libraries-title)}]
|
||||
(if (seq linked-libraries)
|
||||
(for [{:keys [id name data connected-to nested? parent-name] :as library} linked-libraries]
|
||||
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)
|
||||
has-tokens? (and (has-tokens? library)
|
||||
(contains? cf/flags :token-import-from-library))]
|
||||
[:div {:class (stl/css-case :section-list-item true
|
||||
:section-list-item-nested nested?)
|
||||
:key (dm/str id)
|
||||
:data-testid "library-item"}
|
||||
[:div {:class (stl/css :item-content)}
|
||||
[:div {:class (stl/css-case :item-name true
|
||||
:item-name-short has-tokens?)} name]
|
||||
[:ul {:class (stl/css :item-contents)}
|
||||
(let [summary (get-library-summary data)]
|
||||
[:> library-description* {:summary summary :hint-name parent-name}])]]
|
||||
|
||||
[:div {:class (stl/css :library-actions)}
|
||||
(when (and (cfo/tokens-source? local-library id) (contains? cf/flags :token-lib-sync))
|
||||
[:> text* {:class (stl/css :tokens-source-label)
|
||||
:as "span"
|
||||
:typography "body-medium"}
|
||||
(tr "workspace.libraries.tokens-source")])
|
||||
(if (contains? cf/flags :token-lib-sync)
|
||||
(when (and (cfo/tokens-provider? (:data library))
|
||||
(not (cfo/tokens-source? local-library id)))
|
||||
[:> button* {:variant "secondary"
|
||||
:type "button"
|
||||
:data-library-id (dm/str id)
|
||||
:on-click set-as-tokens-source}
|
||||
(tr "workspace.libraries.set-as-tokens-source")])
|
||||
(when ^boolean has-tokens?
|
||||
[:> icon-button*
|
||||
{:type "button"
|
||||
:aria-label (tr "workspace.tokens.import-tokens")
|
||||
:icon i/import-export
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:on-click import-tokens}]))
|
||||
|
||||
[:> icon-button* {:type "button"
|
||||
:aria-label (tr "workspace.libraries.unlink-library-btn")
|
||||
:icon i/detach
|
||||
:data-library-id (dm/str id)
|
||||
:variant "secondary"
|
||||
:disabled disabled?
|
||||
:on-click unlink-library}]]]))
|
||||
[:div {:class (stl/css :shared-libraries-empty)}
|
||||
[:> text* {:class (stl/css :empty-libraries-text)
|
||||
:as "span"
|
||||
:typography "body-small"}
|
||||
(tr "workspace.libraries.empty.no-connected-libraries")]
|
||||
[:button {:class (stl/css :go-to-shared-button)
|
||||
:on-click go-to-shared}
|
||||
"Add a shared library"]])]]]))
|
||||
|
||||
|
||||
(defn- extract-assets
|
||||
[file-data library summary?]
|
||||
(let [exceeded (volatile! {:components false
|
||||
@ -726,7 +814,7 @@
|
||||
(modal/hide!)))
|
||||
|
||||
selected-tab*
|
||||
(mf/use-state #(d/nilv starting-tab "libraries"))
|
||||
(mf/use-state #(d/nilv starting-tab "file"))
|
||||
|
||||
selected-tab
|
||||
(deref selected-tab*)
|
||||
@ -736,7 +824,9 @@
|
||||
|
||||
tabs
|
||||
(mf/with-memo []
|
||||
[{:label (tr "workspace.libraries.libraries")
|
||||
[{:label "This file"
|
||||
:id "file"}
|
||||
{:label (tr "workspace.libraries.libraries")
|
||||
:id "libraries"}
|
||||
{:label (tr "workspace.libraries.updates")
|
||||
:id "updates"}])]
|
||||
@ -760,10 +850,14 @@
|
||||
:selected selected-tab
|
||||
:on-change on-change-tab}
|
||||
(case selected-tab
|
||||
"file"
|
||||
[:> file-tab* {:is-shared shared?
|
||||
:on-change-tab on-change-tab
|
||||
:linked-libraries linked-libraries
|
||||
:shared-libraries shared-libraries}]
|
||||
"libraries"
|
||||
[:> libraries-tab*
|
||||
{:is-shared shared?
|
||||
:linked-libraries linked-libraries
|
||||
{:linked-libraries linked-libraries
|
||||
:shared-libraries shared-libraries}]
|
||||
|
||||
"updates"
|
||||
|
||||
@ -49,7 +49,13 @@
|
||||
}
|
||||
|
||||
// Tabs content
|
||||
.libraries-content,
|
||||
.libraries-content {
|
||||
display: grid;
|
||||
gap: var(--sp-xxxl);
|
||||
max-height: $sz-400;
|
||||
padding-block-start: var(--sp-l);
|
||||
}
|
||||
|
||||
.updates-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@ -75,6 +81,10 @@
|
||||
margin: 0 0 0 calc(-1 * var(--sp-s));
|
||||
}
|
||||
|
||||
.connected-libraries-title {
|
||||
@include t.use-typography("headline-small");
|
||||
}
|
||||
|
||||
.section-list,
|
||||
.section-list-shared {
|
||||
display: grid;
|
||||
@ -87,6 +97,7 @@
|
||||
%section-list-item-placeholder {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
gap: var(--sp-s);
|
||||
border: $b-1 solid var(--color-background-quaternary);
|
||||
padding: var(--sp-s) var(--sp-s) var(--sp-m) var(--sp-m);
|
||||
@ -96,11 +107,18 @@
|
||||
.section-list-publish {
|
||||
@extend %section-list-item-placeholder;
|
||||
|
||||
grid-template-columns: 1fr auto auto;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.section-list-item {
|
||||
@extend %section-list-item-placeholder;
|
||||
|
||||
padding: var(--sp-m);
|
||||
}
|
||||
|
||||
.section-list-item-nested {
|
||||
margin-inline-start: var(--sp-l);
|
||||
}
|
||||
|
||||
.section-list-item-double-icon {
|
||||
@ -130,6 +148,13 @@
|
||||
color: var(--title-foreground-color);
|
||||
}
|
||||
|
||||
.section-list-linked {
|
||||
display: grid;
|
||||
grid-auto-rows: min-content;
|
||||
gap: var(--sp-s);
|
||||
max-height: px2rem(320);
|
||||
}
|
||||
|
||||
// empty state
|
||||
.section-list-empty {
|
||||
display: grid;
|
||||
@ -141,6 +166,23 @@
|
||||
margin-block: var(--sp-l);
|
||||
}
|
||||
|
||||
.shared-libraries-empty {
|
||||
border: $b-1 solid var(--color-background-quaternary);
|
||||
padding: px2rem(40) var(--sp-s);
|
||||
border-radius: $br-8;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
justify-items: center;
|
||||
gap: var(--sp-m);
|
||||
text-align: center;
|
||||
height: fit-content;
|
||||
margin-block: var(--sp-l);
|
||||
}
|
||||
|
||||
.empty-libraries-text {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
// Update library tab
|
||||
.libraries-updates-see-all {
|
||||
background: unset;
|
||||
@ -246,7 +288,7 @@
|
||||
|
||||
color: var(--library-content-foreground-color);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -255,23 +297,34 @@
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.element-count {
|
||||
white-space: nowrap;
|
||||
.element-count-line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: var(--sp-xs);
|
||||
|
||||
&:not(:last-child)::after {
|
||||
content: "·";
|
||||
margin-inline: var(--sp-xs);
|
||||
&::before {
|
||||
content: "•";
|
||||
}
|
||||
}
|
||||
|
||||
.connected-to-wrapper {
|
||||
display: block;
|
||||
.hint-line {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.connected-to-values {
|
||||
.hint-library-name {
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.shared-library-added {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--color-accent-tertiary);
|
||||
block-size: fit-content;
|
||||
border: $b-1 solid var(--color-accent-select);
|
||||
border-radius: $br-8;
|
||||
}
|
||||
|
||||
// Modal Component v2 update
|
||||
.modal-v2-info {
|
||||
width: px2rem(664);
|
||||
@ -364,6 +417,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.go-to-shared-button {
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
color: var(--color-accent-primary);
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.sample-libraries-container {
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
@ -403,3 +469,15 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tokens-source-label {
|
||||
block-size: $sz-32;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: var(--sp-s) var(--sp-xl);
|
||||
background: var(--color-background-primary);
|
||||
border: $b-1 solid var(--color-accent-select);
|
||||
color: var(--color-accent-tertiary);
|
||||
border-radius: $br-8;
|
||||
}
|
||||
|
||||
@ -37,9 +37,13 @@
|
||||
|
||||
[:div {:class (stl/css :tokens-source-wrapper)}
|
||||
[:div {:class (stl/css :tokens-source-header)}
|
||||
[:> text* {:as "div" :typography "headline-small" :class (stl/css :tokens-source-title)}
|
||||
[:> text* {:as "span"
|
||||
:typography "headline-small"
|
||||
:class (stl/css :tokens-source-title)}
|
||||
(:name tokens-source-file)]
|
||||
[:span {:class (stl/css :replace-this-by-a-badge-component)}
|
||||
[:> text* {:as "span"
|
||||
:typography "body-medium"
|
||||
:class (stl/css :tokens-source-description)}
|
||||
(tr "workspace.tokens.connected-library")]]
|
||||
[:> icon-button*
|
||||
{:variant "ghost"
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
|
||||
@use "ds/typography.scss" as *;
|
||||
@use "ds/_sizes" as *;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/spacing.scss" as *;
|
||||
@use "ds/_utils.scss" as *;
|
||||
|
||||
.tokens-source-wrapper {
|
||||
display: flex;
|
||||
@ -14,17 +16,25 @@
|
||||
}
|
||||
|
||||
.tokens-source-header {
|
||||
column-gap: var(--sp-s);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--sp-s);
|
||||
flex-grow: 1;
|
||||
padding: var(--sp-s);
|
||||
}
|
||||
|
||||
.tokens-source-title {
|
||||
color: var(--title-foreground-color);
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
color: var(--color-foreground-primary);
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.replace-this-by-a-badge-component {
|
||||
font-size: $sz-12;
|
||||
}
|
||||
.tokens-source-description {
|
||||
flex-shrink: 0;
|
||||
color: var(--color-foreground-secondary);
|
||||
border: $b-1 solid var(--color-foreground-secondary);
|
||||
padding: var(--sp-xxs) px2rem(6);
|
||||
border-radius: $br-6;
|
||||
}
|
||||
@ -7349,14 +7349,22 @@ msgid_plural "workspace.libraries.components"
|
||||
msgstr[0] "1 component"
|
||||
msgstr[1] "%s components"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:367
|
||||
msgid "workspace.libraries.connected-to"
|
||||
msgstr "Connected to"
|
||||
#: src/app/main/ui/workspace/libraries.cljs:541
|
||||
msgid "workspace.libraries.connected-libraries"
|
||||
msgstr "Connected library"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:550
|
||||
msgid "workspace.libraries.connected-through"
|
||||
msgstr "Connected through"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:432
|
||||
msgid "workspace.libraries.empty.add-some"
|
||||
msgstr "Or add some of these to try:"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:600
|
||||
msgid "workspace.libraries.empty.no-connected-libraries"
|
||||
msgstr "No connected libraries yet."
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:426
|
||||
msgid "workspace.libraries.empty.no-libraries"
|
||||
msgstr "There are no Shared Libraries at your team, you can look for"
|
||||
@ -7425,6 +7433,10 @@ msgstr "Search shared libraries"
|
||||
msgid "workspace.libraries.shared-libraries"
|
||||
msgstr "SHARED LIBRARIES"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:311
|
||||
msgid "workspace.libraries.shared-library-added"
|
||||
msgstr "Added"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:414
|
||||
msgid "workspace.libraries.shared-library-btn"
|
||||
msgstr "Connect library"
|
||||
|
||||
@ -7178,10 +7178,22 @@ msgid_plural "workspace.libraries.components"
|
||||
msgstr[0] "1 componente"
|
||||
msgstr[1] "%s componentes"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:541
|
||||
msgid "workspace.libraries.connected-libraries"
|
||||
msgstr "Biblioteca conectada"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:550
|
||||
msgid "workspace.libraries.connected-through"
|
||||
msgstr "Conectada mediante"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:367
|
||||
msgid "workspace.libraries.connected-to"
|
||||
msgstr "Conectada con"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:600
|
||||
msgid "workspace.libraries.empty.no-connected-libraries"
|
||||
msgstr "Aun no hay bibliotecas conectadas."
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:432
|
||||
msgid "workspace.libraries.empty.add-some"
|
||||
msgstr "O añadir algunas de éstas para probar:"
|
||||
@ -7254,6 +7266,10 @@ msgstr "Buscar bibliotecas compartidas"
|
||||
msgid "workspace.libraries.shared-libraries"
|
||||
msgstr "BIBLIOTECAS COMPARTIDAS"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:311
|
||||
msgid "workspace.libraries.shared-library-added"
|
||||
msgstr "Añadido"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:414
|
||||
msgid "workspace.libraries.shared-library-btn"
|
||||
msgstr "Conectar biblioteca"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user