mirror of
https://github.com/penpot/penpot.git
synced 2026-01-06 05:18:52 -05:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86bcd1b681 | ||
|
|
70b1989f10 | ||
|
|
e6b5618bd3 | ||
|
|
5199b306aa | ||
|
|
8febfaa21e | ||
|
|
5e675dbf0b | ||
|
|
fc5d9659d6 | ||
|
|
bc20598b3d | ||
|
|
9de8ebb52c | ||
|
|
9be569c54c | ||
|
|
7e6a621484 | ||
|
|
66b47f9444 | ||
|
|
71aa8e5a86 | ||
|
|
e203536506 | ||
|
|
3fe16bd8f9 | ||
|
|
a9725a1aac | ||
|
|
c3e76817cd | ||
|
|
36b78e5e21 | ||
|
|
a2c9d307df | ||
|
|
e52fd90963 | ||
|
|
d8b3b216e9 | ||
|
|
c2b13a6d5d | ||
|
|
a60b3d4b08 | ||
|
|
b14798b405 | ||
|
|
8382a88efe | ||
|
|
53057c4bf2 | ||
|
|
3e0f38e8c3 | ||
|
|
a5bbe765b9 | ||
|
|
4455adc813 | ||
|
|
abca763aa5 |
10
CHANGES.md
10
CHANGES.md
@@ -8,8 +8,9 @@
|
||||
|
||||
### :heart: Community contributions (Thank you!)
|
||||
|
||||
### :sparkles: New features
|
||||
- Design improvements to the Invitations page with an empty state [GitHub #2608](https://github.com/penpot/penpot/issues/2608) by [@iprithvitharun](https://github.com/iprithvitharun)
|
||||
|
||||
### :sparkles: New features
|
||||
|
||||
- Update board presets with a newer devices [Taiga #10610](https://tree.taiga.io/project/penpot/us/10610)
|
||||
- Propagate "sharing a prototype" to editors and viewers [Taiga #8853](https://tree.taiga.io/project/penpot/us/8853)
|
||||
@@ -20,6 +21,9 @@
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix problem in viewer with the back button [Taiga #10907](https://tree.taiga.io/project/penpot/issue/10907)
|
||||
- Fix resize bar background on tokens panel [Taiga #10811](https://tree.taiga.io/project/penpot/issue/10811)
|
||||
- Fix shortcut for history version panel [Taiga #11006](https://tree.taiga.io/project/penpot/issue/11006)
|
||||
- Fix positioning of comment drafts when near the right / bottom edges of viewport [Taiga #10534](https://tree.taiga.io/project/penpot/issue/10534)
|
||||
- Fix path having a wrong selrect [Taiga #10257](https://tree.taiga.io/project/penpot/issue/10257)
|
||||
- Fix SVG `stroke-linecap` property when importing SVGs [Taiga #9489](https://tree.taiga.io/project/penpot/issue/9489)
|
||||
@@ -41,8 +45,10 @@
|
||||
- Fix Out of Sync Token Value & Color Picker [Github #102](https://github.com/tokens-studio/penpot/issues/102)
|
||||
- Fix Color should preserve color space [Github #69](https://github.com/tokens-studio/penpot/issues/69)
|
||||
- Fix cannot rename Design Token Sets when group of same name exists [Taiga Issue #10773](https://tree.taiga.io/project/penpot/issue/10773)
|
||||
- Fix problem when duplicating grid layout [Github #6391](https://github.com/penpot/penpot/issues/6391)
|
||||
- Fix issue that makes workspace shortcuts stop working [Taiga #11062](https://tree.taiga.io/project/penpot/issue/11062)
|
||||
|
||||
## 2.6.2 (Unreleased)
|
||||
## 2.6.2
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
[::ip-addr {:optional true} ::sm/text]
|
||||
[::props {:optional true} [:map-of :keyword :any]]
|
||||
[::context {:optional true} [:map-of :keyword :any]]
|
||||
[::tracked-at {:optional true} ::sm/inst]
|
||||
[::webhooks/event? {:optional true} ::sm/boolean]
|
||||
[::webhooks/batch-timeout {:optional true} ::dt/duration]
|
||||
[::webhooks/batch-key {:optional true}
|
||||
@@ -118,12 +119,12 @@
|
||||
|
||||
(defn prepare-event
|
||||
[cfg mdata params result]
|
||||
(let [resultm (meta result)
|
||||
request (-> params meta ::http/request)
|
||||
profile-id (or (::profile-id resultm)
|
||||
(:profile-id result)
|
||||
(::rpc/profile-id params)
|
||||
uuid/zero)
|
||||
(let [resultm (meta result)
|
||||
request (-> params meta ::http/request)
|
||||
profile-id (or (::profile-id resultm)
|
||||
(:profile-id result)
|
||||
(::rpc/profile-id params)
|
||||
uuid/zero)
|
||||
|
||||
session-id (get params ::rpc/external-session-id)
|
||||
event-origin (get params ::rpc/external-event-origin)
|
||||
@@ -135,14 +136,14 @@
|
||||
|
||||
(clean-props))
|
||||
|
||||
token-id (::actoken/id request)
|
||||
context (-> (::context resultm)
|
||||
(assoc :external-session-id session-id)
|
||||
(assoc :external-event-origin event-origin)
|
||||
(assoc :access-token-id (some-> token-id str))
|
||||
(d/without-nils))
|
||||
token-id (::actoken/id request)
|
||||
context (-> (::context resultm)
|
||||
(assoc :external-session-id session-id)
|
||||
(assoc :external-event-origin event-origin)
|
||||
(assoc :access-token-id (some-> token-id str))
|
||||
(d/without-nils))
|
||||
|
||||
ip-addr (inet/parse-request request)]
|
||||
ip-addr (inet/parse-request request)]
|
||||
|
||||
{::type (or (::type resultm)
|
||||
(::rpc/type cfg))
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.http.client :as http]
|
||||
[app.loggers.audit :as audit]
|
||||
[app.util.time :as dt]
|
||||
[app.worker :as wrk]
|
||||
[clojure.data.json :as json]
|
||||
@@ -67,18 +68,27 @@
|
||||
(defmethod ig/init-key ::process-event-handler
|
||||
[_ cfg]
|
||||
(fn [{:keys [props] :as task}]
|
||||
(l/dbg :hint "process webhook event" :name (:name props))
|
||||
|
||||
(when-let [items (lookup-webhooks cfg props)]
|
||||
(l/trc :hint "webhooks found for event" :total (count items))
|
||||
(db/tx-run! cfg (fn [cfg]
|
||||
(doseq [item items]
|
||||
(wrk/submit! (-> cfg
|
||||
(assoc ::wrk/task :run-webhook)
|
||||
(assoc ::wrk/queue :webhooks)
|
||||
(assoc ::wrk/max-retries 3)
|
||||
(assoc ::wrk/params {:event props
|
||||
:config item})))))))))
|
||||
(let [items (lookup-webhooks cfg props)
|
||||
event {::audit/profile-id (:profile-id props)
|
||||
::audit/name "webhook"
|
||||
::audit/type "trigger"
|
||||
::audit/props {:name (get props :name)
|
||||
:event-id (get props :id)
|
||||
:total-affected (count items)}}]
|
||||
|
||||
(audit/insert! cfg event)
|
||||
|
||||
(when items
|
||||
(l/trc :hint "webhooks found for event" :total (count items))
|
||||
(db/tx-run! cfg (fn [cfg]
|
||||
(doseq [item items]
|
||||
(wrk/submit! (-> cfg
|
||||
(assoc ::wrk/task :run-webhook)
|
||||
(assoc ::wrk/queue :webhooks)
|
||||
(assoc ::wrk/max-retries 3)
|
||||
(assoc ::wrk/params {:event props
|
||||
:config item}))))))))))
|
||||
;; --- RUN
|
||||
|
||||
(declare interpret-exception)
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
[:project-id {:optional true} ::sm/uuid]])
|
||||
|
||||
(defn- migrate-file
|
||||
[{:keys [::db/conn] :as cfg} {:keys [id] :as file}]
|
||||
[{:keys [::db/conn] :as cfg} {:keys [id] :as file} {:keys [read-only?]}]
|
||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)
|
||||
pmap/*tracked* (pmap/create-tracked)]
|
||||
(let [;; For avoid unnecesary overhead of creating multiple pointers and
|
||||
@@ -219,43 +219,45 @@
|
||||
file (-> file
|
||||
(update :data feat.fdata/process-pointers deref)
|
||||
(update :data feat.fdata/process-objects (partial into {}))
|
||||
(fmg/migrate-file))
|
||||
(fmg/migrate-file))]
|
||||
|
||||
;; When file is migrated, we break the rule of no perform
|
||||
;; mutations on get operations and update the file with all
|
||||
;; migrations applied
|
||||
;;
|
||||
;; WARN: he following code will not work on read-only mode,
|
||||
;; it is a known issue; we keep is not implemented until we
|
||||
;; really need this.
|
||||
file (if (contains? (:features file) "fdata/objects-map")
|
||||
(feat.fdata/enable-objects-map file)
|
||||
file)
|
||||
file (if (contains? (:features file) "fdata/pointer-map")
|
||||
(feat.fdata/enable-pointer-map file)
|
||||
file)]
|
||||
(if (or read-only? (db/read-only? conn))
|
||||
file
|
||||
(let [;; When file is migrated, we break the rule of no perform
|
||||
;; mutations on get operations and update the file with all
|
||||
;; migrations applied
|
||||
file (if (contains? (:features file) "fdata/objects-map")
|
||||
(feat.fdata/enable-objects-map file)
|
||||
file)
|
||||
file (if (contains? (:features file) "fdata/pointer-map")
|
||||
(feat.fdata/enable-pointer-map file)
|
||||
file)]
|
||||
|
||||
(db/update! conn :file
|
||||
{:data (blob/encode (:data file))
|
||||
:version (:version file)
|
||||
:features (db/create-array conn "text" (:features file))}
|
||||
{:id id})
|
||||
(db/update! conn :file
|
||||
{:data (blob/encode (:data file))
|
||||
:version (:version file)
|
||||
:features (db/create-array conn "text" (:features file))}
|
||||
{:id id}
|
||||
{::db/return-keys false})
|
||||
|
||||
(when (contains? (:features file) "fdata/pointer-map")
|
||||
(feat.fdata/persist-pointers! cfg id))
|
||||
(when (contains? (:features file) "fdata/pointer-map")
|
||||
(feat.fdata/persist-pointers! cfg id))
|
||||
|
||||
(feat.fmigr/upsert-migrations! conn file)
|
||||
(feat.fmigr/resolve-applied-migrations cfg file))))
|
||||
(feat.fmigr/upsert-migrations! conn file)
|
||||
(feat.fmigr/resolve-applied-migrations cfg file))))))
|
||||
|
||||
(defn get-file
|
||||
[{:keys [::db/conn ::wrk/executor] :as cfg} id
|
||||
& {:keys [project-id
|
||||
migrate?
|
||||
include-deleted?
|
||||
lock-for-update?]
|
||||
lock-for-update?
|
||||
preload-pointers?]
|
||||
:or {include-deleted? false
|
||||
lock-for-update? false
|
||||
migrate? true}}]
|
||||
migrate? true
|
||||
preload-pointers? false}
|
||||
:as options}]
|
||||
|
||||
(assert (db/connection? conn) "expected cfg with valid connection")
|
||||
|
||||
@@ -273,10 +275,16 @@
|
||||
;; because it has heavy and synchronous operations for
|
||||
;; decoding file body that are not very friendly with virtual
|
||||
;; threads.
|
||||
file (px/invoke! executor #(decode-row file))]
|
||||
file (px/invoke! executor #(decode-row file))
|
||||
|
||||
file (if (and migrate? (fmg/need-migration? file))
|
||||
(migrate-file cfg file options)
|
||||
file)]
|
||||
|
||||
(if preload-pointers?
|
||||
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)]
|
||||
(update file :data feat.fdata/process-pointers deref))
|
||||
|
||||
(if (and migrate? (fmg/need-migration? file))
|
||||
(migrate-file cfg file)
|
||||
file)))
|
||||
|
||||
(defn get-minimal-file
|
||||
@@ -484,7 +492,7 @@
|
||||
|
||||
(let [perms (get-permissions conn profile-id file-id share-id)
|
||||
|
||||
file (get-file cfg file-id)
|
||||
file (get-file cfg file-id :read-only? true)
|
||||
|
||||
proj (db/get conn :project {:id (:project-id file)})
|
||||
|
||||
@@ -741,7 +749,9 @@
|
||||
:project-id project-id
|
||||
:file-id id)
|
||||
|
||||
file (get-file cfg id :project-id project-id)]
|
||||
file (get-file cfg id
|
||||
:project-id project-id
|
||||
:read-only? true)]
|
||||
|
||||
(-> (cfeat/get-team-enabled-features cf/flags team)
|
||||
(cfeat/check-client-features! (:features params))
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.features :as cfeat]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.migrations :as fmg]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.thumbnails :as thc]
|
||||
@@ -18,7 +17,6 @@
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.db.sql :as-alias sql]
|
||||
[app.features.fdata :as feat.fdata]
|
||||
[app.loggers.audit :as-alias audit]
|
||||
[app.loggers.webhooks :as-alias webhooks]
|
||||
[app.media :as media]
|
||||
@@ -200,14 +198,13 @@
|
||||
(db/run! cfg (fn [{:keys [::db/conn] :as cfg}]
|
||||
(files/check-read-permissions! conn profile-id file-id)
|
||||
|
||||
(let [team (teams/get-team conn
|
||||
:profile-id profile-id
|
||||
:file-id file-id)
|
||||
(let [team (teams/get-team conn
|
||||
:profile-id profile-id
|
||||
:file-id file-id)
|
||||
|
||||
file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
|
||||
(-> (files/get-file cfg file-id :migrate? false)
|
||||
(update :data feat.fdata/process-pointers deref)
|
||||
(fmg/migrate-file)))]
|
||||
file (files/get-file cfg file-id
|
||||
:preload-pointers? true
|
||||
:read-only? true)]
|
||||
|
||||
(-> (cfeat/get-team-enabled-features cf/flags team)
|
||||
(cfeat/check-file-features! (:features file)))
|
||||
|
||||
@@ -1049,6 +1049,33 @@
|
||||
:id id
|
||||
:delta delta})))
|
||||
|
||||
(defn reorder-children
|
||||
[changes id children]
|
||||
(assert-page-id! changes)
|
||||
(assert-objects! changes)
|
||||
|
||||
(let [page-id (::page-id (meta changes))
|
||||
objects (lookup-objects changes)
|
||||
shape (get objects id)
|
||||
old-children (:shapes shape)
|
||||
|
||||
redo-change
|
||||
{:type :reorder-children
|
||||
:parent-id (:id shape)
|
||||
:page-id page-id
|
||||
:shapes children}
|
||||
|
||||
undo-change
|
||||
{:type :reorder-children
|
||||
:parent-id (:id shape)
|
||||
:page-id page-id
|
||||
:shapes old-children}]
|
||||
|
||||
(-> changes
|
||||
(update :redo-changes conj redo-change)
|
||||
(update :undo-changes conj undo-change)
|
||||
(apply-changes-local))))
|
||||
|
||||
(defn reorder-grid-children
|
||||
[changes ids]
|
||||
(assert-page-id! changes)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
(ns app.main.ui.workspace.tokens.token
|
||||
;; 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.common.files.tokens
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
@@ -128,18 +133,6 @@
|
||||
(defn color-token? [token]
|
||||
(= (:type token) :color))
|
||||
|
||||
|
||||
;; FIXME: this should be precalculated ?
|
||||
(defn is-reference? [token]
|
||||
(str/includes? (:value token) "{"))
|
||||
|
||||
(defn color-bullet-color [token-color-value]
|
||||
(when-let [tc (tinycolor/valid-color token-color-value)]
|
||||
(if (tinycolor/alpha tc)
|
||||
{:color (tinycolor/->hex-string tc)
|
||||
:opacity (tinycolor/alpha tc)}
|
||||
(tinycolor/->hex-string tc))))
|
||||
|
||||
(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}]
|
||||
(when (and resolved-value (color-token? token))
|
||||
(color-bullet-color resolved-value)))
|
||||
@@ -216,10 +216,12 @@
|
||||
"Generate changes to create a new instance from a component."
|
||||
([changes objects file-id component-id position page libraries]
|
||||
(generate-instantiate-component changes objects file-id component-id position page libraries nil nil nil {}))
|
||||
|
||||
([changes objects file-id component-id position page libraries old-id parent-id frame-id
|
||||
([changes objects file-id component-id position page libraries old-id parent-id frame-id params]
|
||||
(generate-instantiate-component changes objects file-id component-id position page libraries old-id parent-id frame-id {} params))
|
||||
([changes objects file-id component-id position page libraries old-id parent-id frame-id ids-map
|
||||
{:keys [force-frame?]
|
||||
:or {force-frame? false}}]
|
||||
|
||||
(let [component (ctf/get-component libraries file-id component-id)
|
||||
library (get libraries file-id)
|
||||
parent (when parent-id (get objects parent-id))
|
||||
@@ -239,6 +241,9 @@
|
||||
(:data library)
|
||||
position
|
||||
(cond-> {}
|
||||
(contains? ids-map old-id)
|
||||
(assoc :force-id (get ids-map old-id))
|
||||
|
||||
force-frame?
|
||||
(assoc :force-frame-id frame-id)))
|
||||
|
||||
@@ -260,8 +265,11 @@
|
||||
(cond-> (pcb/add-object changes first-shape {:ignore-touched true})
|
||||
(some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id)))
|
||||
|
||||
duplicated-parent?
|
||||
(->> ids-map vals (some #(= % (:parent-id first-shape))))
|
||||
|
||||
changes
|
||||
(if (ctl/grid-layout? objects (:parent-id first-shape))
|
||||
(if (and (ctl/grid-layout? objects (:parent-id first-shape)) (not duplicated-parent?))
|
||||
(let [target-cell (-> position meta :cell)
|
||||
|
||||
[row column]
|
||||
@@ -1976,17 +1984,26 @@
|
||||
[changes library-data component-id library-id current-page objects]
|
||||
(let [{:keys [changes shape]} (prepare-restore-component changes library-data component-id current-page)
|
||||
parent-id (:parent-id shape)
|
||||
objects (cond-> (assoc objects (:id shape) shape)
|
||||
(not (nil? parent-id))
|
||||
(update-in [parent-id :shapes]
|
||||
#(conj % (:id shape))))
|
||||
|
||||
insert-before?
|
||||
(and (ctl/flex-layout? objects parent-id)
|
||||
(not (ctl/reverse? objects parent-id)))
|
||||
|
||||
objects
|
||||
(-> objects
|
||||
(assoc (:id shape) shape)
|
||||
(cond-> (and (some? parent-id) insert-before?)
|
||||
(update-in [parent-id :shapes] #(d/concat-vec [(:id shape)] %)))
|
||||
(cond-> (and (some? parent-id) (not insert-before?))
|
||||
(update-in [parent-id :shapes] conj (:id shape))))
|
||||
|
||||
;; Adds a resize-parents operation so the groups are updated. We add all the new objects
|
||||
new-objects-ids (->> changes :redo-changes (filter #(= (:type %) :add-obj)) (mapv :id))
|
||||
changes (-> changes
|
||||
(pcb/with-objects objects)
|
||||
(pcb/resize-parents new-objects-ids))]
|
||||
|
||||
(pcb/resize-parents new-objects-ids)
|
||||
;; Fix the order of the children inside the parent
|
||||
(pcb/reorder-children parent-id (get-in objects [parent-id :shapes])))]
|
||||
(assoc changes :file-id library-id)))
|
||||
|
||||
(defn generate-detach-component
|
||||
@@ -2225,6 +2242,7 @@
|
||||
main-id
|
||||
parent-id
|
||||
frame-id
|
||||
ids-map
|
||||
{})))]
|
||||
changes))
|
||||
|
||||
|
||||
@@ -4,36 +4,36 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns frontend-tests.tokens.token-test
|
||||
(ns common-tests.files.tokens-test
|
||||
(:require
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[cljs.test :as t :include-macros true]))
|
||||
[app.common.files.tokens :as cft]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/deftest test-parse-token-value
|
||||
(t/testing "parses double from a token value"
|
||||
(t/is (= {:value 100.1 :unit nil} (wtt/parse-token-value "100.1")))
|
||||
(t/is (= {:value -9 :unit nil} (wtt/parse-token-value "-9"))))
|
||||
(t/is (= {:value 100.1 :unit nil} (cft/parse-token-value "100.1")))
|
||||
(t/is (= {:value -9.0 :unit nil} (cft/parse-token-value "-9"))))
|
||||
(t/testing "trims white-space"
|
||||
(t/is (= {:value -1.3 :unit nil} (wtt/parse-token-value " -1.3 "))))
|
||||
(t/is (= {:value -1.3 :unit nil} (cft/parse-token-value " -1.3 "))))
|
||||
(t/testing "parses unit: px"
|
||||
(t/is (= {:value 70.3 :unit "px"} (wtt/parse-token-value " 70.3px "))))
|
||||
(t/is (= {:value 70.3 :unit "px"} (cft/parse-token-value " 70.3px "))))
|
||||
(t/testing "parses unit: %"
|
||||
(t/is (= {:value -10 :unit "%"} (wtt/parse-token-value "-10%"))))
|
||||
(t/is (= {:value -10.0 :unit "%"} (cft/parse-token-value "-10%"))))
|
||||
(t/testing "parses unit: px")
|
||||
(t/testing "returns nil for any invalid characters"
|
||||
(t/is (nil? (wtt/parse-token-value " -1.3a "))))
|
||||
(t/is (nil? (cft/parse-token-value " -1.3a "))))
|
||||
(t/testing "doesnt accept invalid double"
|
||||
(t/is (nil? (wtt/parse-token-value ".3")))))
|
||||
(t/is (nil? (cft/parse-token-value ".3")))))
|
||||
|
||||
(t/deftest token-applied-test
|
||||
(t/testing "matches passed token with `:token-attributes`"
|
||||
(t/is (true? (wtt/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/is (true? (cft/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/testing "doesn't match empty token"
|
||||
(t/is (nil? (wtt/token-applied? {} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/is (nil? (cft/token-applied? {} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/testing "does't match passed token `:id`"
|
||||
(t/is (nil? (wtt/token-applied? {:name "b"} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/is (nil? (cft/token-applied? {:name "b"} {:applied-tokens {:x "a"}} #{:x}))))
|
||||
(t/testing "doesn't match passed `:token-attributes`"
|
||||
(t/is (nil? (wtt/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:y})))))
|
||||
(t/is (nil? (cft/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:y})))))
|
||||
|
||||
(t/deftest shapes-ids-by-applied-attributes
|
||||
(t/testing "Returns set of matched attributes that fit the applied token"
|
||||
@@ -54,7 +54,7 @@
|
||||
shape-applied-x-y
|
||||
shape-applied-all
|
||||
shape-applied-none]
|
||||
expected (wtt/shapes-ids-by-applied-attributes {:name "1"} shapes attributes)]
|
||||
expected (cft/shapes-ids-by-applied-attributes {:name "1"} shapes attributes)]
|
||||
(t/is (= (:x expected) (shape-ids shape-applied-x
|
||||
shape-applied-x-y
|
||||
shape-applied-all)))
|
||||
@@ -62,34 +62,34 @@
|
||||
shape-applied-x-y
|
||||
shape-applied-all)))
|
||||
(t/is (= (:z expected) (shape-ids shape-applied-all)))
|
||||
(t/is (true? (wtt/shapes-applied-all? expected (shape-ids shape-applied-all) attributes)))
|
||||
(t/is (false? (wtt/shapes-applied-all? expected (apply shape-ids shapes) attributes)))
|
||||
(t/is (true? (cft/shapes-applied-all? expected (shape-ids shape-applied-all) attributes)))
|
||||
(t/is (false? (cft/shapes-applied-all? expected (apply shape-ids shapes) attributes)))
|
||||
(shape-ids shape-applied-x
|
||||
shape-applied-x-y
|
||||
shape-applied-all))))
|
||||
|
||||
(t/deftest tokens-applied-test
|
||||
(t/testing "is true when single shape matches the token and attributes"
|
||||
(t/is (true? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}}
|
||||
(t/is (true? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}}
|
||||
{:applied-tokens {:x "b"}}]
|
||||
#{:x}))))
|
||||
(t/testing "is false when no shape matches the token or attributes"
|
||||
(t/is (nil? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "b"}}
|
||||
(t/is (nil? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "b"}}
|
||||
{:applied-tokens {:x "b"}}]
|
||||
#{:x})))
|
||||
(t/is (nil? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}}
|
||||
(t/is (nil? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}}
|
||||
{:applied-tokens {:x "a"}}]
|
||||
#{:y})))))
|
||||
|
||||
(t/deftest name->path-test
|
||||
(t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo.bar.baz")))
|
||||
(t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo..bar.baz")))
|
||||
(t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo..bar.baz...."))))
|
||||
(t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo.bar.baz")))
|
||||
(t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo..bar.baz")))
|
||||
(t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo..bar.baz...."))))
|
||||
|
||||
(t/deftest token-name-path-exists?-test
|
||||
(t/is (true? (wtt/token-name-path-exists? "border-radius" {"border-radius" {"sm" {:name "sm"}}})))
|
||||
(t/is (true? (wtt/token-name-path-exists? "border-radius" {"border-radius" {:name "sm"}})))
|
||||
(t/is (true? (wtt/token-name-path-exists? "border-radius.sm" {"border-radius" {:name "sm"}})))
|
||||
(t/is (true? (wtt/token-name-path-exists? "border-radius.sm.x" {"border-radius" {:name "sm"}})))
|
||||
(t/is (false? (wtt/token-name-path-exists? "other" {"border-radius" {:name "sm"}})))
|
||||
(t/is (false? (wtt/token-name-path-exists? "dark.border-radius.md" {"dark" {"border-radius" {"sm" {:name "sm"}}}}))))
|
||||
(t/is (true? (cft/token-name-path-exists? "border-radius" {"border-radius" {"sm" {:name "sm"}}})))
|
||||
(t/is (true? (cft/token-name-path-exists? "border-radius" {"border-radius" {:name "sm"}})))
|
||||
(t/is (true? (cft/token-name-path-exists? "border-radius.sm" {"border-radius" {:name "sm"}})))
|
||||
(t/is (true? (cft/token-name-path-exists? "border-radius.sm.x" {"border-radius" {:name "sm"}})))
|
||||
(t/is (false? (cft/token-name-path-exists? "other" {"border-radius" {:name "sm"}})))
|
||||
(t/is (false? (cft/token-name-path-exists? "dark.border-radius.md" {"dark" {"border-radius" {"sm" {:name "sm"}}}}))))
|
||||
@@ -1,3 +1,9 @@
|
||||
;; 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 common-tests.logic.token-test
|
||||
(:require
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
|
||||
@@ -4,11 +4,13 @@ import { presenceFixture } from "../../data/workspace/ws-notifications";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await WorkspacePage.init(page);
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
});
|
||||
|
||||
test("Save and restore version", async ({ page }) => {
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
|
||||
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=406b7b01-d3e2-80e4-8005-3138b7cc5f0b",
|
||||
@@ -87,3 +89,20 @@ test("Save and restore version", async ({ page }) => {
|
||||
// check that the history panel is closed after restore
|
||||
await expect(page.getByRole("tab", { name: "design" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("BUG 11006 - Fix history panel shortcut", async ({ page }) => {
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-snapshots?file-id=*",
|
||||
"workspace/versions-snapshot-1.json",
|
||||
);
|
||||
|
||||
await workspacePage.goToWorkspace();
|
||||
|
||||
await page.keyboard.press("Control+Alt+h");
|
||||
|
||||
await expect(
|
||||
workspacePage.rightSidebar.getByText("There are no versions yet"),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
BIN
frontend/resources/images/features/2.7-duplicate-set.gif
Normal file
BIN
frontend/resources/images/features/2.7-duplicate-set.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 208 KiB |
BIN
frontend/resources/images/features/2.7-invitations.gif
Normal file
BIN
frontend/resources/images/features/2.7-invitations.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
BIN
frontend/resources/images/features/2.7-share.gif
Normal file
BIN
frontend/resources/images/features/2.7-share.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
BIN
frontend/resources/images/features/2.7-slide-0.jpg
Normal file
BIN
frontend/resources/images/features/2.7-slide-0.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
@@ -8,7 +8,7 @@
|
||||
(:refer-clojure :exclude [meta reset!])
|
||||
(:require
|
||||
["@penpot/mousetrap$default" :as mousetrap]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.data :as d]
|
||||
[app.common.logging :as log]
|
||||
[app.common.schema :as sm]
|
||||
[app.config :as cf]
|
||||
@@ -135,7 +135,7 @@
|
||||
[:fn {:optional true} fn?]
|
||||
[:tooltip {:optional true} :string]]])
|
||||
|
||||
(def check-shortcuts!
|
||||
(def ^:private check-shortcuts
|
||||
(sm/check-fn schema:shortcuts))
|
||||
|
||||
(defn- wrap-cb
|
||||
@@ -167,23 +167,20 @@
|
||||
(mousetrap/reset)
|
||||
(bind! shortcuts)))
|
||||
|
||||
(def ^:private conj*
|
||||
(fnil conj (d/ordered-map)))
|
||||
|
||||
(defn push-shortcuts
|
||||
[key shortcuts]
|
||||
(assert (keyword? key) "expected a keyword for `key`")
|
||||
(let [shortcuts (check-shortcuts shortcuts)]
|
||||
(ptk/reify ::push-shortcuts
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :shortcuts conj* [key shortcuts]))
|
||||
|
||||
(dm/assert!
|
||||
"expected valid parameters"
|
||||
(and (keyword? key)
|
||||
(check-shortcuts! shortcuts)))
|
||||
|
||||
(ptk/reify ::push-shortcuts
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :shortcuts (fnil conj '()) [key shortcuts])))
|
||||
|
||||
ptk/EffectEvent
|
||||
(effect [_ state _]
|
||||
(let [[_key shortcuts] (peek (:shortcuts state))]
|
||||
ptk/EffectEvent
|
||||
(effect [_ _ _]
|
||||
(reset! shortcuts)))))
|
||||
|
||||
(defn pop-shortcuts
|
||||
@@ -192,12 +189,9 @@
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :shortcuts (fn [shortcuts]
|
||||
(let [current-key (first (peek shortcuts))]
|
||||
(if (= key current-key)
|
||||
(pop shortcuts)
|
||||
shortcuts)))))
|
||||
(dissoc shortcuts key))))
|
||||
|
||||
ptk/EffectEvent
|
||||
(effect [_ state _]
|
||||
(let [[key* shortcuts] (peek (:shortcuts state))]
|
||||
(when (not= key key*)
|
||||
(reset! shortcuts))))))
|
||||
(let [[_key shortcuts] (last (:shortcuts state))]
|
||||
(reset! shortcuts)))))
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
(ns app.main.ui.workspace.tokens.style-dictionary
|
||||
;; 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.data.style-dictionary
|
||||
(:require
|
||||
["@tokens-studio/sd-transforms" :as sd-transforms]
|
||||
["style-dictionary$default" :as sd]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.logging :as l]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.transit :as t]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.warnings :as wtw]
|
||||
[app.main.data.tinycolor :as tinycolor]
|
||||
[app.main.data.workspace.tokens.errors :as wte]
|
||||
[app.main.data.workspace.tokens.warnings :as wtw]
|
||||
[app.util.time :as dt]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
@@ -54,7 +60,7 @@
|
||||
"Parses `value` of a numeric `sd-token` into a map like `{:value 1 :unit \"px\"}`.
|
||||
If the `value` is not parseable and/or has missing references returns a map with `:errors`."
|
||||
[value]
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-bounds (or (>= (:value parsed-value) sm/max-safe-int)
|
||||
(<= (:value parsed-value) sm/min-safe-int))]
|
||||
(if (and parsed-value (not out-of-bounds))
|
||||
@@ -72,7 +78,7 @@
|
||||
If the `value` is parseable but is out of range returns a map with `warnings`."
|
||||
[value has-references?]
|
||||
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-scope (not (<= 0 (:value parsed-value) 1))
|
||||
references (seq (ctob/find-token-value-references value))]
|
||||
(cond
|
||||
@@ -98,7 +104,7 @@
|
||||
If the `value` is parseable but is out of range returns a map with `warnings`."
|
||||
[value has-references?]
|
||||
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-scope (< (:value parsed-value) 0)
|
||||
references (seq (ctob/find-token-value-references value))]
|
||||
(cond
|
||||
@@ -1,4 +1,10 @@
|
||||
(ns app.main.ui.workspace.tokens.tinycolor
|
||||
;; 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.data.tinycolor
|
||||
"Bindings for tinycolor2 which supports a wide range of css compatible colors.
|
||||
|
||||
This library was chosen as it is already used by StyleDictionary,
|
||||
@@ -581,11 +581,14 @@
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(cll/generate-restore-component ldata component-id library-id page objects))
|
||||
|
||||
page-id
|
||||
(->> changes :redo-changes (keep :page-id) first)
|
||||
|
||||
frames
|
||||
(->> changes :redo-changes (keep :frame-id))]
|
||||
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(ptk/data-event :layout/update {:ids frames}))))))
|
||||
(ptk/data-event :layout/update {:page-id page-id :ids frames}))))))
|
||||
|
||||
|
||||
(defn restore-components
|
||||
|
||||
@@ -97,15 +97,17 @@
|
||||
;; Never call this directly but through the data-event `:layout/update`
|
||||
;; Otherwise a lot of cycle dependencies could be generated
|
||||
(defn- update-layout-positions
|
||||
[{:keys [ids undo-group]}]
|
||||
[{:keys [page-id ids undo-group]}]
|
||||
(ptk/reify ::update-layout-positions
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (dsh/lookup-page-objects state)
|
||||
(let [page-id (or page-id (:current-page-id state))
|
||||
objects (dsh/lookup-page-objects state page-id)
|
||||
ids (->> ids (filter #(contains? objects %)))]
|
||||
(if (d/not-empty? ids)
|
||||
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modif-tree
|
||||
(rx/of (dwm/apply-modifiers {:page-id page-id
|
||||
:modifiers modif-tree
|
||||
:stack-undo? true
|
||||
:undo-group undo-group})))
|
||||
(rx/empty))))))
|
||||
@@ -127,8 +129,9 @@
|
||||
(rx/filter #(d/not-empty? %))
|
||||
(rx/map
|
||||
(fn [data]
|
||||
(let [ids (reduce #(into %1 (:ids %2)) #{} data)]
|
||||
(update-layout-positions {:ids ids}))))
|
||||
(let [page-id (->> data (keep :page-id) first)
|
||||
ids (reduce #(into %1 (:ids %2)) #{} data)]
|
||||
(update-layout-positions {:page-id page-id :ids ids}))))
|
||||
(rx/take-until stopper))))))
|
||||
|
||||
(defn finalize-shape-layout
|
||||
|
||||
@@ -464,11 +464,11 @@
|
||||
:subsections [:panels]
|
||||
:fn #(st/emit! (dcm/go-to-workspace :layout :assets))}
|
||||
|
||||
:toggle-history {:tooltip (ds/alt "H")
|
||||
:command (ds/a-mod "h")
|
||||
:toggle-history {:tooltip (ds/meta-alt "H")
|
||||
:command (ds/ca-mod "h")
|
||||
:subsections [:panels]
|
||||
:fn #(emit-when-no-readonly
|
||||
(dcm/go-to-workspace :layout :document-history))}
|
||||
(dw/toggle-layout-flag :document-history))}
|
||||
|
||||
:toggle-colorpalette {:tooltip (ds/alt "P")
|
||||
:command (ds/a-mod "p")
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.tokens.changes
|
||||
(ns app.main.data.workspace.tokens.application
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.types.token :as ctt]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.data.tinycolor :as tinycolor]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace.colors :as wdc]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
@@ -21,16 +24,13 @@
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare token-properties)
|
||||
|
||||
;; Token Updates ---------------------------------------------------------------
|
||||
;; Events to apply / unapply tokens to shapes ------------------------------------------------------------
|
||||
|
||||
(defn apply-token
|
||||
"Apply `attributes` that match `token` for `shape-ids`.
|
||||
@@ -56,8 +56,8 @@
|
||||
(keys))
|
||||
[])
|
||||
|
||||
resolved-value (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value])
|
||||
tokenized-attributes (wtt/attributes-map attributes token)]
|
||||
resolved-value (get-in resolved-tokens [(cft/token-identifier token) :resolved-value])
|
||||
tokenized-attributes (cft/attributes-map attributes token)]
|
||||
(rx/of
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "apply-tokens"}))
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
@@ -80,7 +80,7 @@
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of
|
||||
(let [remove-token #(when % (wtt/remove-attributes-for-token attributes token %))]
|
||||
(let [remove-token #(when % (cft/remove-attributes-for-token attributes token %))]
|
||||
(dwsh/update-shapes
|
||||
shape-ids
|
||||
(fn [shape]
|
||||
@@ -95,7 +95,7 @@
|
||||
(get token-properties (:type token))
|
||||
|
||||
unapply-tokens?
|
||||
(wtt/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
(cft/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
|
||||
shape-ids (map :id shapes)]
|
||||
(if unapply-tokens?
|
||||
@@ -109,7 +109,9 @@
|
||||
:shape-ids shape-ids
|
||||
:on-update-shape on-update-shape})))))))
|
||||
|
||||
;; Shape Updates ---------------------------------------------------------------
|
||||
;; Events to update the value of attributes with applied tokens ---------------------------------------------------------
|
||||
|
||||
;; (note that dwsh/update-shapes function returns an event)
|
||||
|
||||
(defn update-shape-radius-all
|
||||
([value shape-ids attributes] (update-shape-radius-all value shape-ids attributes nil))
|
||||
@@ -326,7 +328,7 @@
|
||||
(dwsl/update-layout-child shape-ids props {:ignore-touched true
|
||||
:page-id page-id}))))))))
|
||||
|
||||
;; Token Types -----------------------------------------------------------------
|
||||
;; Map token types to different properties used along the cokde ---------------------------------------------------------
|
||||
|
||||
;; FIXME: the values should be lazy evaluated, probably a function,
|
||||
;; becasue on future we will need to translate that labels and that
|
||||
21
frontend/src/app/main/data/workspace/tokens/color.cljs
Normal file
21
frontend/src/app/main/data/workspace/tokens/color.cljs
Normal file
@@ -0,0 +1,21 @@
|
||||
;; 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.data.workspace.tokens.color
|
||||
(:require
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.main.data.tinycolor :as tinycolor]))
|
||||
|
||||
(defn color-bullet-color [token-color-value]
|
||||
(when-let [tc (tinycolor/valid-color token-color-value)]
|
||||
(if (tinycolor/alpha tc)
|
||||
{:color (tinycolor/->hex-string tc)
|
||||
:opacity (tinycolor/alpha tc)}
|
||||
(tinycolor/->hex-string tc))))
|
||||
|
||||
(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}]
|
||||
(when (and resolved-value (cft/color-token? token))
|
||||
(color-bullet-color resolved-value)))
|
||||
@@ -1,4 +1,10 @@
|
||||
(ns app.main.ui.workspace.tokens.errors
|
||||
;; 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.data.workspace.tokens.errors
|
||||
(:require
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cuerdas.core :as str]))
|
||||
@@ -4,7 +4,7 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.data.tokens
|
||||
(ns app.main.data.workspace.tokens.library-edit
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
@@ -18,7 +18,7 @@
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.notifications :as ntf]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.main.data.workspace.tokens.propagation :as dwtp]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
@@ -123,7 +123,7 @@
|
||||
(pcb/update-active-token-themes active-token-themes' prev-active-token-themes))]
|
||||
(rx/of
|
||||
(dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn delete-token-theme [group theme-name]
|
||||
(ptk/reify ::delete-token-theme
|
||||
@@ -135,7 +135,7 @@
|
||||
(pcb/set-token-theme group theme-name nil))]
|
||||
(rx/of
|
||||
(dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn create-token-set
|
||||
[set-name]
|
||||
@@ -221,7 +221,7 @@
|
||||
(clt/generate-toggle-token-set tlib name))]
|
||||
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn toggle-token-set-group [group-path]
|
||||
(ptk/reify ::toggle-token-set-group
|
||||
@@ -233,7 +233,7 @@
|
||||
(clt/generate-toggle-token-set-group (get-tokens-lib state) group-path))]
|
||||
(rx/of
|
||||
(dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn import-tokens-lib [lib]
|
||||
(ptk/reify ::import-tokens-lib
|
||||
@@ -244,7 +244,7 @@
|
||||
(pcb/with-library-data data)
|
||||
(pcb/set-tokens-lib lib))]
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn delete-token-set-path
|
||||
[group? path]
|
||||
@@ -256,7 +256,7 @@
|
||||
(pcb/with-library-data data)
|
||||
(pcb/set-token-set (ctob/join-set-path path) group? nil))]
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens))))))
|
||||
(dwtp/propagate-workspace-tokens))))))
|
||||
|
||||
(defn drop-error [{:keys [error to-path]}]
|
||||
(ptk/reify ::drop-error
|
||||
@@ -283,7 +283,7 @@
|
||||
(when-let [changes (clt/generate-move-token-set-group (pcb/empty-changes it) (get-tokens-lib state) drop-opts)]
|
||||
(rx/of
|
||||
(dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens)))
|
||||
(dwtp/propagate-workspace-tokens)))
|
||||
(catch :default e
|
||||
(rx/of
|
||||
(drop-error (ex-data e))))))))
|
||||
@@ -300,7 +300,7 @@
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(clt/generate-move-token-set tokens-lib params))]
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(wtu/update-workspace-tokens)))
|
||||
(dwtp/propagate-workspace-tokens)))
|
||||
(catch :default cause
|
||||
(rx/of (drop-error (ex-data cause))))))))
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.tokens.update
|
||||
(ns app.main.data.workspace.tokens.propagation
|
||||
(:require
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.logging :as l]
|
||||
[app.common.types.token :as ctt]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.thumbnails :as dwt]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as wtsd]
|
||||
[app.util.time :as dt]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.data :as data]
|
||||
@@ -24,21 +24,21 @@
|
||||
|
||||
;; Constants -------------------------------------------------------------------
|
||||
|
||||
(def filter-existing-values? false)
|
||||
(def ^:private filter-existing-values? false)
|
||||
|
||||
(def attributes->shape-update
|
||||
{ctt/border-radius-keys wtch/update-shape-radius-for-corners
|
||||
ctt/color-keys wtch/update-fill-stroke
|
||||
ctt/stroke-width-keys wtch/update-stroke-width
|
||||
ctt/sizing-keys wtch/update-shape-dimensions
|
||||
ctt/opacity-keys wtch/update-opacity
|
||||
#{:x :y} wtch/update-shape-position
|
||||
#{:p1 :p2 :p3 :p4} wtch/update-layout-padding
|
||||
#{:m1 :m2 :m3 :m4} wtch/update-layout-item-margin
|
||||
#{:column-gap :row-gap} wtch/update-layout-spacing
|
||||
#{:width :height} wtch/update-shape-dimensions
|
||||
#{:layout-item-min-w :layout-item-min-h :layout-item-max-w :layout-item-max-h} wtch/update-layout-sizing-limits
|
||||
ctt/rotation-keys wtch/update-rotation})
|
||||
(def ^:private attributes->shape-update
|
||||
{ctt/border-radius-keys dwta/update-shape-radius-for-corners
|
||||
ctt/color-keys dwta/update-fill-stroke
|
||||
ctt/stroke-width-keys dwta/update-stroke-width
|
||||
ctt/sizing-keys dwta/update-shape-dimensions
|
||||
ctt/opacity-keys dwta/update-opacity
|
||||
#{:x :y} dwta/update-shape-position
|
||||
#{:p1 :p2 :p3 :p4} dwta/update-layout-padding
|
||||
#{:m1 :m2 :m3 :m4} dwta/update-layout-item-margin
|
||||
#{:column-gap :row-gap} dwta/update-layout-spacing
|
||||
#{:width :height} dwta/update-shape-dimensions
|
||||
#{:layout-item-min-w :layout-item-min-h :layout-item-max-w :layout-item-max-h} dwta/update-layout-sizing-limits
|
||||
ctt/rotation-keys dwta/update-rotation})
|
||||
|
||||
(def attribute-actions-map
|
||||
(reduce
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
;; Helpers ---------------------------------------------------------------------
|
||||
|
||||
;; TODO: see if this can be replaced by more standard functions
|
||||
(defn deep-merge
|
||||
"Like d/deep-merge but unions set values."
|
||||
([a b]
|
||||
@@ -60,7 +61,7 @@
|
||||
|
||||
;; Data flows ------------------------------------------------------------------
|
||||
|
||||
(defn invert-collect-key-vals
|
||||
(defn- invert-collect-key-vals
|
||||
[xs resolved-tokens shape]
|
||||
(-> (reduce
|
||||
(fn [acc [k v]]
|
||||
@@ -74,7 +75,7 @@
|
||||
(update acc resolved-value (fnil conj #{}) k))))
|
||||
{} xs)))
|
||||
|
||||
(defn split-attribute-groups [attrs-values-map]
|
||||
(defn- split-attribute-groups [attrs-values-map]
|
||||
(reduce
|
||||
(fn [acc [attrs v]]
|
||||
(cond
|
||||
@@ -91,7 +92,7 @@
|
||||
attrs (assoc acc attrs v)))
|
||||
{} attrs-values-map))
|
||||
|
||||
(defn shape-ids-by-values
|
||||
(defn- shape-ids-by-values
|
||||
[attrs-values-map object-id]
|
||||
(->> (map (fn [[value attrs]] [attrs {value #{object-id}}]) attrs-values-map)
|
||||
(into {})))
|
||||
@@ -121,7 +122,6 @@
|
||||
|
||||
[tokens frame-ids text-ids])))
|
||||
|
||||
;; FIXME: revisit this
|
||||
(defn- actionize-shapes-update-info [page-id shapes-update-info]
|
||||
(mapcat (fn [[attrs update-infos]]
|
||||
(let [action (some attribute-actions-map attrs)]
|
||||
@@ -131,14 +131,15 @@
|
||||
update-infos)))
|
||||
shapes-update-info))
|
||||
|
||||
(defn update-tokens
|
||||
(defn propagate-tokens
|
||||
"Propagate tokens values to all shapes where they are applied"
|
||||
[state resolved-tokens]
|
||||
(let [file-id (get state :current-file-id)
|
||||
current-page-id (get state :current-page-id)
|
||||
fdata (dsh/lookup-file-data state file-id)
|
||||
tpoint (dt/tpoint-ms)]
|
||||
|
||||
(l/inf :status "START" :hint "update-tokens")
|
||||
(l/inf :status "START" :hint "propagate-tokens")
|
||||
(->> (rx/concat
|
||||
(rx/of current-page-id)
|
||||
(->> (rx/from (:pages fdata))
|
||||
@@ -155,7 +156,7 @@
|
||||
(actionize-shapes-update-info page-id attrs)]
|
||||
|
||||
(l/inf :status "PROGRESS"
|
||||
:hint "update-tokens"
|
||||
:hint "propagate-tokens"
|
||||
:page-id (str page-id)
|
||||
:elapsed (tpoint)
|
||||
::l/sync? true)
|
||||
@@ -175,21 +176,21 @@
|
||||
(rx/finalize
|
||||
(fn [_]
|
||||
(let [elapsed (tpoint)]
|
||||
(l/inf :status "END" :hint "update-tokens" :elapsed elapsed)))))))
|
||||
(l/inf :status "END" :hint "propagate-tokens" :elapsed elapsed)))))))
|
||||
|
||||
(defn update-workspace-tokens
|
||||
(defn propagate-workspace-tokens
|
||||
[]
|
||||
(ptk/reify ::update-workspace-tokens
|
||||
(ptk/reify ::propagate-workspace-tokens
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(when-let [tokens-lib (-> (dsh/lookup-file-data state)
|
||||
(get :tokens-lib))]
|
||||
(let [tokens (-> (ctob/get-active-themes-set-tokens tokens-lib)
|
||||
(wtsd/resolve-tokens+))]
|
||||
(sd/resolve-tokens+))]
|
||||
(->> (rx/from tokens)
|
||||
(rx/mapcat (fn [sd-tokens]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/concat
|
||||
(rx/of (dwu/start-undo-transaction undo-id :timeout false))
|
||||
(update-tokens state sd-tokens)
|
||||
(propagate-tokens state sd-tokens)
|
||||
(rx/of (dwu/commit-undo-transaction undo-id))))))))))))
|
||||
@@ -11,7 +11,7 @@
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.helpers :as dsh]))
|
||||
|
||||
(defn get-selected-token-set-name [state]
|
||||
(defn- get-selected-token-set-name [state]
|
||||
(or (get-in state [:workspace-tokens :selected-token-set-name])
|
||||
(some-> (dsh/lookup-file-data state)
|
||||
(get :tokens-lib)
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
(ns app.main.ui.workspace.tokens.warnings
|
||||
;; 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.data.workspace.tokens.warnings
|
||||
(:require
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cuerdas.core :as str]))
|
||||
@@ -198,7 +198,7 @@
|
||||
}
|
||||
|
||||
.import-error-disclaimer {
|
||||
color: var(--color-foreground-primary);
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.import-error-list {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
[app.main.ui.releases.v2-4]
|
||||
[app.main.ui.releases.v2-5]
|
||||
[app.main.ui.releases.v2-6]
|
||||
[app.main.ui.releases.v2-7]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as tm]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -97,4 +98,4 @@
|
||||
|
||||
(defmethod rc/render-release-notes "0.0"
|
||||
[params]
|
||||
(rc/render-release-notes (assoc params :version "2.6")))
|
||||
(rc/render-release-notes (assoc params :version "2.7")))
|
||||
|
||||
142
frontend/src/app/main/ui/releases/v2_7.cljs
Normal file
142
frontend/src/app/main/ui/releases/v2_7.cljs
Normal file
@@ -0,0 +1,142 @@
|
||||
;; 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.releases.v2-7
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.releases.common :as c]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defmethod c/render-release-notes "2.7"
|
||||
[{:keys [slide klass next finish navigate version]}]
|
||||
(mf/html
|
||||
(case slide
|
||||
:start
|
||||
[:div {:class (stl/css-case :modal-overlay true)}
|
||||
[:div.animated {:class klass}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:img {:src "images/features/2.7-slide-0.jpg"
|
||||
:class (stl/css :start-image)
|
||||
:border "0"
|
||||
:alt "Design Tokens make their debut in Penpot!"}]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
"What’s new in Penpot?"]
|
||||
|
||||
[:div {:class (stl/css :version-tag)}
|
||||
(dm/str "Version " version)]]
|
||||
|
||||
[:div {:class (stl/css :features-block)}
|
||||
[:span {:class (stl/css :feature-title)}
|
||||
"Penpot 2.7 is out!"]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"After the huge excitement around our last release. The first-ever native Design Tokens support in a design tool (yay!), we’re keeping the momentum going with a fresh batch of new features and improvements."]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"This update brings the first set of upgrades to our new Design Tokens system, a few of the many to come. We’ve also expanded who can create sharing prototype links and improved the invitations area. Last but not least, we fixed a bunch of bugs and optimizations that will make the experience more enjoyable for all."]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"Let’s dive in!"]]
|
||||
|
||||
[:div {:class (stl/css :navigation)}
|
||||
[:button {:class (stl/css :next-btn)
|
||||
:on-click next} "Continue"]]]]]]
|
||||
|
||||
0
|
||||
[:div {:class (stl/css-case :modal-overlay true)}
|
||||
[:div.animated {:class klass}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:img {:src "images/features/2.7-duplicate-set.gif"
|
||||
:class (stl/css :start-image)
|
||||
:border "0"
|
||||
:alt "Design Tokens improvements"}]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
"Design Tokens improvements"]]
|
||||
|
||||
[:div {:class (stl/css :feature)}
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"It hasn’t been long since we launched Design Tokens in Penpot (the first native Design Tokens support in a design tool!), and we’re already rolling out the first set of improvements."]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"The highlight: you can now duplicate token sets directly from a menu item. A huge time-saver, especially when working from existing sets. We’ve also made it easier to create themes by letting you select their set right away, and we’ve polished some info indicators to make everything a bit clearer. Plus, we’ve fixed a bunch of early-stage bugs to keep things running smoothly."]]
|
||||
|
||||
[:div {:class (stl/css :navigation)}
|
||||
[:& c/navigation-bullets
|
||||
{:slide slide
|
||||
:navigate navigate
|
||||
:total 3}]
|
||||
|
||||
[:button {:on-click next
|
||||
:class (stl/css :next-btn)} "Continue"]]]]]]
|
||||
|
||||
1
|
||||
[:div {:class (stl/css-case :modal-overlay true)}
|
||||
[:div.animated {:class klass}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:img {:src "images/features/2.7-share.gif"
|
||||
:class (stl/css :start-image)
|
||||
:border "0"
|
||||
:alt "Editors and viewers can now create Share prototype links"}]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
"Editors and viewers can now create Share prototype links"]]
|
||||
|
||||
[:div {:class (stl/css :feature)}
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"From now on, both editors and viewers can create Share Prototype links. Sharing prototypes is key for better team collaboration, no matter the role. It’s a common need, team members often have to share presentations without risking any accidental changes to the designs, which means they don’t necessarily need editing permissions. In the future, Penpot will introduce more fine-grained control over these permissions."]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"This update gives editors and viewers the same ability to configure, create, copy, and delete sharing links. A capability that, until now, was limited to owners and admins."]]
|
||||
|
||||
[:div {:class (stl/css :navigation)}
|
||||
[:& c/navigation-bullets
|
||||
{:slide slide
|
||||
:navigate navigate
|
||||
:total 3}]
|
||||
|
||||
[:button {:on-click next
|
||||
:class (stl/css :next-btn)} "Continue"]]]]]]
|
||||
|
||||
2
|
||||
[:div {:class (stl/css-case :modal-overlay true)}
|
||||
[:div.animated {:class klass}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:img {:src "images/features/2.7-invitations.gif"
|
||||
:class (stl/css :start-image)
|
||||
:border "0"
|
||||
:alt "A clearer way to invite your first team members"}]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
"A clearer way to invite your first team members"]]
|
||||
[:div {:class (stl/css :feature)}
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"Penpot works perfectly for solo projects, but it’s always more fun with a team. That’s why we’ve updated the initial state of the invitations area. Instead of starting blank, it now offers clearer guidance to help you invite your first team members."]
|
||||
|
||||
[:p {:class (stl/css :feature-content)}
|
||||
"This improvement in design and UX writing comes from community member Prithvi Tharun (credit where it’s due!) Not all open source contributions are about code, and this is a fantastic example of how design and writing make a real difference too."]]
|
||||
|
||||
[:div {:class (stl/css :navigation)}
|
||||
|
||||
[:& c/navigation-bullets
|
||||
{:slide slide
|
||||
:navigate navigate
|
||||
:total 3}]
|
||||
|
||||
[:button {:on-click finish
|
||||
:class (stl/css :next-btn)} "Let's go"]]]]]])))
|
||||
|
||||
102
frontend/src/app/main/ui/releases/v2_7.scss
Normal file
102
frontend/src/app/main/ui/releases/v2_7.scss
Normal file
@@ -0,0 +1,102 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.modal-overlay {
|
||||
@extend .modal-overlay-base;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
display: grid;
|
||||
grid-template-columns: $s-324 1fr;
|
||||
height: $s-500;
|
||||
width: $s-888;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--modal-background-color);
|
||||
border: $s-2 solid var(--modal-border-color);
|
||||
}
|
||||
|
||||
.start-image {
|
||||
width: $s-324;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
padding: $s-40;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr $s-32;
|
||||
gap: $s-24;
|
||||
|
||||
a {
|
||||
color: var(--button-primary-background-color-rest);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: grid;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.version-tag {
|
||||
@include flexCenter;
|
||||
@include headlineSmallTypography;
|
||||
height: $s-32;
|
||||
width: $s-96;
|
||||
background-color: var(--communication-tag-background-color);
|
||||
color: var(--communication-tag-foreground-color);
|
||||
border-radius: $br-8;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@include headlineLargeTypography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.features-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-16;
|
||||
width: $s-440;
|
||||
}
|
||||
|
||||
.feature {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
@include bodyLargeTypography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.feature-content {
|
||||
@include bodyMediumTypography;
|
||||
margin: 0;
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.feature-list {
|
||||
@include bodyMediumTypography;
|
||||
color: var(--modal-text-foreground-color);
|
||||
list-style: disc;
|
||||
display: grid;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-areas: "bullets button";
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
@extend .button-primary;
|
||||
width: $s-100;
|
||||
justify-self: flex-end;
|
||||
grid-area: button;
|
||||
}
|
||||
@@ -127,6 +127,7 @@
|
||||
width: $s-28;
|
||||
margin-left: $s-8;
|
||||
background-color: var(--viewer-controls-background-color);
|
||||
pointer-events: all;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
|
||||
@@ -586,10 +586,10 @@
|
||||
|
||||
(mf/with-effect []
|
||||
(st/emit! (st/emit! (dsc/push-shortcuts ::colorpicker sc/shortcuts)))
|
||||
#(do
|
||||
(st/emit! (dsc/pop-shortcuts ::colorpicker))
|
||||
(when (and @dirty? @last-change on-close)
|
||||
(on-close @last-change))))
|
||||
(fn []
|
||||
(st/emit! (dsc/pop-shortcuts ::colorpicker))
|
||||
(when (and @dirty? @last-change on-close)
|
||||
(on-close @last-change))))
|
||||
|
||||
[:div {:class (stl/css :colorpicker-tooltip)
|
||||
:data-testid "colorpicker"
|
||||
|
||||
@@ -618,7 +618,7 @@
|
||||
[:> dropdown-menu-item* {:class (stl/css :submenu-item)
|
||||
:on-click on-pin-version
|
||||
:on-key-down on-pin-version-key-down
|
||||
:id "file-menu-show-version-history"}
|
||||
:id "file-menu-create-version"}
|
||||
[:span {:class (stl/css :item-name)}
|
||||
(tr "dashboard.create-version-menu")]]
|
||||
|
||||
@@ -627,7 +627,10 @@
|
||||
:on-key-down on-show-version-history-key-down
|
||||
:id "file-menu-show-version-history"}
|
||||
[:span {:class (stl/css :item-name)}
|
||||
(tr "dashboard.show-version-history")]]
|
||||
(tr "dashboard.show-version-history")]
|
||||
[:span {:class (stl/css :shortcut)}
|
||||
(for [sc (scd/split-sc (sc/get-tooltip :toggle-history))]
|
||||
[:span {:class (stl/css :shortcut-key) :key sc} sc])]]
|
||||
|
||||
[:div {:class (stl/css :separator)}]])
|
||||
|
||||
@@ -786,6 +789,7 @@
|
||||
on-power-up-click
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "explore-pricing-click" ::ev/origin "workspace-menu"}))
|
||||
(dom/open-new-window "https://penpot.app/pricing")))
|
||||
|
||||
toggle-flag
|
||||
@@ -900,14 +904,16 @@
|
||||
:id "file-menu-help-info"}
|
||||
[:span {:class (stl/css :item-name)} (tr "workspace.header.menu.option.help-info")]
|
||||
[:span {:class (stl/css :open-arrow)} i/arrow]]
|
||||
[:> dropdown-menu-item* {:class (stl/css-case :menu-item true)
|
||||
:on-click on-power-up-click
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-power-up-click)))
|
||||
:on-pointer-enter close-sub-menu
|
||||
:id "file-menu-power-up"}
|
||||
[:span {:class (stl/css :item-name)} (tr "workspace.header.menu.option.power-up")]]]
|
||||
;; TODO remove this block when subscriptions is full implemented
|
||||
(when (contains? cf/flags :subscriptions-old)
|
||||
[:> dropdown-menu-item* {:class (stl/css-case :menu-item true)
|
||||
:on-click on-power-up-click
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-power-up-click)))
|
||||
:on-pointer-enter close-sub-menu
|
||||
:id "file-menu-power-up"}
|
||||
[:span {:class (stl/css :item-name)} (tr "workspace.header.menu.option.power-up")]])]
|
||||
|
||||
(case sub-menu
|
||||
:file
|
||||
|
||||
@@ -85,6 +85,7 @@ $width-settings-bar-max: $s-500;
|
||||
}
|
||||
|
||||
.resize-area-horiz {
|
||||
background-color: var(--panel-background-color);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
;; 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.common
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.data.shortcuts :as dsc]
|
||||
[app.main.store :as st]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.globals :as globals]
|
||||
[app.util.keyboard :as kbd]
|
||||
[cuerdas.core :as str]
|
||||
[goog.events :as events]
|
||||
[rumext.v2 :as mf])
|
||||
(:import goog.events.EventType))
|
||||
|
||||
;; Helpers ---------------------------------------------------------------------
|
||||
|
||||
(defn camel-keys [m]
|
||||
(->> m
|
||||
(d/deep-mapm
|
||||
(fn [[k v]]
|
||||
(if (or (keyword? k) (string? k))
|
||||
[(keyword (str/camel (name k))) v]
|
||||
[k v])))))
|
||||
|
||||
(defn direction-select
|
||||
"Returns next `n` in `direction` while wrapping around at the last item at the count of `coll`.
|
||||
|
||||
`direction` accepts `:up` or `:down`."
|
||||
[direction n coll]
|
||||
(let [last-n (dec (count coll))
|
||||
next-n (case direction
|
||||
:up (dec n)
|
||||
:down (inc n))
|
||||
wrap-around-n (cond
|
||||
(neg? next-n) last-n
|
||||
(> next-n last-n) 0
|
||||
:else next-n)]
|
||||
wrap-around-n))
|
||||
|
||||
(defn use-arrow-highlight [{:keys [shortcuts-key options on-select]}]
|
||||
(let [highlighted* (mf/use-state nil)
|
||||
highlighted (deref highlighted*)
|
||||
on-dehighlight #(reset! highlighted* nil)
|
||||
on-keyup (fn [event]
|
||||
(cond
|
||||
(and (kbd/enter? event) highlighted) (on-select (nth options highlighted))
|
||||
(kbd/up-arrow? event) (do
|
||||
(dom/prevent-default event)
|
||||
(->> (direction-select :up (or highlighted 0) options)
|
||||
(reset! highlighted*)))
|
||||
(kbd/down-arrow? event) (do
|
||||
(dom/prevent-default event)
|
||||
(->> (direction-select :down (or highlighted -1) options)
|
||||
(reset! highlighted*)))))]
|
||||
(mf/with-effect [highlighted]
|
||||
(let [shortcuts-key shortcuts-key
|
||||
keys [(events/listen globals/document EventType.KEYUP on-keyup)
|
||||
(events/listen globals/document EventType.KEYDOWN dom/prevent-default)]]
|
||||
(st/emit! (dsc/push-shortcuts shortcuts-key {}))
|
||||
(fn []
|
||||
(doseq [key keys]
|
||||
(events/unlistenByKey key))
|
||||
(st/emit! (dsc/pop-shortcuts shortcuts-key)))))
|
||||
{:highlighted highlighted
|
||||
:on-dehighlight on-dehighlight}))
|
||||
@@ -7,8 +7,8 @@
|
||||
(ns app.main.ui.workspace.tokens.components.controls.input-token-color-bullet
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.data.workspace.tokens.color :as dwtc]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private schema::input-token-color-bullet
|
||||
@@ -23,6 +23,6 @@
|
||||
[:div {:data-testid "token-form-color-bullet"
|
||||
:class (stl/css :input-token-color-bullet)
|
||||
:on-click on-click}
|
||||
(if-let [color' (wtt/color-bullet-color color)]
|
||||
(if-let [color' (dwtc/color-bullet-color color)]
|
||||
[:> color-bullet {:color color' :mini true}]
|
||||
[:div {:class (stl/css :input-token-color-bullet-placeholder)}])])
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.timers :as timers]
|
||||
@@ -30,15 +30,15 @@
|
||||
;; Actions ---------------------------------------------------------------------
|
||||
|
||||
(defn attribute-actions [token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
(let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} (map :id selected-shapes))]
|
||||
{:all-selected? (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)
|
||||
{:all-selected? (cft/shapes-applied-all? ids-by-attributes shape-ids attributes)
|
||||
:shape-ids shape-ids
|
||||
:selected-pred #(seq (% ids-by-attributes))}))
|
||||
|
||||
(defn generic-attribute-actions [attributes title {:keys [token selected-shapes on-update-shape hint]}]
|
||||
(let [on-update-shape-fn (or on-update-shape
|
||||
(-> (wtch/get-token-properties token)
|
||||
(-> (dwta/get-token-properties token)
|
||||
(:on-update-shape)))
|
||||
{:keys [selected-pred shape-ids]} (attribute-actions token selected-shapes attributes)]
|
||||
(map (fn [attribute]
|
||||
@@ -52,8 +52,8 @@
|
||||
:selected? selected?
|
||||
:action (fn []
|
||||
(if selected?
|
||||
(st/emit! (wtch/unapply-token props))
|
||||
(st/emit! (wtch/apply-token (assoc props :on-update-shape on-update-shape-fn)))))}))
|
||||
(st/emit! (dwta/unapply-token props))
|
||||
(st/emit! (dwta/apply-token (assoc props :on-update-shape on-update-shape-fn)))))}))
|
||||
attributes)))
|
||||
|
||||
(defn all-or-separate-actions [{:keys [attribute-labels on-update-shape-all on-update-shape hint]}
|
||||
@@ -67,8 +67,8 @@
|
||||
:selected? all-selected?
|
||||
:hint hint
|
||||
:action #(if all-selected?
|
||||
(st/emit! (wtch/unapply-token props))
|
||||
(st/emit! (wtch/apply-token (assoc props :on-update-shape (or on-update-shape-all on-update-shape)))))})
|
||||
(st/emit! (dwta/unapply-token props))
|
||||
(st/emit! (dwta/apply-token (assoc props :on-update-shape (or on-update-shape-all on-update-shape)))))})
|
||||
single-actions (map (fn [[attr title]]
|
||||
(let [selected? (selected-pred attr)]
|
||||
{:title title
|
||||
@@ -78,10 +78,10 @@
|
||||
:shape-ids shape-ids}
|
||||
event (cond
|
||||
all-selected? (-> (assoc props :attributes-to-remove attributes)
|
||||
(wtch/apply-token))
|
||||
selected? (wtch/unapply-token props)
|
||||
(dwta/apply-token))
|
||||
selected? (dwta/unapply-token props)
|
||||
:else (-> (assoc props :on-update-shape on-update-shape)
|
||||
(wtch/apply-token)))]
|
||||
(dwta/apply-token)))]
|
||||
(st/emit! event))}))
|
||||
attribute-labels)]
|
||||
(concat [all-action] single-actions)))
|
||||
@@ -105,17 +105,17 @@
|
||||
:token token
|
||||
:shape-ids shape-ids}]
|
||||
(if all-selected?
|
||||
(st/emit! (wtch/unapply-token props))
|
||||
(st/emit! (wtch/apply-token (assoc props :on-update-shape on-update-shape))))))}
|
||||
(st/emit! (dwta/unapply-token props))
|
||||
(st/emit! (dwta/apply-token (assoc props :on-update-shape on-update-shape))))))}
|
||||
{:title "Horizontal"
|
||||
:selected? horizontal-selected?
|
||||
:action (fn []
|
||||
(let [props {:token token
|
||||
:shape-ids shape-ids}
|
||||
event (cond
|
||||
all-selected? (wtch/apply-token (assoc props :attributes-to-remove vertical-attrs))
|
||||
horizontal-selected? (wtch/apply-token (assoc props :attributes-to-remove horizontal-attrs))
|
||||
:else (wtch/apply-token (assoc props
|
||||
all-selected? (dwta/apply-token (assoc props :attributes-to-remove vertical-attrs))
|
||||
horizontal-selected? (dwta/apply-token (assoc props :attributes-to-remove horizontal-attrs))
|
||||
:else (dwta/apply-token (assoc props
|
||||
:attributes horizontal-attrs
|
||||
:on-update-shape on-update-shape)))]
|
||||
(st/emit! event)))}
|
||||
@@ -125,9 +125,9 @@
|
||||
(let [props {:token token
|
||||
:shape-ids shape-ids}
|
||||
event (cond
|
||||
all-selected? (wtch/apply-token (assoc props :attributes-to-remove horizontal-attrs))
|
||||
vertical-selected? (wtch/apply-token (assoc props :attributes-to-remove vertical-attrs))
|
||||
:else (wtch/apply-token (assoc props
|
||||
all-selected? (dwta/apply-token (assoc props :attributes-to-remove horizontal-attrs))
|
||||
vertical-selected? (dwta/apply-token (assoc props :attributes-to-remove vertical-attrs))
|
||||
:else (dwta/apply-token (assoc props
|
||||
:attributes vertical-attrs
|
||||
:on-update-shape on-update-shape)))]
|
||||
(st/emit! event)))}]
|
||||
@@ -147,10 +147,10 @@
|
||||
:shape-ids shape-ids}
|
||||
event (cond
|
||||
all-selected? (-> (assoc props :attributes-to-remove attrs)
|
||||
(wtch/apply-token))
|
||||
selected? (wtch/unapply-token props)
|
||||
(dwta/apply-token))
|
||||
selected? (dwta/unapply-token props)
|
||||
:else (-> (assoc props :on-update-shape on-update-shape)
|
||||
(wtch/apply-token)))]
|
||||
(dwta/apply-token)))]
|
||||
(st/emit! event))}))
|
||||
all-attr-labels)]
|
||||
(concat multi-items single-items)))
|
||||
@@ -159,13 +159,13 @@
|
||||
(st/emit!
|
||||
(when (= (count attributes) 1)
|
||||
(dwsl/update-layout shape-ids {:layout-padding-type :multiple}))
|
||||
(wtch/update-layout-padding value shape-ids attributes)))
|
||||
(dwta/update-layout-padding value shape-ids attributes)))
|
||||
|
||||
(defn update-shape-layout-margin [value shape-ids attributes]
|
||||
(st/emit!
|
||||
(when (= (count attributes) 1)
|
||||
(dwsl/update-layout shape-ids {:layout-item-margin-type :multiple}))
|
||||
(wtch/update-layout-item-margin value shape-ids attributes)))
|
||||
(dwta/update-layout-item-margin value shape-ids attributes)))
|
||||
|
||||
(defn spacing-attribute-actions [{:keys [token selected-shapes] :as context-data}]
|
||||
(let [padding-items (layout-spacing-items {:token token
|
||||
@@ -195,7 +195,7 @@
|
||||
gap-items (all-or-separate-actions {:attribute-labels {:column-gap "Column Gap"
|
||||
:row-gap "Row Gap"}
|
||||
:hint (tr "workspace.token.gaps")
|
||||
:on-update-shape wtch/update-layout-spacing}
|
||||
:on-update-shape dwta/update-layout-spacing}
|
||||
context-data)]
|
||||
(concat gap-items
|
||||
[:separator]
|
||||
@@ -208,25 +208,25 @@
|
||||
(all-or-separate-actions {:attribute-labels {:width "Width"
|
||||
:height "Height"}
|
||||
:hint (tr "workspace.token.size")
|
||||
:on-update-shape wtch/update-shape-dimensions}
|
||||
:on-update-shape dwta/update-shape-dimensions}
|
||||
context-data)
|
||||
[:separator]
|
||||
(all-or-separate-actions {:attribute-labels {:layout-item-min-w "Min Width"
|
||||
:layout-item-min-h "Min Height"}
|
||||
:hint (tr "workspace.token.min-size")
|
||||
:on-update-shape wtch/update-layout-sizing-limits}
|
||||
:on-update-shape dwta/update-layout-sizing-limits}
|
||||
context-data)
|
||||
[:separator]
|
||||
(all-or-separate-actions {:attribute-labels {:layout-item-max-w "Max Width"
|
||||
:layout-item-max-h "Max Height"}
|
||||
:hint (tr "workspace.token.max-size")
|
||||
:on-update-shape wtch/update-layout-sizing-limits}
|
||||
:on-update-shape dwta/update-layout-sizing-limits}
|
||||
context-data)))
|
||||
|
||||
(defn update-shape-radius-for-corners [value shape-ids attributes]
|
||||
(st/emit!
|
||||
(ptk/data-event :expand-border-radius)
|
||||
(wtch/update-shape-radius-for-corners value shape-ids attributes)))
|
||||
(dwta/update-shape-radius-for-corners value shape-ids attributes)))
|
||||
|
||||
(def shape-attribute-actions-map
|
||||
(let [stroke-width (partial generic-attribute-actions #{:stroke-width} "Stroke Width")]
|
||||
@@ -235,11 +235,11 @@
|
||||
:r4 "Bottom Left"
|
||||
:r3 "Bottom Right"}
|
||||
:hint (tr "workspace.token.radius")
|
||||
:on-update-shape-all wtch/update-shape-radius-all
|
||||
:on-update-shape-all dwta/update-shape-radius-all
|
||||
:on-update-shape update-shape-radius-for-corners})
|
||||
:color (fn [context-data]
|
||||
[(generic-attribute-actions #{:fill} "Fill" (assoc context-data :on-update-shape wtch/update-fill :hint (tr "workspace.token.color")))
|
||||
(generic-attribute-actions #{:stroke-color} "Stroke" (assoc context-data :on-update-shape wtch/update-stroke-color))])
|
||||
[(generic-attribute-actions #{:fill} "Fill" (assoc context-data :on-update-shape dwta/update-fill :hint (tr "workspace.token.color")))
|
||||
(generic-attribute-actions #{:stroke-color} "Stroke" (assoc context-data :on-update-shape dwta/update-stroke-color))])
|
||||
:spacing spacing-attribute-actions
|
||||
:sizing sizing-attribute-actions
|
||||
:rotation (partial generic-attribute-actions #{:rotation} "Rotation")
|
||||
@@ -252,19 +252,19 @@
|
||||
:separator
|
||||
{:title "Border Radius" :submenu :border-radius}]
|
||||
[:separator]
|
||||
(stroke-width (assoc context-data :on-update-shape wtch/update-stroke-width))
|
||||
(stroke-width (assoc context-data :on-update-shape dwta/update-stroke-width))
|
||||
[:separator]
|
||||
(generic-attribute-actions #{:x} "X" (assoc context-data :on-update-shape wtch/update-shape-position :hint (tr "workspace.token.axis")))
|
||||
(generic-attribute-actions #{:y} "Y" (assoc context-data :on-update-shape wtch/update-shape-position))))}))
|
||||
(generic-attribute-actions #{:x} "X" (assoc context-data :on-update-shape dwta/update-shape-position :hint (tr "workspace.token.axis")))
|
||||
(generic-attribute-actions #{:y} "Y" (assoc context-data :on-update-shape dwta/update-shape-position))))}))
|
||||
|
||||
(defn default-actions [{:keys [token selected-token-set-name]}]
|
||||
(let [{:keys [modal]} (wtch/get-token-properties token)]
|
||||
(let [{:keys [modal]} (dwta/get-token-properties token)]
|
||||
[{:title (tr "workspace.token.edit")
|
||||
:no-selectable true
|
||||
:action (fn [event]
|
||||
(let [{:keys [key fields]} modal]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/assign-token-context-menu nil)
|
||||
(st/emit! (dwtl/assign-token-context-menu nil)
|
||||
(modal/show key {:x (.-clientX ^js event)
|
||||
:y (.-clientY ^js event)
|
||||
:position :right
|
||||
@@ -274,10 +274,10 @@
|
||||
:token token}))))}
|
||||
{:title (tr "workspace.token.duplicate")
|
||||
:no-selectable true
|
||||
:action #(st/emit! (dt/duplicate-token (:name token)))}
|
||||
:action #(st/emit! (dwtl/duplicate-token (:name token)))}
|
||||
{:title (tr "workspace.token.delete")
|
||||
:no-selectable true
|
||||
:action #(st/emit! (dt/delete-token
|
||||
:action #(st/emit! (dwtl/delete-token
|
||||
(ctob/prefixed-set-path-string->set-name-string selected-token-set-name)
|
||||
(:name token)))}]))
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
(mf/portal
|
||||
(mf/html
|
||||
[:& dropdown {:show is-open?
|
||||
:on-close #(st/emit! (dt/assign-token-context-menu nil))}
|
||||
:on-close #(st/emit! (dwtl/assign-token-context-menu nil))}
|
||||
[:div {:class (stl/css :token-context-menu)
|
||||
:data-testid "tokens-context-menu-for-token"
|
||||
:ref dropdown-ref
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
;; 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.core
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]))
|
||||
|
||||
;; Helpers ---------------------------------------------------------------------
|
||||
|
||||
(defn resolve-token-value [{:keys [value resolved-value] :as _token}]
|
||||
(or
|
||||
resolved-value
|
||||
(d/parse-double value)))
|
||||
|
||||
(defn maybe-resolve-token-value [{:keys [value] :as token}]
|
||||
(when value (resolve-token-value token)))
|
||||
|
||||
(defn tokens->select-options [{:keys [shape tokens attributes selected-attributes]}]
|
||||
(map
|
||||
(fn [{:keys [name] :as token}]
|
||||
(cond-> (assoc token :label name)
|
||||
(wtt/token-applied? token shape (or selected-attributes attributes)) (assoc :selected? true)))
|
||||
tokens))
|
||||
|
||||
(defn tokens-name-map->select-options [{:keys [shape tokens attributes selected-attributes]}]
|
||||
(map
|
||||
(fn [[_k {:keys [name] :as token}]]
|
||||
(cond-> (assoc token :label name)
|
||||
(wtt/token-applied? token shape (or selected-attributes attributes)) (assoc :selected? true)))
|
||||
tokens))
|
||||
@@ -10,9 +10,16 @@
|
||||
[app.common.colors :as c]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.data.tinycolor :as tinycolor]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.errors :as wte]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.data.workspace.tokens.propagation :as dwtp]
|
||||
[app.main.data.workspace.tokens.warnings :as wtw]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||
@@ -22,15 +29,8 @@
|
||||
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
|
||||
[app.main.ui.workspace.colorpicker :as colorpicker]
|
||||
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.components.controls.input-token-color-bullet :refer [input-token-color-bullet*]]
|
||||
[app.main.ui.workspace.tokens.components.controls.input-tokens :refer [input-tokens*]]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.main.ui.workspace.tokens.warnings :as wtw]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.functions :as uf]
|
||||
[app.util.i18n :refer [tr]]
|
||||
@@ -64,7 +64,7 @@
|
||||
(let [path-exists-schema
|
||||
(m/-simple-schema
|
||||
{:type :token/name-exists
|
||||
:pred #(not (wtt/token-name-path-exists? % tokens-tree))
|
||||
:pred #(not (cft/token-name-path-exists? % tokens-tree))
|
||||
:type-properties {:error/fn #(str "A token already exists at the path: " (:value %))}})]
|
||||
(m/schema
|
||||
[:and
|
||||
@@ -239,8 +239,8 @@
|
||||
[{:keys [token token-type action selected-token-set-name on-display-colorpicker]}]
|
||||
(let [create? (not (instance? ctob/Token token))
|
||||
token (or token {:type token-type})
|
||||
token-properties (wtch/get-token-properties token)
|
||||
color? (wtt/color-token? token)
|
||||
token-properties (dwta/get-token-properties token)
|
||||
color? (cft/color-token? token)
|
||||
selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens)
|
||||
|
||||
active-theme-tokens (cond-> (mf/deref refs/workspace-active-theme-sets-tokens)
|
||||
@@ -254,7 +254,7 @@
|
||||
:interactive? true})
|
||||
token-path (mf/use-memo
|
||||
(mf/deps (:name token))
|
||||
#(wtt/token-name->path (:name token)))
|
||||
#(cft/token-name->path (:name token)))
|
||||
|
||||
selected-set-tokens-tree (mf/use-memo
|
||||
(mf/deps token-path selected-set-tokens)
|
||||
@@ -329,7 +329,7 @@
|
||||
value-input-ref (mf/use-ref nil)
|
||||
value-ref (mf/use-var (:value token))
|
||||
|
||||
token-resolve-result* (mf/use-state (get resolved-tokens (wtt/token-identifier token)))
|
||||
token-resolve-result* (mf/use-state (get resolved-tokens (cft/token-identifier token)))
|
||||
token-resolve-result (deref token-resolve-result*)
|
||||
|
||||
set-resolve-value
|
||||
@@ -452,16 +452,16 @@
|
||||
(when (and (seq result) (not err))
|
||||
(st/emit!
|
||||
(if (ctob/token? token)
|
||||
(dt/update-token (:name token)
|
||||
{:name final-name
|
||||
:value final-value
|
||||
:description final-description})
|
||||
(dwtl/update-token (:name token)
|
||||
{:name final-name
|
||||
:value final-value
|
||||
:description final-description})
|
||||
|
||||
(dt/create-token {:name final-name
|
||||
:type token-type
|
||||
:value final-value
|
||||
:description final-description}))
|
||||
(wtu/update-workspace-tokens)
|
||||
(dwtl/create-token {:name final-name
|
||||
:type token-type
|
||||
:value final-value
|
||||
:description final-description}))
|
||||
(dwtp/propagate-workspace-tokens)
|
||||
(modal/hide)))))))))
|
||||
|
||||
on-delete-token
|
||||
@@ -470,7 +470,7 @@
|
||||
(fn [e]
|
||||
(dom/prevent-default e)
|
||||
(modal/hide!)
|
||||
(st/emit! (dt/delete-token (ctob/prefixed-set-path-string->set-name-string selected-token-set-name) (:name token)))))
|
||||
(st/emit! (dwtl/delete-token (ctob/prefixed-set-path-string->set-name-string selected-token-set-name) (:name token)))))
|
||||
|
||||
on-cancel
|
||||
(mf/use-fn
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.tokens :as wdt]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
||||
@@ -117,7 +117,7 @@
|
||||
(fn [e]
|
||||
(dom/prevent-default e)
|
||||
(dom/stop-propagation e)
|
||||
(st/emit! (wdt/delete-token-theme group name)))
|
||||
(st/emit! (dwtl/delete-token-theme group name)))
|
||||
on-edit-theme
|
||||
(fn [e]
|
||||
(dom/prevent-default e)
|
||||
@@ -131,7 +131,7 @@
|
||||
[:div {:on-click (fn [e]
|
||||
(dom/prevent-default e)
|
||||
(dom/stop-propagation e)
|
||||
(st/emit! (wdt/toggle-token-theme-active? group name)))}
|
||||
(st/emit! (dwtl/toggle-token-theme-active? group name)))}
|
||||
[:& switch {:name (tr "workspace.token.theme-name" name)
|
||||
:on-change (constantly nil)
|
||||
:selected? selected?}]]]
|
||||
@@ -292,7 +292,7 @@
|
||||
(mf/use-fn
|
||||
(mf/deps current-theme on-back)
|
||||
(fn []
|
||||
(st/emit! (wdt/delete-token-theme (:group current-theme) (:name current-theme)))
|
||||
(st/emit! (dwtl/delete-token-theme (:group current-theme) (:name current-theme)))
|
||||
(on-back)))
|
||||
|
||||
;; Sets tree handlers
|
||||
@@ -386,7 +386,7 @@
|
||||
(mf/use-fn
|
||||
(mf/deps theme)
|
||||
(fn [theme']
|
||||
(st/emit! (wdt/update-token-theme [(:group theme) (:name theme)] theme'))))]
|
||||
(st/emit! (dwtl/update-token-theme [(:group theme) (:name theme)] theme'))))]
|
||||
|
||||
[:> edit-create-theme*
|
||||
{:change-view change-view
|
||||
@@ -402,7 +402,7 @@
|
||||
(mf/use-fn
|
||||
(fn [theme]
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "create-tokens-theme"})
|
||||
(wdt/create-token-theme theme))))
|
||||
(dwtl/create-token-theme theme))))
|
||||
has-prev-view (has-prev-view (:prev-type state))]
|
||||
|
||||
[:> edit-create-theme*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
@@ -31,26 +31,26 @@
|
||||
|
||||
(defn- on-start-creation
|
||||
[]
|
||||
(st/emit! (dt/start-token-set-creation [])))
|
||||
(st/emit! (dwtl/start-token-set-creation [])))
|
||||
|
||||
(defn- on-toggle-token-set-click [name]
|
||||
(st/emit! (dt/toggle-token-set name)))
|
||||
(st/emit! (dwtl/toggle-token-set name)))
|
||||
|
||||
(defn- on-toggle-token-set-group-click [path]
|
||||
(st/emit! (dt/toggle-token-set-group path)))
|
||||
(st/emit! (dwtl/toggle-token-set-group path)))
|
||||
|
||||
(defn- on-select-token-set-click [name]
|
||||
(st/emit! (dt/set-selected-token-set-name name)))
|
||||
(st/emit! (dwtl/set-selected-token-set-name name)))
|
||||
|
||||
(defn on-update-token-set
|
||||
[token-set name]
|
||||
(st/emit! (dt/clear-token-set-edition)
|
||||
(dt/update-token-set token-set name)))
|
||||
(st/emit! (dwtl/clear-token-set-edition)
|
||||
(dwtl/update-token-set token-set name)))
|
||||
|
||||
(defn- on-update-token-set-group
|
||||
[path name]
|
||||
(st/emit! (dt/clear-token-set-edition)
|
||||
(dt/rename-token-set-group path name)))
|
||||
(st/emit! (dwtl/clear-token-set-edition)
|
||||
(dwtl/rename-token-set-group path name)))
|
||||
|
||||
(defn- on-create-token-set
|
||||
[parent-set name]
|
||||
@@ -63,7 +63,7 @@
|
||||
(ctob/normalize-set-name name))]
|
||||
|
||||
(st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name})
|
||||
(dt/create-token-set name))))
|
||||
(dwtl/create-token-set name))))
|
||||
|
||||
(defn group-edition-id
|
||||
"Prefix editing groups `edition-id` so it can be differentiated from sets with the same id."
|
||||
@@ -167,7 +167,7 @@
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(when (and can-edit? (not is-editing))
|
||||
(st/emit! (dt/assign-token-set-context-menu
|
||||
(st/emit! (dwtl/assign-token-set-context-menu
|
||||
{:position (dom/get-client-position event)
|
||||
:is-group true
|
||||
:id id
|
||||
@@ -270,7 +270,7 @@
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(when (and can-edit? (not is-editing))
|
||||
(st/emit! (dt/assign-token-set-context-menu
|
||||
(st/emit! (dwtl/assign-token-set-context-menu
|
||||
{:position (dom/get-client-position event)
|
||||
:is-group false
|
||||
:id id
|
||||
@@ -383,8 +383,8 @@
|
||||
:position position
|
||||
:collapsed-paths collapsed-paths}]
|
||||
(if (:is-group data)
|
||||
(st/emit! (dt/drop-token-set-group params))
|
||||
(st/emit! (dt/drop-token-set params))))))
|
||||
(st/emit! (dwtl/drop-token-set-group params))
|
||||
(st/emit! (dwtl/drop-token-set params))))))
|
||||
|
||||
on-toggle-collapse
|
||||
(mf/use-fn
|
||||
@@ -560,15 +560,15 @@
|
||||
(mf/deps can-edit?)
|
||||
(fn [_]
|
||||
(when can-edit?
|
||||
(st/emit! (dt/clear-token-set-edition)
|
||||
(dt/clear-token-set-creation)))))
|
||||
(st/emit! (dwtl/clear-token-set-edition)
|
||||
(dwtl/clear-token-set-creation)))))
|
||||
|
||||
on-start-edition
|
||||
(mf/use-fn
|
||||
(mf/deps can-edit?)
|
||||
(fn [id]
|
||||
(when can-edit?
|
||||
(st/emit! (dt/start-token-set-edition id)))))]
|
||||
(st/emit! (dwtl/start-token-set-edition id)))))]
|
||||
|
||||
[:> controlled-sets-list*
|
||||
{:token-sets token-sets
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
@@ -36,24 +36,24 @@
|
||||
{::mf/private true}
|
||||
[{:keys [is-group id edition-id path]}]
|
||||
(let [create-set-at-path
|
||||
(mf/use-fn (mf/deps path) #(st/emit! (dt/start-token-set-creation path)))
|
||||
(mf/use-fn (mf/deps path) #(st/emit! (dwtl/start-token-set-creation path)))
|
||||
|
||||
on-edit
|
||||
(mf/use-fn
|
||||
(mf/deps id)
|
||||
(fn []
|
||||
(st/emit! (dt/start-token-set-edition edition-id))))
|
||||
(st/emit! (dwtl/start-token-set-edition edition-id))))
|
||||
|
||||
on-duplicate
|
||||
(mf/use-fn
|
||||
(mf/deps is-group id)
|
||||
(fn []
|
||||
(st/emit! (dt/duplicate-token-set id is-group))))
|
||||
(st/emit! (dwtl/duplicate-token-set id is-group))))
|
||||
|
||||
on-delete
|
||||
(mf/use-fn
|
||||
(mf/deps is-group path)
|
||||
#(st/emit! (dt/delete-token-set-path is-group path)))]
|
||||
#(st/emit! (dwtl/delete-token-set-path is-group path)))]
|
||||
|
||||
[:ul {:class (stl/css :context-list)}
|
||||
(when is-group
|
||||
@@ -75,7 +75,7 @@
|
||||
(+ (dm/get-prop position :x) 5)
|
||||
|
||||
on-close
|
||||
(mf/use-fn #(st/emit! (dt/assign-token-set-context-menu nil)))]
|
||||
(mf/use-fn #(st/emit! (dwtl/assign-token-set-context-menu nil)))]
|
||||
|
||||
[:& dropdown {:show (some? position)
|
||||
:on-close on-close}
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.notifications :as ntf]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.errors :as wte]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]]
|
||||
@@ -26,12 +29,9 @@
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.context-menu :refer [token-context-menu]]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.sets :as tsets]
|
||||
[app.main.ui.workspace.tokens.sets-context-menu :refer [token-set-context-menu*]]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.theme-select :refer [theme-select]]
|
||||
[app.main.ui.workspace.tokens.token-pill :refer [token-pill*]]
|
||||
[app.util.array :as array]
|
||||
@@ -70,7 +70,7 @@
|
||||
{::mf/private true}
|
||||
[{:keys [type tokens selected-shapes active-theme-tokens is-open]}]
|
||||
(let [{:keys [modal title]}
|
||||
(get wtch/token-properties type)
|
||||
(get dwta/token-properties type)
|
||||
|
||||
can-edit?
|
||||
(mf/use-ctx ctx/can-edit?)
|
||||
@@ -83,7 +83,7 @@
|
||||
(mf/use-fn
|
||||
(fn [event token]
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (dt/assign-token-context-menu
|
||||
(st/emit! (dwtl/assign-token-context-menu
|
||||
{:type :token
|
||||
:position (dom/get-client-position event)
|
||||
:errors (:errors token)
|
||||
@@ -92,14 +92,14 @@
|
||||
on-toggle-open-click
|
||||
(mf/use-fn
|
||||
(mf/deps is-open type)
|
||||
#(st/emit! (dt/set-token-type-section-open type (not is-open))))
|
||||
#(st/emit! (dwtl/set-token-type-section-open type (not is-open))))
|
||||
|
||||
on-popover-open-click
|
||||
(mf/use-fn
|
||||
(mf/deps type title modal)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/set-token-type-section-open type true)
|
||||
(st/emit! (dwtl/set-token-type-section-open type true)
|
||||
;; FIXME: use dom/get-client-position
|
||||
(modal/show (:key modal)
|
||||
{:x (.-clientX ^js event)
|
||||
@@ -116,7 +116,7 @@
|
||||
(fn [event token]
|
||||
(dom/stop-propagation event)
|
||||
(when (seq selected-shapes)
|
||||
(st/emit! (wtch/toggle-token {:token token
|
||||
(st/emit! (dwta/toggle-token {:token token
|
||||
:shapes selected-shapes})))))]
|
||||
|
||||
[:div {:on-click on-toggle-open-click :class (stl/css :token-section-wrapper)}
|
||||
@@ -151,7 +151,7 @@
|
||||
[tokens-by-type]
|
||||
(loop [empty #js []
|
||||
filled #js []
|
||||
types (-> wtch/token-properties keys seq)]
|
||||
types (-> dwta/token-properties keys seq)]
|
||||
(if-let [type (first types)]
|
||||
(if (not-empty (get tokens-by-type type))
|
||||
(recur empty
|
||||
@@ -325,7 +325,7 @@
|
||||
(let [match (->> (ctob/get-sets tokens-lib)
|
||||
(first)
|
||||
(:name))]
|
||||
(st/emit! (dt/set-selected-token-set-name match)))))
|
||||
(st/emit! (dwtl/set-selected-token-set-name match)))))
|
||||
|
||||
[:*
|
||||
[:& token-context-menu]
|
||||
@@ -394,7 +394,7 @@
|
||||
(sd/process-json-stream {:file-name file-name})
|
||||
(rx/subs! (fn [lib]
|
||||
(st/emit! (ptk/data-event ::ev/event {::ev/name "import-tokens"})
|
||||
(dt/import-tokens-lib lib)))
|
||||
(dwtl/import-tokens-lib lib)))
|
||||
(fn [err]
|
||||
(js/console.error err)
|
||||
(st/emit! (ntf/show {:content (wte/humanize-errors [(ex-data err)])
|
||||
|
||||
@@ -193,12 +193,14 @@
|
||||
}
|
||||
|
||||
.resize-area-horiz {
|
||||
background-color: var(--panel-background-color);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: $s-3 0 $s-1 0;
|
||||
height: $s-6;
|
||||
cursor: ns-resize;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.resize-handle-horiz {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.tokens :as wdt]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
@@ -31,7 +31,7 @@
|
||||
selected? (get active-theme-paths theme-id)
|
||||
select-theme (fn [e]
|
||||
(dom/stop-propagation e)
|
||||
(st/emit! (wdt/toggle-token-theme-active? group name))
|
||||
(st/emit! (dwtl/toggle-token-theme-active? group name))
|
||||
(on-close))]]
|
||||
[:li {:key theme-id
|
||||
:role "option"
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.color :as dwtc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
@@ -80,6 +81,7 @@
|
||||
:y "Y"})
|
||||
|
||||
;; Helper functions
|
||||
|
||||
(defn partially-applied-attr
|
||||
"Translates partially applied attributes based on the dictionary."
|
||||
[app-token-keys is-applied {:keys [attributes all-attributes]}]
|
||||
@@ -106,7 +108,7 @@
|
||||
(let [{:keys [name value type resolved-value]} token
|
||||
resolved-value-theme (:resolved-value theme-token)
|
||||
resolved-value (or resolved-value-theme resolved-value)
|
||||
{:keys [title] :as token-props} (wtch/get-token-properties theme-token)
|
||||
{:keys [title] :as token-props} (dwta/get-token-properties theme-token)
|
||||
applied-tokens (:applied-tokens shape)
|
||||
app-token-vals (set (vals applied-tokens))
|
||||
app-token-keys (keys applied-tokens)
|
||||
@@ -156,9 +158,9 @@
|
||||
|
||||
(defn- applied-all-attributes?
|
||||
[token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
(let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} xf:map-id selected-shapes)]
|
||||
(wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)))
|
||||
(cft/shapes-applied-all? ids-by-attributes shape-ids attributes)))
|
||||
|
||||
(mf/defc token-pill*
|
||||
{::mf/wrap [mf/memo]}
|
||||
@@ -166,11 +168,11 @@
|
||||
(let [{:keys [name value errors]} token
|
||||
|
||||
has-selected? (pos? (count selected-shapes))
|
||||
is-reference? (wtt/is-reference? token)
|
||||
is-reference? (cft/is-reference? token)
|
||||
contains-path? (str/includes? name ".")
|
||||
|
||||
{:keys [attributes all-attributes]}
|
||||
(get wtch/token-properties (:type token))
|
||||
(get dwta/token-properties (:type token))
|
||||
|
||||
full-applied?
|
||||
(if has-selected?
|
||||
@@ -179,7 +181,7 @@
|
||||
|
||||
applied?
|
||||
(if has-selected?
|
||||
(wtt/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes))
|
||||
(cft/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes))
|
||||
false)
|
||||
|
||||
half-applied?
|
||||
@@ -201,10 +203,10 @@
|
||||
no-valid-value)
|
||||
|
||||
color
|
||||
(when (wtt/color-token? token)
|
||||
(when (cft/color-token? token)
|
||||
(let [theme-token (get active-theme-tokens (:name token))]
|
||||
(or (wtt/resolved-token-bullet-color theme-token)
|
||||
(wtt/resolved-token-bullet-color token))))
|
||||
(or (dwtc/resolved-token-bullet-color theme-token)
|
||||
(dwtc/resolved-token-bullet-color token))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
|
||||
@@ -472,16 +472,23 @@
|
||||
(defn setup-shortcuts
|
||||
[path-editing? drawing-path? text-editing? grid-editing?]
|
||||
(hooks/use-shortcuts ::workspace wsc/shortcuts)
|
||||
(mf/use-effect
|
||||
(mf/deps path-editing? drawing-path? grid-editing?)
|
||||
(fn []
|
||||
(cond
|
||||
grid-editing?
|
||||
(do (st/emit! (dsc/push-shortcuts ::grid gsc/shortcuts))
|
||||
#(st/emit! (dsc/pop-shortcuts ::grid)))
|
||||
(or drawing-path? path-editing?)
|
||||
(do (st/emit! (dsc/push-shortcuts ::path psc/shortcuts))
|
||||
#(st/emit! (dsc/pop-shortcuts ::path)))
|
||||
text-editing?
|
||||
(do (st/emit! (dsc/push-shortcuts ::text tsc/shortcuts))
|
||||
#(st/emit! (dsc/pop-shortcuts ::text)))))))
|
||||
|
||||
(mf/with-effect [path-editing? drawing-path? grid-editing?]
|
||||
(cond
|
||||
grid-editing?
|
||||
(do
|
||||
(st/emit! (dsc/push-shortcuts ::grid gsc/shortcuts))
|
||||
(fn []
|
||||
(st/emit! (dsc/pop-shortcuts ::grid))))
|
||||
|
||||
(or drawing-path? path-editing?)
|
||||
(do
|
||||
(st/emit! (dsc/push-shortcuts ::path psc/shortcuts))
|
||||
(fn []
|
||||
(st/emit! (dsc/pop-shortcuts ::path))))
|
||||
|
||||
text-editing?
|
||||
(do
|
||||
(st/emit! (dsc/push-shortcuts ::text tsc/shortcuts))
|
||||
(fn []
|
||||
(st/emit! (dsc/pop-shortcuts ::text)))))))
|
||||
|
||||
@@ -421,11 +421,9 @@
|
||||
:uri uri}))
|
||||
(rx/catch
|
||||
(fn [cause]
|
||||
(rx/of (ex/raise :type :internal
|
||||
:code :export-error
|
||||
:hint "unexpected error on exporting file"
|
||||
:file-id (:id file)
|
||||
:cause cause))))))))
|
||||
(rx/of {:type :error
|
||||
:file-id (:id file)
|
||||
:hint (ex-message cause)})))))))
|
||||
|
||||
(= format :legacy-zip)
|
||||
(->> (rx/from files)
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
[app.common.test-helpers.tokens :as ctht]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.data.workspace.tokens.propagation :as dwtp]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.pages :as thp]
|
||||
[frontend-tests.helpers.state :as ths]
|
||||
@@ -134,10 +134,10 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
events [(dwta/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-2")
|
||||
:on-update-shape wtch/update-shape-radius-all})]
|
||||
:on-update-shape dwta/update-shape-radius-all})]
|
||||
|
||||
step2 (fn [_]
|
||||
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||
@@ -171,7 +171,7 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(wtch/unapply-token {:shape-ids [(cthi/id :frame1)]
|
||||
events [(dwta/unapply-token {:shape-ids [(cthi/id :frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-1")})]
|
||||
|
||||
@@ -203,14 +203,14 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(dt/set-selected-token-set-name "test-token-set")
|
||||
(dt/update-token "test-token-1"
|
||||
{:name "test-token-1"
|
||||
:type :border-radius
|
||||
:value 66})]
|
||||
events [(dwtl/set-selected-token-set-name "test-token-set")
|
||||
(dwtl/update-token "test-token-1"
|
||||
{:name "test-token-1"
|
||||
:type :border-radius
|
||||
:value 66})]
|
||||
|
||||
step2 (fn [_]
|
||||
(let [events2 [(wtu/update-workspace-tokens)
|
||||
(let [events2 [(dwtp/propagate-workspace-tokens)
|
||||
(dwl/sync-file (:id file) (:id file))]]
|
||||
(tohs/run-store-async
|
||||
store done events2
|
||||
@@ -242,14 +242,14 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(wtch/apply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||
events [(dwta/apply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-2")
|
||||
:on-update-shape wtch/update-shape-radius-all})
|
||||
(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
:on-update-shape dwta/update-shape-radius-all})
|
||||
(dwta/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-3")
|
||||
:on-update-shape wtch/update-shape-radius-all})]
|
||||
:on-update-shape dwta/update-shape-radius-all})]
|
||||
|
||||
step2 (fn [_]
|
||||
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||
@@ -283,13 +283,13 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(wtch/unapply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||
events [(dwta/unapply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-1")})
|
||||
(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
(dwta/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "test-token-3")
|
||||
:on-update-shape wtch/update-shape-radius-all})]
|
||||
:on-update-shape dwta/update-shape-radius-all})]
|
||||
|
||||
step2 (fn [_]
|
||||
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||
@@ -359,28 +359,28 @@
|
||||
store (ths/setup-store file)
|
||||
|
||||
;; ==== Action
|
||||
events [(dt/set-selected-token-set-name "test-token-set")
|
||||
(dt/update-token "token-radius"
|
||||
{:name "token-radius"
|
||||
:value 30})
|
||||
(dt/update-token "token-rotation"
|
||||
{:name "token-rotation"
|
||||
:value 45})
|
||||
(dt/update-token "token-opacity"
|
||||
{:name "token-opacity"
|
||||
:value 0.9})
|
||||
(dt/update-token "token-stroke-width"
|
||||
{:name "token-stroke-width"
|
||||
:value 8})
|
||||
(dt/update-token "token-color"
|
||||
{:name "token-color"
|
||||
:value "#ff0000"})
|
||||
(dt/update-token "token-dimensions"
|
||||
{:name "token-dimensions"
|
||||
:value 200})]
|
||||
events [(dwtl/set-selected-token-set-name "test-token-set")
|
||||
(dwtl/update-token "token-radius"
|
||||
{:name "token-radius"
|
||||
:value 30})
|
||||
(dwtl/update-token "token-rotation"
|
||||
{:name "token-rotation"
|
||||
:value 45})
|
||||
(dwtl/update-token "token-opacity"
|
||||
{:name "token-opacity"
|
||||
:value 0.9})
|
||||
(dwtl/update-token "token-stroke-width"
|
||||
{:name "token-stroke-width"
|
||||
:value 8})
|
||||
(dwtl/update-token "token-color"
|
||||
{:name "token-color"
|
||||
:value "#ff0000"})
|
||||
(dwtl/update-token "token-dimensions"
|
||||
{:name "token-dimensions"
|
||||
:value 200})]
|
||||
|
||||
step2 (fn [_]
|
||||
(let [events2 [(wtu/update-workspace-tokens)
|
||||
(let [events2 [(dwtp/propagate-workspace-tokens)
|
||||
(dwl/sync-file (:id file) (:id file))]]
|
||||
(tohs/run-store-async
|
||||
store done events2
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
[frontend-tests.tokens.logic.token-data-test]
|
||||
[frontend-tests.tokens.style-dictionary-test]
|
||||
[frontend-tests.tokens.token-form-test]
|
||||
[frontend-tests.tokens.token-test]
|
||||
[frontend-tests.util-range-tree-test]
|
||||
[frontend-tests.util-simple-math-test]
|
||||
[frontend-tests.util-snap-data-test]))
|
||||
@@ -42,5 +41,4 @@
|
||||
'frontend-tests.tokens.logic.token-actions-test
|
||||
'frontend-tests.tokens.logic.token-data-test
|
||||
'frontend-tests.tokens.style-dictionary-test
|
||||
'frontend-tests.tokens.token-test
|
||||
'frontend-tests.tokens.token-form-test))
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
;; 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 frontend-tests.tokens.helpers.state
|
||||
(:require
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
;; 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 frontend-tests.tokens.helpers.tokens
|
||||
(:require
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]))
|
||||
[app.common.types.tokens-lib :as ctob]))
|
||||
|
||||
(defn get-token [file name]
|
||||
(some-> (get-in file [:data :tokens-lib])
|
||||
@@ -14,7 +20,7 @@
|
||||
(let [first-page-id (get-in file [:data :pages 0])
|
||||
shape-id (thi/id shape-label)
|
||||
token (get-token file token-label)
|
||||
applied-attributes (wtt/attributes-map attributes token)]
|
||||
applied-attributes (cft/attributes-map attributes token)]
|
||||
(update-in file [:data
|
||||
:pages-index first-page-id
|
||||
:objects shape-id
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
;; 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 frontend-tests.tokens.logic.token-actions-test
|
||||
(:require
|
||||
[app.common.test-helpers.compositions :as ctho]
|
||||
[app.common.test-helpers.files :as cthf]
|
||||
[app.common.test-helpers.shapes :as cths]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.pages :as thp]
|
||||
[frontend-tests.helpers.state :as ths]
|
||||
@@ -48,10 +54,10 @@
|
||||
(let [file (setup-file-with-tokens)
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.md")
|
||||
:on-update-shape wtch/update-shape-radius-all})]]
|
||||
:on-update-shape dwta/update-shape-radius-all})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -73,14 +79,14 @@
|
||||
(let [file (setup-file-with-tokens)
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:on-update-shape wtch/update-shape-radius-all})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
:on-update-shape dwta/update-shape-radius-all})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.md")
|
||||
:on-update-shape wtch/update-shape-radius-all})]]
|
||||
:on-update-shape dwta/update-shape-radius-all})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -101,17 +107,17 @@
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [;; Apply "borderRadius.sm" to all border radius attributes
|
||||
(wtch/apply-token {:attributes #{:r1 :r2 :r3 :r4}
|
||||
(dwta/apply-token {:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:shape-ids [(:id rect-1)]
|
||||
:on-update-shape wtch/update-shape-radius-all})
|
||||
:on-update-shape dwta/update-shape-radius-all})
|
||||
;; Apply single `:r1` attribute to same shape
|
||||
;; while removing other attributes from the border-radius set
|
||||
;; but keep `:r4` for testing purposes
|
||||
(wtch/apply-token {:attributes #{:r1 :r2 :r3}
|
||||
(dwta/apply-token {:attributes #{:r1 :r2 :r3}
|
||||
:token (toht/get-token file "borderRadius.md")
|
||||
:shape-ids [(:id rect-1)]
|
||||
:on-update-shape wtch/update-shape-radius-all})]]
|
||||
:on-update-shape dwta/update-shape-radius-all})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -133,14 +139,14 @@
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
rect-2 (cths/get-shape file :rect-2)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:on-update-shape wtch/update-shape-radius-for-corners})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-2)]
|
||||
:on-update-shape dwta/update-shape-radius-for-corners})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-2)]
|
||||
:attributes #{:r1 :r2 :r3 :r4}
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:on-update-shape wtch/update-shape-radius-all})]]
|
||||
:on-update-shape dwta/update-shape-radius-all})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -185,22 +191,22 @@
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
rect-2 (cths/get-shape file :rect-2)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:color}
|
||||
:token (toht/get-token file "color.primary")
|
||||
:on-update-shape wtch/update-fill})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
:on-update-shape dwta/update-fill})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:stroke-color}
|
||||
:token (toht/get-token file "color.primary")
|
||||
:on-update-shape wtch/update-stroke-color})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-2)]
|
||||
:on-update-shape dwta/update-stroke-color})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-2)]
|
||||
:attributes #{:color}
|
||||
:token (toht/get-token file "color.secondary")
|
||||
:on-update-shape wtch/update-fill})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-2)]
|
||||
:on-update-shape dwta/update-fill})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-2)]
|
||||
:attributes #{:stroke-color}
|
||||
:token (toht/get-token file "color.secondary")
|
||||
:on-update-shape wtch/update-stroke-color})]]
|
||||
:on-update-shape dwta/update-stroke-color})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -239,10 +245,10 @@
|
||||
#(ctob/add-token-in-set % "Set A" (ctob/make-token dimensions-token))))
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:width :height}
|
||||
:token (toht/get-token file "dimensions.sm")
|
||||
:on-update-shape wtch/update-shape-dimensions})]]
|
||||
:on-update-shape dwta/update-shape-dimensions})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -272,10 +278,10 @@
|
||||
store (ths/setup-store file)
|
||||
frame-1 (cths/get-shape file :frame-1)
|
||||
frame-2 (cths/get-shape file :frame-2)
|
||||
events [(wtch/apply-token {:shape-ids [(:id frame-1) (:id frame-2)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id frame-1) (:id frame-2)]
|
||||
:attributes #{:padding}
|
||||
:token (toht/get-token file "padding.sm")
|
||||
:on-update-shape wtch/update-layout-padding})]]
|
||||
:on-update-shape dwta/update-layout-padding})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -303,10 +309,10 @@
|
||||
#(ctob/add-token-in-set % "Set A" (ctob/make-token sizing-token))))
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:width :height}
|
||||
:token (toht/get-token file "sizing.sm")
|
||||
:on-update-shape wtch/update-shape-dimensions})]]
|
||||
:on-update-shape dwta/update-shape-dimensions})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -344,18 +350,18 @@
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
rect-2 (cths/get-shape file :rect-2)
|
||||
rect-3 (cths/get-shape file :rect-3)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:opacity}
|
||||
:token (toht/get-token file "opacity.float")
|
||||
:on-update-shape wtch/update-opacity})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-2)]
|
||||
:on-update-shape dwta/update-opacity})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-2)]
|
||||
:attributes #{:opacity}
|
||||
:token (toht/get-token file "opacity.percent")
|
||||
:on-update-shape wtch/update-opacity})
|
||||
(wtch/apply-token {:shape-ids [(:id rect-3)]
|
||||
:on-update-shape dwta/update-opacity})
|
||||
(dwta/apply-token {:shape-ids [(:id rect-3)]
|
||||
:attributes #{:opacity}
|
||||
:token (toht/get-token file "opacity.invalid")
|
||||
:on-update-shape wtch/update-opacity})]]
|
||||
:on-update-shape dwta/update-opacity})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -388,10 +394,10 @@
|
||||
#(ctob/add-token-in-set % "Set A" (ctob/make-token rotation-token))))
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-1)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||
:attributes #{:rotation}
|
||||
:token (toht/get-token file "rotation.medium")
|
||||
:on-update-shape wtch/update-rotation})]]
|
||||
:on-update-shape dwta/update-rotation})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -419,10 +425,10 @@
|
||||
store (ths/setup-store file)
|
||||
rect-with-stroke (cths/get-shape file :rect-1)
|
||||
rect-without-stroke (cths/get-shape file :rect-2)
|
||||
events [(wtch/apply-token {:shape-ids [(:id rect-with-stroke) (:id rect-without-stroke)]
|
||||
events [(dwta/apply-token {:shape-ids [(:id rect-with-stroke) (:id rect-without-stroke)]
|
||||
:attributes #{:stroke-width}
|
||||
:token (toht/get-token file "stroke-width.sm")
|
||||
:on-update-shape wtch/update-stroke-width})]]
|
||||
:on-update-shape dwta/update-stroke-width})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
(fn [new-state]
|
||||
@@ -445,9 +451,9 @@
|
||||
store (ths/setup-store file)
|
||||
rect-1 (cths/get-shape file :rect-1)
|
||||
rect-2 (cths/get-shape file :rect-2)
|
||||
events [(wtch/toggle-token {:shapes [rect-1 rect-2]
|
||||
events [(dwta/toggle-token {:shapes [rect-1 rect-2]
|
||||
:token-type-props {:attributes #{:r1 :r2 :r3 :r4}
|
||||
:on-update-shape wtch/update-shape-radius-all}
|
||||
:on-update-shape dwta/update-shape-radius-all}
|
||||
:token (toht/get-token file "borderRadius.md")})]]
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
@@ -476,7 +482,7 @@
|
||||
rect-without-token (cths/get-shape file :rect-2)
|
||||
rect-with-other-token (cths/get-shape file :rect-3)
|
||||
|
||||
events [(wtch/toggle-token {:shapes [rect-with-token rect-without-token rect-with-other-token]
|
||||
events [(dwta/toggle-token {:shapes [rect-with-token rect-without-token rect-with-other-token]
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:token-type-props {:attributes #{:r1 :r2 :r3 :r4}}})]]
|
||||
(tohs/run-store-async
|
||||
@@ -509,7 +515,7 @@
|
||||
rect-without-token (cths/get-shape file :rect-2)
|
||||
rect-with-other-token-2 (cths/get-shape file :rect-3)
|
||||
|
||||
events [(wtch/toggle-token {:shapes [rect-with-other-token-1 rect-without-token rect-with-other-token-2]
|
||||
events [(dwta/toggle-token {:shapes [rect-with-other-token-1 rect-without-token rect-with-other-token-2]
|
||||
:token (toht/get-token file "borderRadius.sm")
|
||||
:token-type-props {:attributes #{:r1 :r2 :r3 :r4}}})]]
|
||||
(tohs/run-store-async
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
;; 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 frontend-tests.tokens.logic.token-data-test
|
||||
(:require
|
||||
[app.common.test-helpers.files :as cthf]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.tokens :as dt]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.pages :as thp]
|
||||
[frontend-tests.helpers.state :as ths]
|
||||
@@ -27,7 +33,7 @@
|
||||
done
|
||||
(let [file (setup-file-with-token-lib)
|
||||
store (ths/setup-store file)
|
||||
events [(dt/duplicate-token-set "Set A" false)]]
|
||||
events [(dwtl/duplicate-token-set "Set A" false)]]
|
||||
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
@@ -46,7 +52,7 @@
|
||||
done
|
||||
(let [file (setup-file-with-token-lib)
|
||||
store (ths/setup-store file)
|
||||
events [(dt/duplicate-token-set "Set B" false)]]
|
||||
events [(dwtl/duplicate-token-set "Set B" false)]]
|
||||
|
||||
(tohs/run-store-async
|
||||
store done events
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
;; 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 frontend-tests.tokens.style-dictionary-test
|
||||
(:require
|
||||
[app.common.transit :as tr]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[promesa.core :as p]))
|
||||
|
||||
Reference in New Issue
Block a user