mirror of
https://github.com/penpot/penpot.git
synced 2026-02-23 18:27:55 -05:00
Compare commits
2 Commits
develop
...
dfelinto-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ecaffa5375 | ||
|
|
4f6be55f9a |
@@ -14,6 +14,7 @@
|
||||
- Add woff2 support on user uploaded fonts (by @Nivl) [Github #8248](https://github.com/penpot/penpot/pull/8248)
|
||||
- Option to download custom fonts (by @dfelinto) [Github #8320](https://github.com/penpot/penpot/issues/8320)
|
||||
- Add copy as image to clipboard option to workspace context menu (by @dfelinto) [Github #8313](https://github.com/penpot/penpot/pull/8313)
|
||||
- Import Tokens from linked library [Github #8391](https://github.com/penpot/penpot/pull/8391)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
||||
@@ -119,12 +119,13 @@
|
||||
:strict-session-cookies
|
||||
:telemetry
|
||||
:terms-and-privacy-checkbox
|
||||
;; Only for developtment.
|
||||
:tiered-file-data-storage
|
||||
:token-base-font-size
|
||||
:token-color
|
||||
:token-shadow
|
||||
:token-tokenscript
|
||||
:token-import-from-library
|
||||
;; Only for developtment.
|
||||
:transit-readable-response
|
||||
:user-feedback
|
||||
;; TODO: remove this flag.
|
||||
@@ -180,7 +181,8 @@
|
||||
:enable-token-color
|
||||
:enable-token-shadow
|
||||
:enable-inspect-styles
|
||||
:enable-feature-fdata-objects-map])
|
||||
:enable-feature-fdata-objects-map
|
||||
:enable-token-import-from-library])
|
||||
|
||||
(defn parse
|
||||
[& flags]
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.notifications :as ntf]
|
||||
@@ -36,6 +38,7 @@
|
||||
[app.main.ui.ds.product.empty-state :refer [empty-state*]]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.workspace.tokens.import-from-library]
|
||||
[app.util.color :as uc]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [c tr]]
|
||||
@@ -180,6 +183,12 @@
|
||||
[summary]
|
||||
(boolean (:is-empty summary)))
|
||||
|
||||
(defn- has-tokens?
|
||||
"Check if library has tokens to be imported"
|
||||
[{:keys [data]}]
|
||||
(when-let [tokens-lib (get data :tokens-lib)]
|
||||
(not (ctob/empty-lib? tokens-lib))))
|
||||
|
||||
(mf/defc libraries-tab*
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
@@ -230,14 +239,18 @@
|
||||
(keep library-names))))
|
||||
(sort-by (comp str/lower :name))))
|
||||
|
||||
linked-libraries-ids (mf/with-memo [linked-libraries]
|
||||
(into #{} (map :id) linked-libraries))
|
||||
linked-libraries-ids
|
||||
(mf/with-memo [linked-libraries]
|
||||
(into #{} d/xf:map-id linked-libraries))
|
||||
|
||||
importing*
|
||||
(mf/use-state nil)
|
||||
|
||||
importing* (mf/use-state nil)
|
||||
sample-libraries [{:id "penpot-design-system", :name "Design system example"}
|
||||
{:id "wireframing-kit", :name "Wireframe library"}
|
||||
{:id "whiteboarding-kit", :name "Whiteboarding Kit"}]
|
||||
sample-libraries
|
||||
(mf/with-memo []
|
||||
[{:id "penpot-design-system", :name "Design system example"}
|
||||
{:id "wireframing-kit", :name "Wireframe library"}
|
||||
{:id "whiteboarding-kit", :name "Whiteboarding Kit"}])
|
||||
|
||||
|
||||
change-search-term
|
||||
@@ -267,6 +280,17 @@
|
||||
(st/emit! (dwl/unlink-file-from-library file-id library-id)
|
||||
(dwl/sync-file file-id library-id)))))
|
||||
|
||||
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})))))
|
||||
|
||||
on-delete-accept
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
@@ -332,8 +356,12 @@
|
||||
:on-click publish}])]
|
||||
|
||||
(for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries]
|
||||
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)]
|
||||
[:div {:class (stl/css :section-list-item)
|
||||
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)
|
||||
has-tokens? (and (has-tokens? library)
|
||||
(contains? cf/flags :token-import-from-library))]
|
||||
[:div {:class (if has-tokens?
|
||||
(stl/css :section-list-item-double-icon)
|
||||
(stl/css :section-list-item))
|
||||
:key (dm/str id)
|
||||
:data-testid "library-item"}
|
||||
[:div {:class (stl/css :item-content)}
|
||||
@@ -348,6 +376,15 @@
|
||||
[:span {:class (stl/css :connected-to-values)} (str/join ", " connected-to-names)]
|
||||
[:span ")"]])])]]
|
||||
|
||||
(when ^boolean has-tokens?
|
||||
[:> icon-button*
|
||||
{:type "button"
|
||||
:aria-label (tr "workspace.libraries.import-tokens-btn")
|
||||
: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
|
||||
|
||||
@@ -116,6 +116,11 @@
|
||||
border-radius: $br-8;
|
||||
}
|
||||
|
||||
.section-list-item-double-icon {
|
||||
@extend .section-list-item;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.tokens.import-from-library
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.store :as st]
|
||||
[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.typography :as t]
|
||||
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
|
||||
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
||||
(mf/defc import-modal-library*
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :tokens/import-from-library}
|
||||
[all-props]
|
||||
(let [{:keys [file-id library-id]}
|
||||
(js->clj all-props :keywordize-keys true)
|
||||
|
||||
library-file-ref (mf/with-memo [library-id]
|
||||
(l/derived (fn [state]
|
||||
(dm/get-in state [:files library-id :data]))
|
||||
st/state))
|
||||
library-data (mf/deref library-file-ref)
|
||||
|
||||
show-libraries-dialog
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn []
|
||||
(modal/hide!)
|
||||
(modal/show! :libraries-dialog {:file-id file-id})))
|
||||
|
||||
cancel
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(show-libraries-dialog)))
|
||||
|
||||
import
|
||||
(mf/use-fn
|
||||
(mf/deps file-id library-id library-data)
|
||||
(fn []
|
||||
(let [tokens-lib (:tokens-lib library-data)]
|
||||
(st/emit! (dwtl/import-tokens-lib tokens-lib)))
|
||||
(show-libraries-dialog)))]
|
||||
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-dialog)}
|
||||
[:> icon-button* {:class (stl/css :close-btn)
|
||||
:on-click cancel
|
||||
:aria-label (tr "labels.close")
|
||||
:variant "ghost"
|
||||
:icon i/close}]
|
||||
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:> heading* {:level 2
|
||||
:id "modal-title"
|
||||
:typography "headline-large"
|
||||
:class (stl/css :modal-title)}
|
||||
(tr "modals.import-library-tokens.title")]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:> text* {:as "p" :typography t/body-medium} (tr "modals.import-library-tokens.description")]]
|
||||
|
||||
[:> context-notification* {:type :context
|
||||
:appearance "neutral"
|
||||
:level "default"
|
||||
:is-html true}
|
||||
(tr "workspace.tokens.import-warning")]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:> button* {:on-click cancel
|
||||
:type "button"
|
||||
:variant "secondary"}
|
||||
(tr "labels.cancel")]
|
||||
[:> button* {:on-click import
|
||||
:type "button"
|
||||
:variant "primary"}
|
||||
(tr "modals.import-library-tokens.import")]]]]]))
|
||||
@@ -0,0 +1,70 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
|
||||
@use "ds/typography.scss" as t;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
inset-block-start: var(--sp-s);
|
||||
inset-inline-end: var(--sp-s);
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
--modal-title-foreground-color: var(--color-foreground-primary);
|
||||
--modal-text-foreground-color: var(--color-foreground-secondary);
|
||||
|
||||
@extend .modal-overlay-base;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
inset-inline-start: 0;
|
||||
inset-block-start: 0;
|
||||
block-size: 100%;
|
||||
inline-size: 100%;
|
||||
background-color: var(--overlay-color);
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
@extend .modal-container-base;
|
||||
inline-size: 100%;
|
||||
max-inline-size: 32rem;
|
||||
max-block-size: unset;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
margin-block-end: var(--sp-xxl);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@include t.use-typography("headline-medium");
|
||||
color: var(--modal-title-foreground-color);
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include t.use-typography("body-large");
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
margin-block-start: var(--sp-xxl);
|
||||
gap: var(--sp-s);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
gap: var(--sp-s);
|
||||
}
|
||||
@@ -1153,6 +1153,20 @@ msgstr "Type to search results"
|
||||
msgid "dashboard.unpublish-shared"
|
||||
msgstr "Unpublish Library"
|
||||
|
||||
#:src/app/main/ui/workspace/tokens/import_from_library.cljs
|
||||
msgid "modals.import-library-tokens.title"
|
||||
msgstr "Import tokens from library?"
|
||||
|
||||
#:src/app/main/ui/workspace/tokens/import_from_library.cljs
|
||||
msgid "modals.import-library-tokens.description"
|
||||
msgstr ""
|
||||
"The library has tokens and themes which "
|
||||
"are likely used by its components."
|
||||
|
||||
#:src/app/main/ui/workspace/tokens/import_from_library.cljs
|
||||
msgid "modals.import-library-tokens.import"
|
||||
msgstr "Import tokens"
|
||||
|
||||
#: src/app/main/ui/settings/options.cljs:74
|
||||
msgid "dashboard.update-settings"
|
||||
msgstr "Update settings"
|
||||
@@ -6008,6 +6022,10 @@ msgid_plural "workspace.libraries.typography"
|
||||
msgstr[0] "1 typography"
|
||||
msgstr[1] "%s typographies"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs
|
||||
msgid "workspace.libraries.import-tokens-btn"
|
||||
msgstr "Import tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:343
|
||||
msgid "workspace.libraries.unlink-library-btn"
|
||||
msgstr "Disconnect library"
|
||||
|
||||
Reference in New Issue
Block a user