mirror of
https://github.com/penpot/penpot.git
synced 2025-04-04 19:11:20 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
a79e4d7af3
80 changed files with 563 additions and 2702 deletions
|
@ -4,7 +4,7 @@ export PENPOT_HOST=devenv
|
|||
export PENPOT_TENANT=dev
|
||||
export PENPOT_FLAGS="\
|
||||
$PENPOT_FLAGS \
|
||||
enable-registration
|
||||
enable-login-with-ldap \
|
||||
enable-login-with-password
|
||||
enable-login-with-oidc \
|
||||
enable-login-with-google \
|
||||
|
@ -28,9 +28,7 @@ export PENPOT_FLAGS="\
|
|||
enable-access-tokens \
|
||||
disable-feature-components-v2 \
|
||||
enable-file-validation \
|
||||
enable-file-schema-validation \
|
||||
disable-soft-file-schema-validation \
|
||||
disable-soft-file-validation";
|
||||
enable-file-schema-validation";
|
||||
|
||||
|
||||
# Setup default upload media file size to 100MiB
|
||||
|
|
|
@ -15,13 +15,12 @@ export PENPOT_FLAGS="\
|
|||
enable-feature-fdata-pointer-map \
|
||||
enable-feature-fdata-objects-map \
|
||||
disable-secure-session-cookies \
|
||||
enable-rpc-climit \
|
||||
enable-smtp \
|
||||
enable-access-tokens \
|
||||
disable-feature-components-v2 \
|
||||
enable-file-validation \
|
||||
enable-file-schema-validation \
|
||||
disable-soft-file-schema-validation \
|
||||
disable-soft-file-validation";
|
||||
enable-file-schema-validation";
|
||||
|
||||
export OPTIONS="
|
||||
-A:jmx-remote -A:dev \
|
||||
|
|
|
@ -215,10 +215,15 @@
|
|||
(update :pages-index update-vals fix-container)
|
||||
(d/update-when :components update-vals fix-container))))
|
||||
|
||||
fix-page-invalid-options
|
||||
fix-invalid-page
|
||||
(fn [file-data]
|
||||
(letfn [(update-page [page]
|
||||
(update page :options fix-options))
|
||||
(-> page
|
||||
(update :name (fn [name]
|
||||
(if (nil? name)
|
||||
"Page"
|
||||
name)))
|
||||
(update :options fix-options)))
|
||||
|
||||
(fix-background [options]
|
||||
(if (and (contains? options :background)
|
||||
|
@ -433,7 +438,8 @@
|
|||
(letfn [(fix-component [components id component]
|
||||
(let [root-shape (ctst/get-shape component (:id component))]
|
||||
(if (or (empty? (:objects component))
|
||||
(nil? root-shape))
|
||||
(nil? root-shape)
|
||||
(nil? (:type root-shape)))
|
||||
(dissoc components id)
|
||||
components)))]
|
||||
|
||||
|
@ -731,43 +737,61 @@
|
|||
(fn [file-data]
|
||||
;; Remap shape-refs so that they point to the near main.
|
||||
;; At the same time, if there are any dangling ref, detach the shape and its children.
|
||||
(letfn [(fix-container [container]
|
||||
(reduce fix-shape container (ctn/shapes-seq container)))
|
||||
(let [count (volatile! 0)
|
||||
|
||||
(fix-shape [container shape]
|
||||
(if (ctk/in-component-copy? shape)
|
||||
;; First look for the direct shape.
|
||||
(let [root (ctn/get-component-shape (:objects container) shape)
|
||||
libraries (assoc-in libraries [(:id file-data) :data] file-data)
|
||||
library (get libraries (:component-file root))
|
||||
component (ctkl/get-component (:data library) (:component-id root) true)
|
||||
direct-shape (ctf/get-component-shape (:data library) component (:shape-ref shape))]
|
||||
(if (some? direct-shape)
|
||||
;; If it exists, there is nothing else to do.
|
||||
container
|
||||
;; If not found, find the near shape.
|
||||
(let [near-shape (d/seek #(= (:shape-ref %) (:shape-ref shape))
|
||||
(ctf/get-component-shapes (:data library) component))]
|
||||
(if (some? near-shape)
|
||||
;; If found, update the ref to point to the near shape.
|
||||
(ctn/update-shape container (:id shape) #(assoc % :shape-ref (:id near-shape)))
|
||||
;; If not found, it may be a fostered component. Try to locate a direct shape
|
||||
;; in the head component.
|
||||
(let [head (ctn/get-head-shape (:objects container) shape)
|
||||
library-2 (get libraries (:component-file head))
|
||||
component-2 (ctkl/get-component (:data library-2) (:component-id head) true)
|
||||
direct-shape-2 (ctf/get-component-shape (:data library-2) component-2 (:shape-ref shape))]
|
||||
(if (some? direct-shape-2)
|
||||
;; If it exists, there is nothing else to do.
|
||||
container
|
||||
;; If not found, detach shape and all children.
|
||||
;; container
|
||||
(detach-shape container shape)))))))
|
||||
container))]
|
||||
fix-shape
|
||||
(fn [container shape]
|
||||
(if (ctk/in-component-copy? shape)
|
||||
;; First look for the direct shape.
|
||||
(let [root (ctn/get-component-shape (:objects container) shape)
|
||||
libraries (assoc-in libraries [(:id file-data) :data] file-data)
|
||||
library (get libraries (:component-file root))
|
||||
component (ctkl/get-component (:data library) (:component-id root) true)
|
||||
direct-shape (ctf/get-component-shape (:data library) component (:shape-ref shape))]
|
||||
(if (some? direct-shape)
|
||||
;; If it exists, there is nothing else to do.
|
||||
container
|
||||
;; If not found, find the near shape.
|
||||
(let [near-shape (d/seek #(= (:shape-ref %) (:shape-ref shape))
|
||||
(ctf/get-component-shapes (:data library) component))]
|
||||
(if (some? near-shape)
|
||||
;; If found, update the ref to point to the near shape.
|
||||
(do
|
||||
(vswap! count inc)
|
||||
(ctn/update-shape container (:id shape) #(assoc % :shape-ref (:id near-shape))))
|
||||
;; If not found, it may be a fostered component. Try to locate a direct shape
|
||||
;; in the head component.
|
||||
(let [head (ctn/get-head-shape (:objects container) shape)
|
||||
library-2 (get libraries (:component-file head))
|
||||
component-2 (ctkl/get-component (:data library-2) (:component-id head) true)
|
||||
direct-shape-2 (ctf/get-component-shape (:data library-2) component-2 (:shape-ref shape))]
|
||||
(if (some? direct-shape-2)
|
||||
;; If it exists, there is nothing else to do.
|
||||
container
|
||||
;; If not found, detach shape and all children.
|
||||
;; container
|
||||
(do
|
||||
(vswap! count inc)
|
||||
(detach-shape container shape))))))))
|
||||
container))
|
||||
|
||||
(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
(d/update-when :components update-vals fix-container))))
|
||||
fix-container
|
||||
(fn [container]
|
||||
(reduce fix-shape container (ctn/shapes-seq container)))]
|
||||
|
||||
[(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
(d/update-when :components update-vals fix-container))
|
||||
@count]))
|
||||
|
||||
remap-refs-recur
|
||||
;; remapping refs can generate cascade changes so we call it until no changes are done
|
||||
(fn [file-data]
|
||||
(loop [f-data file-data]
|
||||
(let [[f-data count] (remap-refs f-data)]
|
||||
(if (= count 0)
|
||||
f-data
|
||||
(recur f-data)))))
|
||||
|
||||
fix-converted-copies
|
||||
(fn [file-data]
|
||||
|
@ -974,7 +998,7 @@
|
|||
|
||||
(-> file-data
|
||||
(fix-file-data)
|
||||
(fix-page-invalid-options)
|
||||
(fix-invalid-page)
|
||||
(fix-misc-shape-issues)
|
||||
(fix-recent-colors)
|
||||
(fix-missing-image-metadata)
|
||||
|
@ -993,8 +1017,8 @@
|
|||
(remove-nested-roots)
|
||||
(add-not-nested-roots)
|
||||
(fix-components-without-id)
|
||||
(remap-refs)
|
||||
(fix-converted-copies)
|
||||
(remap-refs-recur)
|
||||
(wrap-non-group-component-roots)
|
||||
(detach-non-group-instance-roots)
|
||||
(transform-to-frames)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
[app.worker :as-alias wrk]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[datoteka.fs :as fs]
|
||||
[integrant.core :as ig]
|
||||
[promesa.exec :as px]
|
||||
|
@ -241,16 +240,15 @@
|
|||
[{:keys [::label ::profile-id ::rpc/climit ::mtx/metrics] :as cfg} f]
|
||||
(let [config (get climit ::config)
|
||||
cache (get climit ::cache)]
|
||||
|
||||
(reduce (fn [handler [limit-id limit-key :as ckey]]
|
||||
(let [config (get config limit-id)]
|
||||
(when-not config
|
||||
(throw (IllegalArgumentException.
|
||||
(str/ffmt "config not found for: %" limit-id))))
|
||||
|
||||
(if-let [config (get config limit-id)]
|
||||
(fn [& params]
|
||||
(let [limiter (cache/get cache ckey (partial create-limiter config))]
|
||||
(invoke limiter metrics limit-id limit-key label profile-id handler params)))))
|
||||
(invoke limiter metrics limit-id limit-key label profile-id handler params)))
|
||||
|
||||
(do
|
||||
(l/wrn :hint "config not found" :label label :id limit-id)
|
||||
f)))
|
||||
f
|
||||
(get-limits cfg))))
|
||||
|
||||
|
|
|
@ -190,8 +190,8 @@
|
|||
{:project-id (:id project)
|
||||
:profile-id profile-id
|
||||
:team-id team-id
|
||||
:is-pinned true})
|
||||
(assoc project :is-pinned true))))
|
||||
:is-pinned false})
|
||||
(assoc project :is-pinned false))))
|
||||
|
||||
|
||||
;; --- MUTATION: Toggle Project Pin
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
component-child (first component-children)]
|
||||
(if (or (nil? child) (nil? component-child))
|
||||
container
|
||||
(let [container (if (and (not (ctk/is-main-of? component-child child))
|
||||
(let [container (if (and (not (ctk/is-main-of? component-child child true))
|
||||
(nil? (ctk/get-swap-slot child))
|
||||
(ctk/instance-head? child))
|
||||
(let [slot (guess-swap-slot component-child component-container)]
|
||||
|
|
|
@ -56,7 +56,9 @@
|
|||
;; migrations process, so all features referenced in migrations should
|
||||
;; be here.
|
||||
(def default-enabled-features
|
||||
#{"fdata/shape-data-type"})
|
||||
#{"fdata/shape-data-type"
|
||||
"styles/v2"
|
||||
"layout/grid"})
|
||||
|
||||
;; A set of features which only affects on frontend and can be enabled
|
||||
;; and disabled freely by the user any time. This features does not
|
||||
|
|
|
@ -732,7 +732,8 @@
|
|||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:objects (:objects new-component)}) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:modified-at (:modified-at new-component)})
|
||||
(update :undo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name prev-component)
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
[{:keys [version] :as file}]
|
||||
(if (int? version)
|
||||
file
|
||||
(let [version (or version (-> file :data :version))]
|
||||
(let [version (or (-> file :data :version) 0)]
|
||||
(-> file
|
||||
(assoc :version version)
|
||||
(update :data dissoc :version)))))
|
||||
|
@ -853,11 +853,11 @@
|
|||
(defn migrate-up-44
|
||||
[data]
|
||||
(letfn [(fix-shadow [shadow]
|
||||
(if (string? (:color shadow))
|
||||
(let [color {:color (:color shadow)
|
||||
:opacity 1}]
|
||||
(assoc shadow :color color))
|
||||
shadow))
|
||||
(let [color (if (string? (:color shadow))
|
||||
{:color (:color shadow)
|
||||
:opacity 1}
|
||||
(d/without-nils (:color shadow)))]
|
||||
(assoc shadow :color color)))
|
||||
|
||||
(update-object [object]
|
||||
(d/update-when object :shadow
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
(def default
|
||||
"A common flags that affects both: backend and frontend."
|
||||
[:enable-registration
|
||||
:enable-login-with-password
|
||||
:enable-login-illustration
|
||||
:enable-feature-styles-v2])
|
||||
:enable-login-with-password])
|
||||
|
||||
(defn parse
|
||||
[& flags]
|
||||
|
@ -35,5 +33,3 @@
|
|||
|
||||
:else
|
||||
(recur (rest flags) result)))))))
|
||||
|
||||
|
||||
|
|
|
@ -190,3 +190,8 @@
|
|||
|
||||
(get-rect-filter-bounds children-bounds filters blur-value))))
|
||||
|
||||
(defn get-frame-bounds
|
||||
([shape]
|
||||
(get-frame-bounds shape nil))
|
||||
([shape {:keys [ignore-margin?] :or {ignore-margin? false}}]
|
||||
(get-object-bounds [] shape {:ignore-margin? ignore-margin?})))
|
||||
|
|
|
@ -995,6 +995,9 @@
|
|||
(= key :style)
|
||||
attrs
|
||||
|
||||
(= key :unicode)
|
||||
attrs
|
||||
|
||||
(str/starts-with? (d/name key) "data-")
|
||||
attrs
|
||||
|
||||
|
|
|
@ -383,13 +383,16 @@
|
|||
(update :svg-attrs dissoc :fill)
|
||||
(assoc-in [:fills 0 :fill-color] (clr/parse color-style)))
|
||||
|
||||
(dm/get-in shape [:svg-attrs :fillOpacity])
|
||||
;; Only create an opacity if the color is setted. Othewise can create problems down the line
|
||||
(and (or (clr/color-string? color-attr) (clr/color-string? color-style))
|
||||
(dm/get-in shape [:svg-attrs :fillOpacity]))
|
||||
(-> (update :svg-attrs dissoc :fillOpacity)
|
||||
(update-in [:svg-attrs :style] dissoc :fillOpacity)
|
||||
(assoc-in [:fills 0 :fill-opacity] (-> (dm/get-in shape [:svg-attrs :fillOpacity])
|
||||
(d/parse-double 1))))
|
||||
|
||||
(dm/get-in shape [:svg-attrs :style :fillOpacity])
|
||||
(and (or (clr/color-string? color-attr) (clr/color-string? color-style))
|
||||
(dm/get-in shape [:svg-attrs :style :fillOpacity]))
|
||||
(-> (update-in [:svg-attrs :style] dissoc :fillOpacity)
|
||||
(update :svg-attrs dissoc :fillOpacity)
|
||||
(assoc-in [:fills 0 :fill-opacity] (-> (dm/get-in shape [:svg-attrs :style :fillOpacity])
|
||||
|
|
|
@ -138,10 +138,10 @@
|
|||
(= (:component-file shape) file-id)))
|
||||
|
||||
(defn is-main-of?
|
||||
[shape-main shape-inst]
|
||||
(and (:shape-ref shape-inst)
|
||||
(or (= (:shape-ref shape-inst) (:id shape-main))
|
||||
(= (:shape-ref shape-inst) (:shape-ref shape-main)))))
|
||||
[shape-main shape-inst components-v2]
|
||||
(or (= (:shape-ref shape-inst) (:id shape-main))
|
||||
(and (= (:shape-ref shape-inst) (:shape-ref shape-main))
|
||||
(not components-v2))))
|
||||
|
||||
(defn main-instance?
|
||||
"Check if this shape is the root of the main instance of some
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
(wrap-object-fn)))))))
|
||||
|
||||
(defn mod-component
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page objects annotation]}]
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page objects annotation modified-at]}]
|
||||
(let [wrap-objects-fn cfeat/*wrap-with-objects-map-fn*]
|
||||
(d/update-in-when file-data [:components id]
|
||||
(fn [component]
|
||||
|
@ -69,6 +69,9 @@
|
|||
(some? objects)
|
||||
(assoc :objects objects)
|
||||
|
||||
(some? modified-at)
|
||||
(assoc :modified-at modified-at)
|
||||
|
||||
(some? annotation)
|
||||
(assoc :annotation annotation)
|
||||
|
||||
|
@ -76,7 +79,7 @@
|
|||
(dissoc :annotation))
|
||||
diff (set/difference
|
||||
(ctk/diff-components component new-comp)
|
||||
#{:annotation})] ;; The set of properties that doesn't mark a component as touched
|
||||
#{:annotation :modified-at})] ;; The set of properties that doesn't mark a component as touched
|
||||
|
||||
(if (empty? diff)
|
||||
new-comp
|
||||
|
|
|
@ -154,6 +154,17 @@
|
|||
:else
|
||||
(get-head-shape objects (get objects (:parent-id shape)) options))))
|
||||
|
||||
(defn get-child-heads
|
||||
"Get all recursive childs that are heads (when a head is found, do not
|
||||
continue down looking for subsequent nested heads)."
|
||||
[objects shape-id]
|
||||
(let [shape (get objects shape-id)]
|
||||
(if (nil? shape)
|
||||
[]
|
||||
(if (ctk/instance-head? shape)
|
||||
[shape]
|
||||
(mapcat #(get-child-heads objects %) (:shapes shape))))))
|
||||
|
||||
(defn get-parent-heads
|
||||
"Get all component heads that are ancestors of the shape, in top-down order
|
||||
(include self if it's also a head)."
|
||||
|
@ -170,6 +181,20 @@
|
|||
(filter #(and (ctk/instance-head? %) (ctk/in-component-copy? %)))
|
||||
(reverse)))
|
||||
|
||||
(defn get-nesting-level-delta
|
||||
"Get how many levels a shape will 'go up' if moved under the new parent."
|
||||
[objects shape new-parent]
|
||||
(let [orig-heads (->> (get-parent-copy-heads objects shape)
|
||||
(remove #(= (:id %) (:id shape))))
|
||||
dest-heads (get-parent-copy-heads objects new-parent)
|
||||
|
||||
;; Calculate how many parent heads share in common the original
|
||||
;; shape and the new parent.
|
||||
pairs (map vector orig-heads dest-heads)
|
||||
common-count (count (take-while (fn [a b] (= a b)) pairs))]
|
||||
|
||||
(- (count orig-heads) common-count)))
|
||||
|
||||
(defn get-instance-root
|
||||
"Get the parent shape at the top of the component instance (main or copy)."
|
||||
[objects shape]
|
||||
|
|
|
@ -216,14 +216,14 @@
|
|||
|
||||
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects container) shape))))
|
||||
|
||||
(defn find-original-ref-shape
|
||||
"Recursively call to find-ref-shape until find the original shape of the original component"
|
||||
[file container libraries shape & options]
|
||||
(defn advance-shape-ref
|
||||
"Get the shape-ref of the near main of the shape, recursively repeated as many times
|
||||
as the given levels."
|
||||
[file container libraries shape levels & options]
|
||||
(let [ref-shape (find-ref-shape file container libraries shape options)]
|
||||
(if (nil? (:shape-ref ref-shape))
|
||||
ref-shape
|
||||
(find-original-ref-shape file container libraries ref-shape options))))
|
||||
|
||||
(if (or (nil? (:shape-ref ref-shape)) (not (pos? levels)))
|
||||
(:id ref-shape)
|
||||
(advance-shape-ref file container libraries ref-shape (dec levels) options))))
|
||||
|
||||
(defn find-ref-component
|
||||
"Locate the nearest component in the local file or libraries that is referenced by the
|
||||
|
|
|
@ -237,7 +237,7 @@
|
|||
--assets-item-border-color: var(--color-accent-primary);
|
||||
--assets-item-background-color-drag: transparent;
|
||||
--assets-item-border-color-drag: var(--color-accent-primary-muted);
|
||||
--assets-component-background-color: var(--color-foreground-secondary);
|
||||
--assets-component-background-color: var(--color-canvas);
|
||||
--assets-component-background-color-disabled: var(--df-secondary;);
|
||||
--assets-component-border-color: var(--color-background-tertiary);
|
||||
--assets-component-border-selected: var(--color-accent-tertiary);
|
||||
|
@ -419,8 +419,6 @@
|
|||
}
|
||||
|
||||
.light {
|
||||
--assets-component-background-color: var(--color-background-secondary);
|
||||
|
||||
--tabs-background-color: var(--color-background-tertiary);
|
||||
--tab-background-color-selected: var(--color-background-primary);
|
||||
--tab-border-color: var(--color-background-tertiary);
|
||||
|
|
|
@ -4,6 +4,18 @@
|
|||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@mixin font-face($style-name, $file, $weight: unquote("normal"), $style: unquote("normal")) {
|
||||
$filepath: "/fonts/" + $file;
|
||||
@font-face {
|
||||
font-family: "#{$style-name}";
|
||||
src:
|
||||
url($filepath + ".woff2") format("woff2"),
|
||||
url($filepath + ".ttf") format("truetype");
|
||||
font-weight: unquote($weight);
|
||||
font-style: unquote($style);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin flexCenter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
@ -33,34 +33,20 @@
|
|||
//#################################################
|
||||
|
||||
@import "common/base";
|
||||
@import "main/layouts/login";
|
||||
@import "main/layouts/main-layout";
|
||||
@import "main/layouts/not-found";
|
||||
@import "main/layouts/viewer";
|
||||
@import "main/layouts/inspect";
|
||||
|
||||
//#################################################
|
||||
// Commons
|
||||
//#################################################
|
||||
|
||||
@import "common/framework";
|
||||
@import "main/partials/forms";
|
||||
@import "main/partials/texts";
|
||||
@import "main/partials/context-menu";
|
||||
@import "main/partials/dropdown";
|
||||
|
||||
//#################################################
|
||||
// Partials
|
||||
//#################################################
|
||||
|
||||
@import "main/partials/activity-bar";
|
||||
@import "main/partials/debug-icons-preview";
|
||||
@import "main/partials/editable-label";
|
||||
@import "main/partials/loader";
|
||||
@import "main/partials/project-bar";
|
||||
@import "main/partials/sidebar";
|
||||
@import "main/partials/tab-container";
|
||||
@import "main/partials/user-settings";
|
||||
@import "main/partials/workspace";
|
||||
@import "main/partials/exception-page";
|
||||
@import "main/partials/signup-questions";
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
$width-left-toolbar: 48px;
|
||||
$width-settings-bar: 256px;
|
||||
|
||||
.inspect-layout {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
grid-template-rows: 48px auto;
|
||||
grid-template-columns: 1fr;
|
||||
user-select: none;
|
||||
|
||||
.viewer-header {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 1 / span 1;
|
||||
}
|
||||
|
||||
.viewer-content {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 2 / span 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen.inspect-layout.force-visible {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
& .viewer-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
transition: top 400ms ease 300ms;
|
||||
margin-bottom: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
& .viewer-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
transition: bottom 400ms ease 300ms;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen.inspect-layout:not(.force-visible) {
|
||||
& .viewer-header {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: -48px;
|
||||
left: 0;
|
||||
transition: top 400ms ease 300ms;
|
||||
z-index: 10;
|
||||
margin-bottom: 48px;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
left: 0;
|
||||
top: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
& .viewer-header:hover {
|
||||
top: 0;
|
||||
transition: top 200ms;
|
||||
}
|
||||
|
||||
& .viewer-bottom {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: -48px;
|
||||
left: 0;
|
||||
transition: bottom 400ms ease 300ms;
|
||||
z-index: 2;
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
left: 0;
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
& .viewer-bottom:hover {
|
||||
bottom: 0px;
|
||||
transition: bottom 200ms;
|
||||
}
|
||||
|
||||
& .viewer-content {
|
||||
grid-row: 1 / span 2;
|
||||
}
|
||||
}
|
||||
|
||||
.inspect-layout {
|
||||
.viewer-section {
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 0;
|
||||
&.fullscreen {
|
||||
.settings-bar,
|
||||
.settings-bar {
|
||||
padding-top: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-bar {
|
||||
width: $width-settings-bar;
|
||||
|
||||
&.settings-bar-right,
|
||||
&.settings-bar-left {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
left: unset;
|
||||
right: unset;
|
||||
|
||||
.settings-bar-inside {
|
||||
padding-top: 0.5rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.settings-bar-right {
|
||||
width: 100%;
|
||||
grid-area: right-sidebar;
|
||||
}
|
||||
}
|
||||
|
||||
.inspect-svg-wrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inspect-svg-container {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
align-items: center;
|
||||
justify-content: safe center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: var(--width, $width-settings-bar);
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
& > .resize-area {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
}
|
|
@ -1,250 +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
|
||||
|
||||
// TODO: rename to auth.scss
|
||||
|
||||
.auth {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: 33% auto;
|
||||
height: 100vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.auth-sidebar {
|
||||
grid-column: 1 / span 1;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
padding-top: 7vh;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
background-color: #151035;
|
||||
background-image: url("/images/login-penpot.svg");
|
||||
background-position: center 30vh;
|
||||
background-size: 96%;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
.tagline {
|
||||
text-align: center;
|
||||
width: 280px;
|
||||
font-size: $fs18;
|
||||
margin-top: 2vh;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.logo {
|
||||
svg {
|
||||
fill: white;
|
||||
max-width: 11vw;
|
||||
height: 80px;
|
||||
}
|
||||
.hidden-name {
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-content {
|
||||
grid-column: 2 / span 1;
|
||||
background-color: $color-white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
.form-container {
|
||||
width: 412px;
|
||||
flex-direction: column;
|
||||
margin-bottom: 30px;
|
||||
.auth-buttons {
|
||||
margin: $size-6 0 $size-4 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 17px;
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 2rem 0 0.5rem 0;
|
||||
.accept-terms-and-privacy-wrapper {
|
||||
position: relative;
|
||||
.input-checkbox {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.input-checkbox input[type="checkbox"] {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0;
|
||||
top: 22px;
|
||||
}
|
||||
label {
|
||||
margin-left: 40px;
|
||||
}
|
||||
label:before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: -36px;
|
||||
}
|
||||
label:after {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: -33px;
|
||||
}
|
||||
.input-checkbox input[type="checkbox"]:focus {
|
||||
opacity: 100%;
|
||||
}
|
||||
.auth-links {
|
||||
margin-left: 40px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.buttons-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
*:not(:last-child) {
|
||||
margin-bottom: $size-4;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-large {
|
||||
flex-grow: 1;
|
||||
font-size: $fs14;
|
||||
font-style: normal;
|
||||
font-weight: $fw400;
|
||||
}
|
||||
|
||||
.btn-google-auth {
|
||||
background-color: #4285f4;
|
||||
color: $color-white;
|
||||
margin-bottom: $size-4;
|
||||
text-decoration: none;
|
||||
.logo {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: #2065d7;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-gitlab-auth {
|
||||
background-color: #fc6d26;
|
||||
color: $color-white;
|
||||
margin-bottom: $size-4;
|
||||
text-decoration: none;
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: #ee5f18;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-github-auth {
|
||||
background-color: #4c4c4c;
|
||||
color: $color-white;
|
||||
margin-bottom: $size-4;
|
||||
text-decoration: none;
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: #2f2f2f;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
.link-oidc {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.separator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
|
||||
.text {
|
||||
margin: 0 10px;
|
||||
color: $color-gray-40;
|
||||
}
|
||||
|
||||
.line {
|
||||
border: 1px solid $color-gray-10;
|
||||
flex-grow: 10;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
font-size: $fs14;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-top: $size-4;
|
||||
margin-bottom: $size-4;
|
||||
|
||||
&.demo {
|
||||
justify-content: center;
|
||||
margin-top: $size-5;
|
||||
}
|
||||
|
||||
.link-entry {
|
||||
font-size: $fs14;
|
||||
color: $color-gray-40;
|
||||
margin-bottom: 10px;
|
||||
a {
|
||||
font-size: $fs14;
|
||||
font-weight: $fw500;
|
||||
color: $color-gray-50;
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.terms-login {
|
||||
bottom: $size-5;
|
||||
font-size: $fs14;
|
||||
position: absolute;
|
||||
|
||||
span {
|
||||
margin: 0 $size-2;
|
||||
color: $color-gray-40;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
.viewer-layout {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
grid-template-rows: 48px auto;
|
||||
grid-template-columns: 1fr;
|
||||
user-select: none;
|
||||
|
||||
.viewer-header {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 1 / span 1;
|
||||
}
|
||||
|
||||
.viewer-content {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 2 / span 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen.viewer-layout.force-visible {
|
||||
grid-template-rows: 1fr;
|
||||
& .viewer-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
transition: top 400ms ease 300ms;
|
||||
margin-bottom: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
& .viewer-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
transition: bottom 400ms ease 300ms;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen.viewer-layout:not(.force-visible) {
|
||||
grid-template-rows: 1fr;
|
||||
& .viewer-header {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: -48px;
|
||||
left: 0;
|
||||
transition: top 400ms ease 300ms;
|
||||
z-index: 2;
|
||||
margin-bottom: 48px;
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
left: 0;
|
||||
top: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
& .viewer-header:hover {
|
||||
top: 0;
|
||||
transition: top 200ms;
|
||||
}
|
||||
|
||||
& .viewer-bottom {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: -48px;
|
||||
left: 0;
|
||||
transition: bottom 400ms ease 300ms;
|
||||
z-index: 2;
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
left: 0;
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
& .viewer-bottom:hover {
|
||||
bottom: 0px;
|
||||
transition: bottom 200ms;
|
||||
}
|
||||
|
||||
& .viewer-content {
|
||||
grid-row: 1 / span 2;
|
||||
}
|
||||
}
|
||||
|
||||
.viewer-overlay {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.viewer-overlay-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
&.visible {
|
||||
background-color: rgb(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
|
@ -1,77 +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
|
||||
|
||||
.activity-bar {
|
||||
background-color: $color-gray-50;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 250px;
|
||||
|
||||
.activity-bar-inside {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
padding-top: 70px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: $color-gray-40;
|
||||
font-size: $fs16;
|
||||
font-weight: $fw700;
|
||||
margin-bottom: $size-1;
|
||||
}
|
||||
|
||||
.date-ribbon {
|
||||
background-color: lighten($color-gray-20, 12%);
|
||||
color: $color-white;
|
||||
font-size: $fs12;
|
||||
font-weight: $fw700;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activity-input {
|
||||
border-bottom: 1px solid $color-gray-10;
|
||||
display: flex;
|
||||
font-size: $fs12;
|
||||
padding: $size-2;
|
||||
width: 100%;
|
||||
|
||||
img.activity-author {
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
height: 30px;
|
||||
margin-right: $size-4;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.activity-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.activity-project {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
a {
|
||||
font-weight: $fw700;
|
||||
margin: 0 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.activity-time {
|
||||
color: $color-gray-20;
|
||||
font-size: $fs12;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +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
|
||||
|
||||
.context-menu {
|
||||
position: relative;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.context-menu.is-open {
|
||||
position: relative;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.context-menu.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.context-menu-items {
|
||||
background: $color-white;
|
||||
border-radius: $br3;
|
||||
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
|
||||
left: -$size-4;
|
||||
max-height: 30rem;
|
||||
min-width: 7rem;
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
top: $size-3;
|
||||
|
||||
& .separator {
|
||||
border-top: 1px solid $color-gray-10;
|
||||
padding: 0px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
&.min-width {
|
||||
min-width: 13rem;
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu-action {
|
||||
color: $color-black;
|
||||
display: block;
|
||||
font-size: $fs14;
|
||||
font-weight: $fw400;
|
||||
padding: $size-2 $size-4;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: $color-black;
|
||||
background-color: $color-primary-lighter;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.submenu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
& span {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
& svg {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&.submenu-back {
|
||||
color: $color-black;
|
||||
display: flex;
|
||||
font-weight: $fw700;
|
||||
align-items: center;
|
||||
|
||||
& svg {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
transform: rotate(180deg);
|
||||
margin-right: $size-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu.is-selectable {
|
||||
& .context-menu-action {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
& .context-menu-item.is-selected .context-menu-action {
|
||||
background-image: url(/images/icons/tick.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5% 48%;
|
||||
background-size: 10px;
|
||||
font-weight: $fw700;
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
.dropdown {
|
||||
position: absolute;
|
||||
max-height: 30rem;
|
||||
background-color: $color-white;
|
||||
border-radius: $br2;
|
||||
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
|
||||
z-index: 3;
|
||||
|
||||
hr {
|
||||
margin: 0 !important;
|
||||
border-color: $color-gray-10;
|
||||
}
|
||||
|
||||
> li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $color-gray-60;
|
||||
cursor: pointer;
|
||||
font-size: $fs14;
|
||||
height: 40px;
|
||||
padding: 5px 16px;
|
||||
|
||||
&.warning {
|
||||
color: $color-danger;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
&.title {
|
||||
font-weight: $fw600;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-primary-lighter;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 1px black solid;
|
||||
}
|
||||
}
|
||||
|
||||
&.with-check {
|
||||
> li {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
> li:not(.selected) {
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $color-gray-50;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
.editable-label {
|
||||
display: flex;
|
||||
|
||||
&.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.editable-label-input {
|
||||
border: 0;
|
||||
height: 30px;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
background-color: $color-white;
|
||||
}
|
||||
|
||||
.editable-label-close {
|
||||
background-color: $color-white;
|
||||
cursor: pointer;
|
||||
padding: 3px 5px;
|
||||
|
||||
& svg {
|
||||
fill: $color-gray-30;
|
||||
height: 15px;
|
||||
transform: rotate(45deg) translateY(7px);
|
||||
width: 15px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
.exception-layout {
|
||||
display: grid;
|
||||
|
||||
grid-template-rows: 120px auto;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.exception-header {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 1 / span 1;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 32px;
|
||||
z-index: 40;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
height: 55px;
|
||||
width: 170px;
|
||||
}
|
||||
}
|
||||
|
||||
.exception-content {
|
||||
grid-column: 1 / span 1;
|
||||
grid-row: 1 / span 2;
|
||||
height: 100vh;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.image {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
svg {
|
||||
height: 220px;
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
.main-message {
|
||||
color: $color-black;
|
||||
font-size: $fs80;
|
||||
line-height: $lh-188; // Original value was 150px; 150px/80px = 187.5 % => $lh-188 (rounded)
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.desc-message {
|
||||
color: $color-black;
|
||||
font-size: $fs26;
|
||||
font-weight: $fw300;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sign-info {
|
||||
margin-top: 20px;
|
||||
color: $color-black;
|
||||
font-size: $fs16;
|
||||
font-weight: $fw200;
|
||||
text-align: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
b {
|
||||
font-weight: $fw400;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,390 +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
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
&.invalid {
|
||||
border-color: $color-danger;
|
||||
color: $color-danger;
|
||||
}
|
||||
}
|
||||
|
||||
.form-container,
|
||||
.generic-form {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
.forms-container {
|
||||
display: flex;
|
||||
margin-top: 40px;
|
||||
width: 536px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// flex-basis: 368px;
|
||||
}
|
||||
|
||||
.fields-row {
|
||||
margin-bottom: 20px;
|
||||
flex-direction: column;
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
font-size: $fs14;
|
||||
margin-top: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.field {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $fs36;
|
||||
color: #2c233e;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: $fs24;
|
||||
color: #2c233e;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
margin-bottom: 3rem;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-60;
|
||||
height: 40%;
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-text {
|
||||
font-size: $fs18;
|
||||
color: $color-gray-60;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.notification-text-email {
|
||||
background: $color-gray-10;
|
||||
border-radius: $br3;
|
||||
color: $color-gray-60;
|
||||
font-size: $fs18;
|
||||
font-weight: $fw500;
|
||||
margin: 1.5rem 0 2.5rem 0;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $fs24;
|
||||
color: $color-gray-60;
|
||||
// height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: $color-gray-60;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-color: $color-gray-20;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
input,
|
||||
textarea {
|
||||
background-color: $color-white;
|
||||
border-radius: $br2;
|
||||
border: 1px solid $color-gray-20;
|
||||
color: $color-gray-60;
|
||||
font-size: $fs14;
|
||||
height: 40px;
|
||||
margin: 0;
|
||||
padding: 15px 15px 0 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: auto;
|
||||
font-size: $fs14;
|
||||
font-family: "worksans", sans-serif;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
// Makes the background for autocomplete white
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:focus,
|
||||
input:-webkit-autofill:active {
|
||||
-webkit-box-shadow: 0 0 0 30px $color-white inset !important;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: $fs12;
|
||||
color: $color-gray-50;
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
&.invalid {
|
||||
input {
|
||||
border-color: $color-danger;
|
||||
}
|
||||
label {
|
||||
color: $color-danger;
|
||||
}
|
||||
}
|
||||
|
||||
&.valid {
|
||||
input {
|
||||
border-color: $color-success;
|
||||
}
|
||||
}
|
||||
|
||||
&.focus {
|
||||
input {
|
||||
border-color: $color-gray-60;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
input {
|
||||
background-color: lighten($color-gray-10, 5%);
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.empty {
|
||||
input {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&.with-icon {
|
||||
input {
|
||||
padding-right: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.help-icon {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
fill: $color-gray-30;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
color: $color-gray-40;
|
||||
padding: 4px;
|
||||
font-size: $fs12;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: $color-danger;
|
||||
padding: 4px;
|
||||
font-size: $fs12;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-multi-input {
|
||||
border-radius: $br2;
|
||||
border: 1px solid $color-gray-20;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
&.invalid {
|
||||
label {
|
||||
color: unset;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
border: 0px;
|
||||
|
||||
&.no-padding {
|
||||
padding-top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.selected-items {
|
||||
padding-top: 25px;
|
||||
padding-left: 15px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.selected-item {
|
||||
width: 100%;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.around {
|
||||
border: 1px solid $color-gray-20;
|
||||
padding-left: 5px;
|
||||
border-radius: $br4;
|
||||
&.invalid {
|
||||
border: 1px solid $color-danger;
|
||||
}
|
||||
&.caution {
|
||||
border: 1px solid $color-warning;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
max-width: 85%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: $lh-115; // Original value was 16px; 16px/14px = 114.285714286% => $lh-115 (rounded)
|
||||
font-size: $fs14;
|
||||
color: $color-black;
|
||||
}
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
|
||||
label {
|
||||
font-size: $fs12;
|
||||
color: $color-gray-30;
|
||||
}
|
||||
|
||||
select {
|
||||
cursor: pointer;
|
||||
font-size: $fs14;
|
||||
border: 0px;
|
||||
opacity: 0;
|
||||
z-index: 10;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
width: calc(100% - 1px);
|
||||
height: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: "worksans", sans-serif;
|
||||
justify-content: center;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
background-color: $color-white;
|
||||
border-radius: $br2;
|
||||
border: 1px solid $color-gray-20;
|
||||
height: 40px;
|
||||
|
||||
&.focus {
|
||||
border-color: $color-gray-60;
|
||||
}
|
||||
|
||||
&.invalid {
|
||||
border-color: $color-danger;
|
||||
label {
|
||||
color: $color-danger;
|
||||
}
|
||||
}
|
||||
|
||||
&.valid {
|
||||
border-color: $color-success;
|
||||
}
|
||||
|
||||
&.focus {
|
||||
border-color: $color-gray-60;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: $color-gray-10;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
color: $color-gray-60;
|
||||
font-size: $fs14;
|
||||
width: 100%;
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
pointer-events: none;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-30;
|
||||
transform: rotate(90deg);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,94 +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
|
||||
|
||||
.project-bar {
|
||||
background-color: $color-gray-50;
|
||||
border-right: 1px solid $color-gray-10;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
left: 50px;
|
||||
position: fixed;
|
||||
width: 200px;
|
||||
z-index: 9;
|
||||
|
||||
&.toggle {
|
||||
left: -201px;
|
||||
}
|
||||
|
||||
.project-bar-inside {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
padding-top: 60px;
|
||||
|
||||
.project-name {
|
||||
border-bottom: 1px solid $color-gray-10;
|
||||
font-size: $fs14;
|
||||
font-weight: $fw700;
|
||||
padding: 0 $size-2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
font-size: $fs12;
|
||||
margin-bottom: 0.5rem;
|
||||
padding: 8px $size-2;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
width: 100%;
|
||||
|
||||
li {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: $size-1 $size-2;
|
||||
position: relative;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
height: 12px;
|
||||
margin-right: $size-1;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $fs12;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.current {
|
||||
span {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
right: 0;
|
||||
top: 40%;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
height: 12px;
|
||||
margin-right: $size-2;
|
||||
width: 12px;
|
||||
|
||||
&:hover {
|
||||
fill: $color-gray-40;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,575 +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
|
||||
|
||||
.settings-bar {
|
||||
background-color: $color-gray-50;
|
||||
border-left: 1px solid $color-gray-60;
|
||||
position: relative;
|
||||
|
||||
&.settings-bar-left {
|
||||
border-left: none;
|
||||
border-right: 1px solid $color-gray-60;
|
||||
|
||||
& .tab-container-tabs {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-bar-inside {
|
||||
display: grid;
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: 100%;
|
||||
height: calc(100% - 2px);
|
||||
|
||||
.tool-window {
|
||||
position: relative;
|
||||
border-bottom: 1px solid $color-gray-60;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.tool-window-bar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
padding: $size-2;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
button,
|
||||
div {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: $color-gray-10;
|
||||
font-size: $fs14;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
span.pages-title {
|
||||
color: #e3e3e3;
|
||||
font-size: 0.875rem;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
span.tool-badge {
|
||||
border: 1px solid $color-primary;
|
||||
border-radius: $br2;
|
||||
font-size: $fs10;
|
||||
color: $color-primary;
|
||||
padding: 2px 4px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
span.tool-link,
|
||||
span.shared-library {
|
||||
margin-left: auto;
|
||||
padding-left: 17px;
|
||||
display: flex;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-30;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
span.tool-link:hover svg {
|
||||
fill: $color-primary;
|
||||
}
|
||||
|
||||
span.library-title {
|
||||
color: $color-gray-10;
|
||||
font-size: $fs14;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
&:first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-window-bar-icon {
|
||||
height: 21px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&.big {
|
||||
height: 3rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.tool-window-bar-title {
|
||||
font-size: $fs14;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.tool-window-icon {
|
||||
margin-right: $size-2;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-window-close {
|
||||
cursor: pointer;
|
||||
margin-left: auto;
|
||||
transform: rotate(45deg);
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
fill: $color-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& .view-only-mode {
|
||||
color: $color-primary;
|
||||
border: 1px solid $color-primary;
|
||||
border-radius: $br3;
|
||||
font-size: $fs10;
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: auto;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: $color-gray-20;
|
||||
font-size: $fs12;
|
||||
line-height: $lh-150;
|
||||
text-align: center;
|
||||
padding: 0 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-top: 12px;
|
||||
|
||||
.tool-window-bar-icon {
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
fill: $color-gray-30;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
margin-top: 10px;
|
||||
background-color: $color-gray-60;
|
||||
color: $color-gray-10;
|
||||
&:hover {
|
||||
background-color: $color-primary;
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .resize-area {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
&.settings-bar-left > .resize-area {
|
||||
right: -8px;
|
||||
}
|
||||
|
||||
&.settings-bar-right > .resize-area {
|
||||
left: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-window-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
&.inspect {
|
||||
.tab-container-tabs {
|
||||
padding-bottom: 0.5rem;
|
||||
background-color: $color-gray-50;
|
||||
border-bottom: 1px solid $color-gray-60;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.tab-container-tab-title {
|
||||
border-radius: $br4;
|
||||
|
||||
&.current {
|
||||
background-color: $color-primary;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.element-list {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
|
||||
ul {
|
||||
border-left: 9px solid $color-gray-50;
|
||||
margin: 0 0 0 0.4rem;
|
||||
|
||||
li {
|
||||
border-left: 1px solid $color-gray-40;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
|
||||
&.open {
|
||||
ul {
|
||||
li {
|
||||
.element-list-body {
|
||||
border-style: dashed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.element-list.pages-list {
|
||||
max-height: 10rem;
|
||||
|
||||
.context-menu {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.context-menu-items {
|
||||
border: none;
|
||||
margin: none;
|
||||
}
|
||||
|
||||
.context-menu-action {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
button.collapse-sidebar {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 2.5rem;
|
||||
padding-top: 0.75rem;
|
||||
position: absolute;
|
||||
width: 1rem;
|
||||
|
||||
& svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
fill: $color-gray-20;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
background: $color-gray-60;
|
||||
left: 48px;
|
||||
top: 48px;
|
||||
width: 28px;
|
||||
height: 48px;
|
||||
padding: 0;
|
||||
border-radius: 0 $br4 $br4 0;
|
||||
border-left: 1px solid $color-gray-50;
|
||||
|
||||
& svg {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layers-tab {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.resize-area-horiz {
|
||||
position: absolute;
|
||||
top: var(--height, 200px);
|
||||
left: 0;
|
||||
height: 8px;
|
||||
width: 100%;
|
||||
z-index: 10;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
}
|
||||
|
||||
.shortcuts,
|
||||
.debug-panel {
|
||||
.shortcuts-header,
|
||||
.debug-panel-header {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
background-color: $color-gray-60;
|
||||
|
||||
.shortcuts-title,
|
||||
.debug-panel-title {
|
||||
color: $color-white;
|
||||
font-size: $fs12;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
svg {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
transform: rotate(45deg);
|
||||
fill: $color-gray-20;
|
||||
}
|
||||
}
|
||||
|
||||
.shortcuts-close-button,
|
||||
.debug-panel-close-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 2px 0 2px 15px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
svg {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
transform: rotate(45deg);
|
||||
fill: $color-gray-20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-field {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 12px 10px;
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid $color-gray-30;
|
||||
border-radius: $br2;
|
||||
width: 100%;
|
||||
&:focus-within {
|
||||
border: 1px solid $color-primary;
|
||||
}
|
||||
.input-text {
|
||||
margin: 0;
|
||||
background: $color-gray-50;
|
||||
width: 100%;
|
||||
color: $color-white;
|
||||
&:focus {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
.icon-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.close {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0 7px;
|
||||
cursor: pointer;
|
||||
fill: $color-gray-20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-list {
|
||||
border-top: 1px solid $color-gray-60;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
height: 90%;
|
||||
margin-bottom: 15px;
|
||||
.section-title {
|
||||
background-color: $color-gray-60;
|
||||
padding: 4px 0;
|
||||
}
|
||||
.section-title,
|
||||
.subsection-title {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
margin-top: 4px;
|
||||
font-size: $fs12;
|
||||
|
||||
.section-name {
|
||||
color: $color-white;
|
||||
}
|
||||
.collapesed-shortcuts {
|
||||
padding: 0 10px;
|
||||
svg {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
fill: $color-gray-20;
|
||||
}
|
||||
&.open {
|
||||
svg {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.shortcut-count {
|
||||
padding-left: 5px;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
.subsection-title {
|
||||
padding: 4px 0px;
|
||||
.subsection-name {
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title,
|
||||
.subsection-title {
|
||||
&:hover {
|
||||
background-color: $color-primary;
|
||||
.subsection-name,
|
||||
.section-name {
|
||||
color: $color-gray-60;
|
||||
}
|
||||
svg {
|
||||
fill: $color-gray-60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-name {
|
||||
border: 1px solid $color-gray-60;
|
||||
border-radius: $br4;
|
||||
padding: 7px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 4px;
|
||||
color: $color-white;
|
||||
font-size: $fs12;
|
||||
.command-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.keys {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.char-box {
|
||||
min-width: 15px;
|
||||
background-color: $color-white;
|
||||
color: $color-black;
|
||||
border-radius: $br3;
|
||||
padding: 2px 5px;
|
||||
font-size: $fs11;
|
||||
font-weight: $fw600;
|
||||
margin: 0 2px;
|
||||
text-transform: capitalize;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
.space {
|
||||
margin: 0 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.not-found {
|
||||
background-color: $color-gray-60;
|
||||
padding: 4px 0;
|
||||
color: $color-white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 4px;
|
||||
font-size: $fs12;
|
||||
}
|
||||
}
|
||||
|
||||
.debug-panel {
|
||||
.debug-panel-inner {
|
||||
padding: 8px;
|
||||
}
|
||||
.debug-option {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin: 4px 0;
|
||||
cursor: pointer;
|
||||
|
||||
label {
|
||||
font-size: 80%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
stroke: $color-primary;
|
||||
}
|
||||
label {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,190 +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
|
||||
|
||||
.signup-questions {
|
||||
background-color: $color-white;
|
||||
color: $color-gray-60;
|
||||
max-width: 646px;
|
||||
overflow-y: auto;
|
||||
padding: 1.5rem 1rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h1,
|
||||
h3 {
|
||||
font-family: "worksans", sans-serif;
|
||||
font-weight: $fw500;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $fs36;
|
||||
padding-top: 2.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $fs23;
|
||||
}
|
||||
|
||||
.step-header {
|
||||
height: 2.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
.custom-select {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
background-color: $color-gray-10;
|
||||
border: none;
|
||||
border-radius: 1rem; // Need to be investigated, before we can use variable
|
||||
color: $color-gray-40;
|
||||
float: right;
|
||||
font-family: "worksans", sans-serif;
|
||||
font-size: $fs12;
|
||||
height: 1.5rem;
|
||||
line-height: $lh-200; // Original value was 1.5rem = 24px; 24px/12px = 200% => lh-200
|
||||
text-align: center;
|
||||
width: 2.5rem;
|
||||
}
|
||||
|
||||
.header-image {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
font-size: $fs16;
|
||||
padding: 0.5rem 0 1rem 0;
|
||||
color: $color-gray-40;
|
||||
}
|
||||
.section {
|
||||
display: block;
|
||||
font-weight: $fw500;
|
||||
font-size: $fs18;
|
||||
margin: 0 0 0.3em 0;
|
||||
padding: 0.8rem 0 0 0;
|
||||
font-family: "worksans", sans-serif !important;
|
||||
}
|
||||
|
||||
.other {
|
||||
.custom-input {
|
||||
margin: 0.75rem 0 2rem 0;
|
||||
}
|
||||
}
|
||||
.buttons {
|
||||
flex-grow: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
grid-template-areas: "previous next";
|
||||
.step-prev {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-start;
|
||||
grid-area: previous;
|
||||
button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
font-size: $fs15;
|
||||
}
|
||||
}
|
||||
|
||||
.step-next {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
grid-area: next;
|
||||
input {
|
||||
font-size: $fs15;
|
||||
color: $color-black;
|
||||
background-color: $color-primary;
|
||||
width: 11rem;
|
||||
margin-left: auto;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-radio {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.input-radio {
|
||||
margin: 0;
|
||||
max-width: 12rem;
|
||||
width: 100%;
|
||||
|
||||
&.with-image {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
font-family: "worksans", sans-serif !important;
|
||||
color: $color-gray-60;
|
||||
font-size: $fs15;
|
||||
padding-left: 0;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 4rem;
|
||||
margin: 0;
|
||||
|
||||
&.with-image {
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
padding-top: 4rem;
|
||||
justify-content: center;
|
||||
background-size: 50px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
/*We need it to be accesible so we can't use display none*/
|
||||
display: inline;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
input[type="radio"] + label:before {
|
||||
background-color: $color-white;
|
||||
border: 1px solid $color-gray-10;
|
||||
}
|
||||
|
||||
input[type="radio"] + label.with-image:before {
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type="radio"]:focus + label:before {
|
||||
border: 1px solid $color-gray-60;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label:before {
|
||||
box-shadow: inset 0 0 0 4px $color-white;
|
||||
background-color: $color-primary;
|
||||
border: 1px solid $color-gray-30;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label.with-image:before {
|
||||
border: 1px solid $color-primary;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
.tab-container {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tab-container-tabs {
|
||||
background: $color-gray-60;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: $fs12;
|
||||
height: 2.5rem;
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
|
||||
.tab-container-tab-title {
|
||||
align-items: center;
|
||||
background: $color-gray-60;
|
||||
border-radius: $br2 $br2 0 0;
|
||||
color: $color-white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0.5rem 0.25rem 0 0.25rem;
|
||||
width: 100%;
|
||||
|
||||
&.current {
|
||||
background: $color-gray-50;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container-content {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.inspect .tab-container-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-element,
|
||||
.tab-element-content {
|
||||
height: 100%;
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
.settings-content {
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 160px;
|
||||
background-color: $color-white;
|
||||
|
||||
.secondary-menu {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
font-size: $fs14;
|
||||
color: $color-gray-60;
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.left {
|
||||
margin-left: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
.label {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $color-gray-60;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
.right {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 30px;
|
||||
|
||||
.label {
|
||||
color: $color-primary-dark;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $color-primary-dark;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.label {
|
||||
color: $color-danger;
|
||||
}
|
||||
svg {
|
||||
fill: $color-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
align-items: top;
|
||||
color: $color-gray-60;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
font-size: $fs24;
|
||||
font-weight: $fw400;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
|
||||
.nav-item {
|
||||
align-items: center;
|
||||
color: $color-gray-40;
|
||||
display: flex;
|
||||
flex-basis: 140px;
|
||||
justify-content: center;
|
||||
|
||||
&.current {
|
||||
border-bottom: 3px solid $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-profile {
|
||||
.forms-container {
|
||||
margin-top: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-form {
|
||||
flex-basis: 168px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
.image-change-field {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
|
||||
.update-overlay {
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
width: 121px;
|
||||
height: 121px;
|
||||
border-radius: 50%;
|
||||
font-size: $fs24;
|
||||
color: $color-white;
|
||||
line-height: $lh-500; // Original value was 120px; 120px/24px =500% => $lh-500
|
||||
text-align: center;
|
||||
background: $color-primary-dark;
|
||||
z-index: 14;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
img {
|
||||
display: none;
|
||||
}
|
||||
.update-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.profile-form {
|
||||
flex-grow: 1;
|
||||
flex-basis: 390px;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
.change-email {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: $fs14;
|
||||
color: $color-primary-dark;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-form {
|
||||
img {
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
height: 120px;
|
||||
margin-right: $size-4;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.options-form,
|
||||
.password-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-basis: 368px;
|
||||
|
||||
h2 {
|
||||
font-size: $fs14;
|
||||
font-weight: $fw400;
|
||||
margin-bottom: $size-4;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
|
@ -1598,6 +1599,34 @@
|
|||
(let [frame (get objects parent-frame-id)]
|
||||
(gsh/translate-to-frame shape frame))))
|
||||
|
||||
;; When copying an instance that is nested inside another one, we need to
|
||||
;; advance the shape refs to one or more levels of remote mains.
|
||||
(advance-copies [state selected data]
|
||||
(let [file (wsh/get-local-file-full state)
|
||||
libraries (wsh/get-libraries state)
|
||||
page (wsh/lookup-page state)
|
||||
heads (mapcat #(ctn/get-child-heads (:objects data) %) selected)]
|
||||
(update data :objects
|
||||
#(reduce (partial advance-copy file libraries page)
|
||||
%
|
||||
heads))))
|
||||
|
||||
(advance-copy [file libraries page objects shape]
|
||||
(if (and (ctk/instance-head? shape) (not (ctk/main-instance? shape)))
|
||||
(let [level-delta (ctn/get-nesting-level-delta (:objects page) shape uuid/zero)]
|
||||
(if (pos? level-delta)
|
||||
(reduce (partial advance-shape file libraries page level-delta)
|
||||
objects
|
||||
(cfh/get-children-with-self objects (:id shape)))
|
||||
objects))
|
||||
objects))
|
||||
|
||||
(advance-shape [file libraries page level-delta objects shape]
|
||||
(let [new-shape-ref (ctf/advance-shape-ref file page libraries shape level-delta {:include-deleted? true})]
|
||||
(cond-> objects
|
||||
(and (some? new-shape-ref) (not= new-shape-ref (:shape-ref shape)))
|
||||
(assoc-in [(:id shape) :shape-ref] new-shape-ref))))
|
||||
|
||||
(on-copy-error [error]
|
||||
(js/console.error "clipboard blocked:" error)
|
||||
(rx/empty))]
|
||||
|
@ -1636,6 +1665,7 @@
|
|||
(rx/merge-map (partial prepare-object objects frame-id))
|
||||
(rx/reduce collect-data initial)
|
||||
(rx/map (partial sort-selected state))
|
||||
(rx/map (partial advance-copies state selected))
|
||||
(rx/map #(t/encode-str % {:type :json-verbose}))
|
||||
(rx/map wapi/write-to-clipboard)
|
||||
(rx/catch on-copy-error)
|
||||
|
|
|
@ -168,13 +168,6 @@
|
|||
;; Toolbar
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn toggle-toolbar-visibility
|
||||
[]
|
||||
(ptk/reify ::toggle-toolbar-visibility
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update-in state [:workspace-local :hide-toolbar] not))))
|
||||
|
||||
(defn hide-toolbar
|
||||
[]
|
||||
(ptk/reify ::hide-toolbar
|
||||
|
@ -188,3 +181,10 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-local :hide-toolbar] false))))
|
||||
|
||||
(defn toggle-toolbar-visibility
|
||||
[]
|
||||
(ptk/reify ::toggle-toolbar-visibility
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update-in state [:workspace-local :hide-toolbar] not))))
|
||||
|
|
|
@ -89,7 +89,6 @@
|
|||
(update [_ state]
|
||||
(update state :workspace-layout
|
||||
(fn [flags]
|
||||
(prn flags)
|
||||
(if force?
|
||||
(conj flags flag)
|
||||
(if (contains? flags flag)
|
||||
|
|
|
@ -706,6 +706,38 @@
|
|||
|
||||
(rx/take-until stopper-s))))))
|
||||
|
||||
(defn sync-head
|
||||
[id]
|
||||
(ptk/reify ::sync-head
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(log/info :msg "SYNC-head of shape" :id (str id))
|
||||
(let [file (wsh/get-local-file state)
|
||||
file-full (wsh/get-local-file-full state)
|
||||
libraries (wsh/get-libraries state)
|
||||
|
||||
page-id (:current-page-id state)
|
||||
container (cfh/get-container file :page page-id)
|
||||
objects (:objects container)
|
||||
|
||||
shape-inst (ctn/get-shape container id)
|
||||
parent (get objects (:parent-id shape-inst))
|
||||
head (ctn/get-component-shape container parent)
|
||||
|
||||
components-v2
|
||||
(features/active-feature? state "components/v2")
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it)
|
||||
(pcb/with-container container)
|
||||
(pcb/with-objects (:objects container))
|
||||
(dwlh/generate-sync-shape-direct file-full libraries container (:id head) false components-v2))]
|
||||
|
||||
(log/debug :msg "SYNC-head finished" :js/rchanges (log-changes
|
||||
(:redo-changes changes)
|
||||
file))
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
(defn reset-component
|
||||
"Cancels all modifications in the shape with the given id, and all its children, in
|
||||
the current page. Set all attributes equal to the ones in the linked component,
|
||||
|
@ -726,23 +758,26 @@
|
|||
components-v2
|
||||
(features/active-feature? state "components/v2")
|
||||
|
||||
shape-inst (ctn/get-shape container id)
|
||||
swap-slot (-> (ctn/get-shape container id)
|
||||
(ctk/get-swap-slot))
|
||||
|
||||
undo-id (js/Symbol)
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it)
|
||||
(pcb/with-container container)
|
||||
(pcb/with-objects (:objects container))
|
||||
(dwlh/generate-sync-shape-direct file-full libraries container id true components-v2)
|
||||
(cond->
|
||||
(some? swap-slot)
|
||||
;; We need to propagate parent changes
|
||||
(dwlh/generate-sync-shape-direct file-full libraries container (:parent-id shape-inst) true components-v2)))]
|
||||
(dwlh/generate-sync-shape-direct file-full libraries container id true components-v2))]
|
||||
|
||||
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
|
||||
(:redo-changes changes)
|
||||
file))
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(when (some? swap-slot)
|
||||
(sync-head id))
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn reset-components
|
||||
"Cancels all modifications in the shapes with the given ids"
|
||||
|
@ -1186,6 +1221,26 @@
|
|||
:callback do-update}]
|
||||
:tag :sync-dialog)))))))
|
||||
|
||||
|
||||
(defn touch-component
|
||||
"Update the modified-at attribute of the component to now"
|
||||
[id]
|
||||
(dm/verify! (uuid? id))
|
||||
(ptk/reify ::touch-component
|
||||
cljs.core/IDeref
|
||||
(-deref [_] [id])
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-component id #(assoc % :modified-at (dt/now))))]
|
||||
(rx/of (dch/commit-changes {:origin it
|
||||
:redo-changes (:redo-changes changes)
|
||||
:undo-changes []
|
||||
:save-undo? false}))))))
|
||||
|
||||
(defn component-changed
|
||||
"Notify that the component with the given id has changed, so it needs to be updated
|
||||
in the current file and in the copies. And also update its thumbnails."
|
||||
|
@ -1197,6 +1252,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of
|
||||
(touch-component component-id)
|
||||
(launch-component-sync component-id file-id undo-group)))))
|
||||
|
||||
(defn watch-component-changes
|
||||
|
@ -1244,13 +1300,18 @@
|
|||
(map (partial ch/components-changed old-data))
|
||||
(reduce into #{})))]
|
||||
|
||||
(if (and (d/not-empty? changed-components) save-undo?)
|
||||
(do (log/info :msg "DETECTED COMPONENTS CHANGED"
|
||||
:ids (map str changed-components)
|
||||
:undo-group undo-group)
|
||||
(if (d/not-empty? changed-components)
|
||||
(if save-undo?
|
||||
(do (log/info :msg "DETECTED COMPONENTS CHANGED"
|
||||
:ids (map str changed-components)
|
||||
:undo-group undo-group)
|
||||
|
||||
(->> (rx/from changed-components)
|
||||
(rx/map #(component-changed % (:id old-data) undo-group))))
|
||||
(->> (rx/from changed-components)
|
||||
(rx/map #(component-changed % (:id old-data) undo-group))))
|
||||
;; even if save-undo? is false, we need to update the :modified-date of the component
|
||||
;; (for example, for undos)
|
||||
(->> (rx/from changed-components)
|
||||
(rx/map #(touch-component %))))
|
||||
(rx/empty)))))
|
||||
|
||||
changes-s
|
||||
|
|
|
@ -759,7 +759,8 @@
|
|||
root-inst
|
||||
root-main
|
||||
omit-touched?
|
||||
set-remote-synced?)
|
||||
set-remote-synced?
|
||||
components-v2)
|
||||
changes))
|
||||
|
||||
both (fn [changes child-inst child-main]
|
||||
|
@ -813,7 +814,8 @@
|
|||
swapped
|
||||
moved
|
||||
false
|
||||
reset?))))
|
||||
reset?
|
||||
components-v2))))
|
||||
|
||||
|
||||
(defn- generate-rename-component
|
||||
|
@ -948,7 +950,8 @@
|
|||
component-container
|
||||
container
|
||||
root-inst
|
||||
root-main))
|
||||
root-main
|
||||
components-v2))
|
||||
|
||||
only-main (fn [changes child-main]
|
||||
(remove-shape changes
|
||||
|
@ -1001,7 +1004,8 @@
|
|||
swapped
|
||||
moved
|
||||
true
|
||||
true)
|
||||
true
|
||||
components-v2)
|
||||
|
||||
;; The inverse sync may be made on a component that is inside a
|
||||
;; remote library. We need to separate changes that are from
|
||||
|
@ -1019,7 +1023,7 @@
|
|||
;; ---- Operation generation helpers ----
|
||||
|
||||
(defn- compare-children
|
||||
[changes children-inst children-main container-inst container-main file libraries only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset?]
|
||||
[changes children-inst children-main container-inst container-main file libraries only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset? components-v2]
|
||||
(log/trace :msg "Compare children")
|
||||
(loop [children-inst (seq (or children-inst []))
|
||||
children-main (seq (or children-main []))
|
||||
|
@ -1039,18 +1043,18 @@
|
|||
(reduce only-inst-cb changes children-inst)
|
||||
|
||||
:else
|
||||
(if (or (ctk/is-main-of? child-main child-inst)
|
||||
(if (or (ctk/is-main-of? child-main child-inst components-v2)
|
||||
(and (ctf/match-swap-slot? child-main child-inst container-inst container-main file libraries) (not reset?)))
|
||||
(recur (next children-inst)
|
||||
(next children-main)
|
||||
(if (ctk/is-main-of? child-main child-inst)
|
||||
(if (ctk/is-main-of? child-main child-inst components-v2)
|
||||
(both-cb changes child-inst child-main)
|
||||
(swapped-cb changes child-inst child-main)))
|
||||
|
||||
(let [child-inst' (d/seek #(or (ctk/is-main-of? child-main %)
|
||||
(let [child-inst' (d/seek #(or (ctk/is-main-of? child-main % components-v2)
|
||||
(and (ctf/match-swap-slot? child-main % container-inst container-main file libraries) (not reset?)))
|
||||
children-inst)
|
||||
child-main' (d/seek #(or (ctk/is-main-of? % child-inst)
|
||||
child-main' (d/seek #(or (ctk/is-main-of? % child-inst components-v2)
|
||||
(and (ctf/match-swap-slot? % child-inst container-inst container-main file libraries) (not reset?)))
|
||||
children-main)]
|
||||
(cond
|
||||
|
@ -1066,7 +1070,7 @@
|
|||
|
||||
:else
|
||||
(if inverse?
|
||||
(let [is-main? (ctk/is-main-of? child-inst child-main')]
|
||||
(let [is-main? (ctk/is-main-of? child-inst child-main' components-v2)]
|
||||
(recur (next children-inst)
|
||||
(remove #(= (:id %) (:id child-main')) children-main)
|
||||
(cond-> changes
|
||||
|
@ -1076,7 +1080,7 @@
|
|||
(swapped-cb child-inst child-main')
|
||||
:always
|
||||
(moved-cb child-inst child-main'))))
|
||||
(let [is-main? (ctk/is-main-of? child-inst' child-main)]
|
||||
(let [is-main? (ctk/is-main-of? child-inst' child-main components-v2)]
|
||||
(recur (remove #(= (:id %) (:id child-inst')) children-inst)
|
||||
(next children-main)
|
||||
(cond-> changes
|
||||
|
@ -1088,13 +1092,13 @@
|
|||
(moved-cb child-inst' child-main))))))))))))
|
||||
|
||||
(defn- add-shape-to-instance
|
||||
[changes component-shape index component-page container root-instance root-main omit-touched? set-remote-synced?]
|
||||
[changes component-shape index component-page container root-instance root-main omit-touched? set-remote-synced? components-v2]
|
||||
(log/info :msg (str "ADD [P " (pretty-uuid (:id container)) "] "
|
||||
(:name component-shape)
|
||||
" "
|
||||
(pretty-uuid (:id component-shape))))
|
||||
(let [component-parent-shape (ctn/get-shape component-page (:parent-id component-shape))
|
||||
parent-shape (d/seek #(ctk/is-main-of? component-parent-shape %)
|
||||
parent-shape (d/seek #(ctk/is-main-of? component-parent-shape % components-v2)
|
||||
(cfh/get-children-with-self (:objects container)
|
||||
(:id root-instance)))
|
||||
all-parents (into [(:id parent-shape)]
|
||||
|
@ -1163,13 +1167,13 @@
|
|||
changes')))
|
||||
|
||||
(defn- add-shape-to-main
|
||||
[changes shape index component component-container page root-instance root-main]
|
||||
[changes shape index component component-container page root-instance root-main components-v2]
|
||||
(log/info :msg (str "ADD [C " (pretty-uuid (:id component-container)) "] "
|
||||
(:name shape)
|
||||
" "
|
||||
(pretty-uuid (:id shape))))
|
||||
(let [parent-shape (ctn/get-shape page (:parent-id shape))
|
||||
component-parent-shape (d/seek #(ctk/is-main-of? % parent-shape)
|
||||
component-parent-shape (d/seek #(ctk/is-main-of? % parent-shape components-v2)
|
||||
(cfh/get-children-with-self (:objects component-container)
|
||||
(:id root-main)))
|
||||
all-parents (into [(:id component-parent-shape)]
|
||||
|
|
|
@ -546,10 +546,7 @@
|
|||
:layout-padding-type
|
||||
:layout-gap
|
||||
:layout-item-margin
|
||||
:layout-item-margin-type
|
||||
:layout-grid-cells
|
||||
:layout-grid-columns
|
||||
:layout-grid-rows]})
|
||||
:layout-item-margin-type]})
|
||||
;; We've applied the text-modifier so we can dissoc the temporary data
|
||||
(fn [state]
|
||||
(update state :workspace-text-modifier #(apply dissoc % ids)))
|
||||
|
|
|
@ -22,13 +22,9 @@
|
|||
(defn esc-pressed []
|
||||
(ptk/reify ::esc-pressed
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(watch [_ _ _]
|
||||
;; Not interrupt when we're editing a path
|
||||
(let [edition-id (or (get-in state [:workspace-drawing :object :id])
|
||||
(get-in state [:workspace-local :edition]))
|
||||
path-edit-mode (get-in state [:workspace-local :edit-path edition-id :edit-mode])]
|
||||
(when-not (= :draw path-edit-mode)
|
||||
(rx/of :interrupt))))))
|
||||
(rx/of :interrupt))))
|
||||
|
||||
(def shortcuts
|
||||
{:move-nodes {:tooltip "M"
|
||||
|
|
|
@ -404,6 +404,7 @@
|
|||
ids-map
|
||||
%2
|
||||
delta
|
||||
nil
|
||||
libraries
|
||||
library-data
|
||||
it
|
||||
|
@ -459,10 +460,10 @@
|
|||
|
||||
;; TODO: move to common.files.shape-helpers
|
||||
(defn- prepare-duplicate-shape-change
|
||||
([changes objects page unames update-unames! ids-map obj delta libraries library-data it file-id]
|
||||
(prepare-duplicate-shape-change changes objects page unames update-unames! ids-map obj delta libraries library-data it file-id (:frame-id obj) (:parent-id obj) false false))
|
||||
([changes objects page unames update-unames! ids-map obj delta level-delta libraries library-data it file-id]
|
||||
(prepare-duplicate-shape-change changes objects page unames update-unames! ids-map obj delta level-delta libraries library-data it file-id (:frame-id obj) (:parent-id obj) false false))
|
||||
|
||||
([changes objects page unames update-unames! ids-map obj delta libraries library-data it file-id frame-id parent-id duplicating-component? child?]
|
||||
([changes objects page unames update-unames! ids-map obj delta level-delta libraries library-data it file-id frame-id parent-id duplicating-component? child?]
|
||||
(cond
|
||||
(nil? obj)
|
||||
changes
|
||||
|
@ -486,11 +487,14 @@
|
|||
duplicating-component? (or duplicating-component? (ctk/instance-head? obj))
|
||||
is-component-main? (ctk/main-instance? obj)
|
||||
|
||||
original-ref-shape (-> (ctf/find-original-ref-shape nil page libraries obj {:include-deleted? true})
|
||||
:id)
|
||||
into-component? (and duplicating-component?
|
||||
(ctn/in-any-component? objects parent))
|
||||
|
||||
level-delta (if (some? level-delta)
|
||||
level-delta
|
||||
(ctn/get-nesting-level-delta objects obj parent))
|
||||
new-shape-ref (ctf/advance-shape-ref nil page libraries obj level-delta {:include-deleted? true})
|
||||
|
||||
regenerate-component
|
||||
(fn [changes shape]
|
||||
(let [components-v2 (dm/get-in library-data [:options :components-v2])
|
||||
|
@ -518,9 +522,9 @@
|
|||
(cond-> (or frame? group? bool?)
|
||||
(assoc :shapes []))
|
||||
|
||||
(cond-> (and (some? original-ref-shape)
|
||||
(not= original-ref-shape (:shape-ref obj)))
|
||||
(assoc :shape-ref original-ref-shape))
|
||||
(cond-> (and (some? new-shape-ref)
|
||||
(not= new-shape-ref (:shape-ref obj)))
|
||||
(assoc :shape-ref new-shape-ref))
|
||||
|
||||
(gsh/move delta)
|
||||
(d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))
|
||||
|
@ -561,6 +565,7 @@
|
|||
ids-map
|
||||
child
|
||||
delta
|
||||
level-delta
|
||||
libraries
|
||||
library-data
|
||||
it
|
||||
|
|
|
@ -353,13 +353,14 @@
|
|||
(ptk/reify ::create-artboard-from-selection
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (cfh/clean-loops objects selected)
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (->> (wsh/lookup-selected state)
|
||||
(cfh/clean-loops objects)
|
||||
(remove #(ctn/has-any-copy-parent? objects (get objects %))))
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects))
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects))
|
||||
|
||||
[frame-shape changes]
|
||||
(cfsh/prepare-create-artboard-from-selection changes
|
||||
|
|
|
@ -606,11 +606,11 @@
|
|||
(->> move-stream
|
||||
(rx/last)
|
||||
(rx/mapcat
|
||||
(fn [[_ target-frame drop-index]]
|
||||
(fn [[_ target-frame drop-index cell-data]]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(move-shapes-to-frame ids target-frame drop-index)
|
||||
(dwm/apply-modifiers {:undo-transation? false})
|
||||
(move-shapes-to-frame ids target-frame drop-index cell-data)
|
||||
(finish-transform)
|
||||
(dwu/commit-undo-transaction undo-id))))))))))))))
|
||||
|
||||
|
@ -832,7 +832,7 @@
|
|||
:ignore-snap-pixel true}))))))
|
||||
|
||||
(defn- move-shapes-to-frame
|
||||
[ids frame-id drop-index]
|
||||
[ids frame-id drop-index [row column :as cell]]
|
||||
(ptk/reify ::move-shapes-to-frame
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
|
@ -905,6 +905,11 @@
|
|||
moving-shapes-ids
|
||||
(map :id moving-shapes)
|
||||
|
||||
moving-shapes-children-ids
|
||||
(->> moving-shapes
|
||||
(mapcat #(cfh/get-children-with-self objects (:id %)))
|
||||
(map :id))
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
|
@ -913,7 +918,7 @@
|
|||
(pcb/update-shapes moving-shapes-ids ctl/remove-layout-item-data))
|
||||
;; Remove component-root property when moving a shape inside a component
|
||||
(cond-> (ctn/get-instance-root objects frame)
|
||||
(pcb/update-shapes moving-shapes-ids #(dissoc % :component-root)))
|
||||
(pcb/update-shapes moving-shapes-children-ids #(dissoc % :component-root)))
|
||||
;; Add component-root property when moving a component outside a component
|
||||
(cond-> (not (ctn/get-instance-root objects frame))
|
||||
(pcb/update-shapes moving-shapes-ids (fn [shape]
|
||||
|
@ -924,7 +929,16 @@
|
|||
(pcb/update-shapes shape-ids-to-detach ctk/detach-shape)
|
||||
(pcb/change-parent frame-id moving-shapes drop-index)
|
||||
(cond-> (ctl/grid-layout? objects frame-id)
|
||||
(-> (pcb/update-shapes [frame-id] ctl/assign-cell-positions {:with-objects? true})
|
||||
(-> (pcb/update-shapes
|
||||
[frame-id]
|
||||
(fn [frame objects]
|
||||
(-> frame
|
||||
;; Assign the cell when pushing into a specific grid cell
|
||||
(cond-> (some? cell)
|
||||
(-> (ctl/push-into-cell moving-shapes-ids row column)
|
||||
(ctl/assign-cells objects)))
|
||||
(ctl/assign-cell-positions objects)))
|
||||
{:with-objects? true})
|
||||
(pcb/reorder-grid-children [frame-id])))
|
||||
(pcb/remove-objects empty-parents))]
|
||||
|
||||
|
|
|
@ -625,7 +625,7 @@
|
|||
(if (some? shape)
|
||||
(let [fonts (ff/shape->fonts shape objects)
|
||||
|
||||
bounds (gsb/get-object-bounds objects shape)
|
||||
bounds (gsb/get-object-bounds objects shape {:ignore-margin? false})
|
||||
|
||||
background (when (str/ends-with? object-id "component")
|
||||
(or (:background options) (dom/get-css-variable "--assets-component-background-color") "#fff"))
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui.auth
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.config :as cf]
|
||||
[app.main.ui.auth.login :refer [login-page]]
|
||||
[app.main.ui.auth.recovery :refer [recovery-page]]
|
||||
|
@ -35,41 +36,39 @@
|
|||
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])))
|
||||
|
||||
(mf/defc auth
|
||||
[{:keys [route] :as props}]
|
||||
(let [section (get-in route [:data :name])
|
||||
params (:query-params route)
|
||||
show-illustration? (contains? cf/flags :login-illustration)]
|
||||
{::mf/props :obj}
|
||||
[{:keys [route]}]
|
||||
(let [section (dm/get-in route [:data :name])
|
||||
params (:query-params route)]
|
||||
|
||||
(mf/use-effect
|
||||
#(dom/set-html-title (tr "title.default")))
|
||||
(mf/with-effect []
|
||||
(dom/set-html-title (tr "title.default")))
|
||||
|
||||
[:main {:class (stl/css-case :auth-section true
|
||||
:no-illustration (not show-illustration?))}
|
||||
(when show-illustration?
|
||||
[:div {:class (stl/css :login-illustration)}
|
||||
i/login-illustration])
|
||||
[:main {:class (stl/css :auth-section)}
|
||||
[:div {:class (stl/css :login-illustration)}
|
||||
i/login-illustration]
|
||||
|
||||
[:section {:class (stl/css :auth-content)}
|
||||
[:*
|
||||
[:a {:href "#/" :class (stl/css :logo-btn)} i/logo]
|
||||
(case section
|
||||
:auth-register
|
||||
[:& register-page {:params params}]
|
||||
[:a {:href "#/" :class (stl/css :logo-btn)} i/logo]
|
||||
(case section
|
||||
:auth-register
|
||||
[:& register-page {:params params}]
|
||||
|
||||
:auth-register-validate
|
||||
[:& register-validate-page {:params params}]
|
||||
:auth-register-validate
|
||||
[:& register-validate-page {:params params}]
|
||||
|
||||
:auth-register-success
|
||||
[:& register-success-page {:params params}]
|
||||
:auth-register-success
|
||||
[:& register-success-page {:params params}]
|
||||
|
||||
:auth-login
|
||||
[:& login-page {:params params}]
|
||||
:auth-login
|
||||
[:& login-page {:params params}]
|
||||
|
||||
:auth-recovery-request
|
||||
[:& recovery-request-page]
|
||||
:auth-recovery-request
|
||||
[:& recovery-request-page]
|
||||
|
||||
:auth-recovery
|
||||
[:& recovery-page {:params params}])]
|
||||
:auth-recovery
|
||||
[:& recovery-page {:params params}])
|
||||
|
||||
(when (contains? #{:auth-login :auth-register} section)
|
||||
(when (or (= section :auth-login)
|
||||
(= section :auth-register))
|
||||
[:& terms-login])]]))
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
width: 100%;
|
||||
overflow: auto;
|
||||
|
||||
&.no-illustration {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
@ -35,6 +35,14 @@
|
|||
:login-with-gitlab
|
||||
:login-with-oidc]))
|
||||
|
||||
(mf/defc demo-warning
|
||||
{::mf/props :obj}
|
||||
[]
|
||||
[:div {:class (stl/css :banner)}
|
||||
[:& context-notification
|
||||
{:type :warning
|
||||
:content (tr "auth.demo-warning")}]])
|
||||
|
||||
(defn- login-with-oidc
|
||||
[event provider params]
|
||||
(dom/prevent-default event)
|
||||
|
@ -284,6 +292,9 @@
|
|||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "login-title"} (tr "auth.login-title")]
|
||||
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& demo-warning])
|
||||
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
|
||||
[:& login-methods {:params params}]
|
||||
|
|
|
@ -18,20 +18,12 @@
|
|||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.components.link :as lk]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.notifications.context-notification :refer [context-notification]]
|
||||
[app.util.i18n :refer [tr tr-html]]
|
||||
[app.util.router :as rt]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc demo-warning
|
||||
[_]
|
||||
[:div {:class (stl/css :banner)}
|
||||
[:& context-notification
|
||||
{:type :warning
|
||||
:content (tr "auth.demo-warning")}]])
|
||||
|
||||
;; --- PAGE: Register
|
||||
|
||||
(defn- validate
|
||||
|
@ -86,7 +78,7 @@
|
|||
(st/emit! (rt/nav :auth-register-validate {} params)))
|
||||
|
||||
(mf/defc register-form
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
[{:keys [params on-success-callback]}]
|
||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
form (fm/use-form :spec ::register-form
|
||||
:validators [validate
|
||||
|
@ -136,7 +128,8 @@
|
|||
|
||||
|
||||
(mf/defc register-methods
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
{::mf/props :obj}
|
||||
[{:keys [params on-success-callback]}]
|
||||
[:*
|
||||
(when login/show-alt-login-buttons?
|
||||
[:*
|
||||
|
@ -146,14 +139,15 @@
|
|||
[:& register-form {:params params :on-success-callback on-success-callback}]])
|
||||
|
||||
(mf/defc register-page
|
||||
[{:keys [params] :as props}]
|
||||
{::mf/props :obj}
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "registration-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& demo-warning])
|
||||
[:& login/demo-warning])
|
||||
|
||||
[:& register-methods {:params params}]
|
||||
|
||||
|
@ -212,7 +206,7 @@
|
|||
::accept-newsletter-subscription])))
|
||||
|
||||
(mf/defc register-validate-form
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
[{:keys [params on-success-callback]}]
|
||||
(let [form (fm/use-form :spec ::register-validate-form
|
||||
:validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))]
|
||||
|
@ -263,7 +257,7 @@
|
|||
|
||||
|
||||
(mf/defc register-validate-page
|
||||
[{:keys [params] :as props}]
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "register-title"} (tr "auth.register-title")]
|
||||
|
@ -279,7 +273,7 @@
|
|||
(tr "labels.go-back")]]]])
|
||||
|
||||
(mf/defc register-success-page
|
||||
[{:keys [params] :as props}]
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form :register-success)}
|
||||
[:div {:class (stl/css :notification-icon)} i/icon-verify]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
[app.main.fonts :as fonts]
|
||||
[app.main.rasterizer :as thr]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.render :refer [component-svg]]
|
||||
[app.main.render :as render]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :as bc]
|
||||
|
@ -49,8 +49,7 @@
|
|||
(->> (rp/cmd! :create-file-thumbnail params)
|
||||
(rx/map :uri))))
|
||||
|
||||
(defn- ask-for-thumbnail
|
||||
"Creates some hooks to handle the files thumbnails cache"
|
||||
(defn render-thumbnail
|
||||
[file-id revn]
|
||||
(->> (wrk/ask! {:cmd :thumbnails/generate-for-file
|
||||
:revn revn
|
||||
|
@ -61,7 +60,12 @@
|
|||
(rx/map (fn [styles]
|
||||
(assoc result
|
||||
:styles styles
|
||||
:width 252))))))
|
||||
:width 252))))))))
|
||||
|
||||
(defn- ask-for-thumbnail
|
||||
"Creates some hooks to handle the files thumbnails cache"
|
||||
[file-id revn]
|
||||
(->> (render-thumbnail file-id revn)
|
||||
(rx/mapcat thr/render)
|
||||
(rx/mapcat (partial persist-thumbnail file-id revn))))
|
||||
|
||||
|
@ -141,8 +145,8 @@
|
|||
(let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library
|
||||
[:div {:class (stl/css :asset-list-item)
|
||||
:key (str "assets-component-" (:id component))}
|
||||
[:& component-svg {:root-shape (get-in component [:objects root-id])
|
||||
:objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2
|
||||
[:& render/component-svg {:root-shape (get-in component [:objects root-id])
|
||||
:objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2
|
||||
[:div {:class (stl/css :name-block)}
|
||||
[:span {:class (stl/css :item-name)
|
||||
:title (:name component)}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
|
@ -29,6 +31,9 @@
|
|||
|
||||
.modal-content {
|
||||
@include bodySmallTypography;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: $s-16;
|
||||
|
|
|
@ -378,6 +378,7 @@
|
|||
|
||||
tutorial-viewed? (:viewed-tutorial? props true)
|
||||
walkthrough-viewed? (:viewed-walkthrough? props true)
|
||||
is-my-penpot (= (:default-team-id profile) (:id team))
|
||||
|
||||
team-id (:id team)
|
||||
|
||||
|
@ -387,6 +388,7 @@
|
|||
(st/emit! (du/update-profile-props {:team-hero? false})
|
||||
(ptk/data-event ::ev/event {::ev/name "dont-show-team-up-hero"
|
||||
::ev/origin "dashboard"}))))
|
||||
|
||||
close-tutorial
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
|
@ -395,6 +397,7 @@
|
|||
::ev/origin "get-started-hero"
|
||||
:type "tutorial"
|
||||
:section "dashboard"}))))
|
||||
|
||||
close-walkthrough
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
|
@ -402,7 +405,13 @@
|
|||
(ptk/data-event ::ev/event {::ev/name "dont-show-walkthrough"
|
||||
::ev/origin "get-started-hero"
|
||||
:type "walkthrough"
|
||||
:section "dashboard"}))))]
|
||||
:section "dashboard"}))))
|
||||
|
||||
show-hero? (and is-my-penpot
|
||||
(or (not tutorial-viewed?)
|
||||
(not walkthrough-viewed?)))
|
||||
|
||||
show-team-hero? (and (not is-my-penpot) team-hero?)]
|
||||
|
||||
(mf/with-effect [team]
|
||||
(let [tname (if (:is-default team)
|
||||
|
@ -423,8 +432,7 @@
|
|||
[:& team-hero {:team team :close-fn close-banner}])
|
||||
|
||||
(when (and (contains? cf/flags :dashboard-templates-section)
|
||||
(or (not tutorial-viewed?)
|
||||
(not walkthrough-viewed?)))
|
||||
show-hero?)
|
||||
[:div {:class (stl/css :hero-projects)}
|
||||
(when (and (not tutorial-viewed?) (:is-default team))
|
||||
[:& tutorial-project
|
||||
|
@ -435,7 +443,11 @@
|
|||
[:& interface-walkthrough
|
||||
{:close-walkthrough close-walkthrough}])])
|
||||
|
||||
[:div {:class (stl/css :dashboard-container :no-bg :dashboard-projects)}
|
||||
[:div {:class (stl/css-case :dashboard-container true
|
||||
:no-bg true
|
||||
:dashboard-projects true
|
||||
:with-hero show-hero?
|
||||
:with-team-hero show-team-hero?)}
|
||||
(for [{:keys [id] :as project} projects]
|
||||
(let [files (when recent-map
|
||||
(->> (vals recent-map)
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
.dashboard-projects {
|
||||
user-select: none;
|
||||
height: calc(100vh - $s-64);
|
||||
}
|
||||
|
||||
.with-hero,
|
||||
.with-team-hero {
|
||||
height: calc(100vh - $s-280);
|
||||
}
|
||||
|
||||
.dashboard-shared {
|
||||
|
|
|
@ -339,7 +339,7 @@
|
|||
|
||||
.profile-fullname {
|
||||
@include smallTitleTipography;
|
||||
@include text-ellipsis;
|
||||
@include textEllipsis;
|
||||
align-self: center;
|
||||
max-width: $s-160;
|
||||
color: var(--profile-foreground-color);
|
||||
|
|
|
@ -118,6 +118,7 @@
|
|||
:id id
|
||||
:data-index index
|
||||
:on-click on-click
|
||||
:on-mouse-down dom/prevent-default
|
||||
:on-key-down on-key-down}
|
||||
[:div {:class (stl/css :template-card)}
|
||||
[:div {:class (stl/css :img-container)}
|
||||
|
|
|
@ -91,4 +91,4 @@
|
|||
|
||||
(defmethod rc/render-release-notes "0.0"
|
||||
[params]
|
||||
(rc/render-release-notes (assoc params :version "1.21")))
|
||||
(rc/render-release-notes (assoc params :version "2.0")))
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
[app.main.ui.releases.common :as c]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defmethod c/render-release-notes "1.21"
|
||||
[data]
|
||||
(c/render-release-notes (assoc data :version "2.0")))
|
||||
|
||||
;; TODO: Review all copies and alt text
|
||||
(defmethod c/render-release-notes "2.0"
|
||||
[{:keys [slide klass next finish navigate version]}]
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
(s/keys :req-un [::email-1 ::email-2]))
|
||||
|
||||
(defn- on-error
|
||||
[form {:keys [code] :as error}]
|
||||
(case code
|
||||
[form error]
|
||||
(case (:code (ex-data error))
|
||||
:email-already-exists
|
||||
(swap! form (fn [data]
|
||||
(let [error {:message (tr "errors.email-already-exists")}]
|
||||
|
@ -93,7 +93,6 @@
|
|||
(let [different-emails-error? (= (dma/get-in @form [:errors :email-2 :code]) :different-emails)
|
||||
email-1 (dma/get-in @form [:clean-data :email-1])
|
||||
email-2 (dma/get-in @form [:clean-data :email-2])]
|
||||
(println "different-emails-error?" (and different-emails-error? (= email-1 email-2)))
|
||||
(when (and different-emails-error? (= email-1 email-2))
|
||||
(swap! form d/dissoc-in [:errors :email-2])))))]
|
||||
|
||||
|
|
|
@ -62,32 +62,34 @@
|
|||
(obj/merge! props (get-border-props shape)))
|
||||
|
||||
(defn add-fill!
|
||||
[attrs fill-data render-id index type]
|
||||
(let [index (if (some? index) (dm/str "-" index) "")]
|
||||
(cond
|
||||
(contains? fill-data :fill-image)
|
||||
(let [id (dm/str "fill-image-" render-id)]
|
||||
(obj/set! attrs "fill" (dm/str "url(#" id ")")))
|
||||
([attrs fill-data render-id index type]
|
||||
(add-fill! attrs fill-data render-id index type "none"))
|
||||
([attrs fill-data render-id index type fill-default]
|
||||
(let [index (if (some? index) (dm/str "-" index) "")]
|
||||
(cond
|
||||
(contains? fill-data :fill-image)
|
||||
(let [id (dm/str "fill-image-" render-id)]
|
||||
(obj/set! attrs "fill" (dm/str "url(#" id ")")))
|
||||
|
||||
(some? (:fill-color-gradient fill-data))
|
||||
(let [id (dm/str "fill-color-gradient-" render-id index)]
|
||||
(obj/set! attrs "fill" (dm/str "url(#" id ")")))
|
||||
(some? (:fill-color-gradient fill-data))
|
||||
(let [id (dm/str "fill-color-gradient-" render-id index)]
|
||||
(obj/set! attrs "fill" (dm/str "url(#" id ")")))
|
||||
|
||||
(contains? fill-data :fill-color)
|
||||
(obj/set! attrs "fill" (:fill-color fill-data))
|
||||
(contains? fill-data :fill-color)
|
||||
(obj/set! attrs "fill" (:fill-color fill-data))
|
||||
|
||||
:else
|
||||
(obj/set! attrs "fill" "none"))
|
||||
:else
|
||||
(obj/set! attrs "fill" fill-default))
|
||||
|
||||
(when (contains? fill-data :fill-opacity)
|
||||
(obj/set! attrs "fillOpacity" (:fill-opacity fill-data)))
|
||||
(when (contains? fill-data :fill-opacity)
|
||||
(obj/set! attrs "fillOpacity" (:fill-opacity fill-data)))
|
||||
|
||||
(when (and (= :text type)
|
||||
(nil? (:fill-color-gradient fill-data))
|
||||
(nil? (:fill-color fill-data)))
|
||||
(obj/set! attrs "fill" "black"))
|
||||
(when (and (= :text type)
|
||||
(nil? (:fill-color-gradient fill-data))
|
||||
(nil? (:fill-color fill-data)))
|
||||
(obj/set! attrs "fill" "black"))
|
||||
|
||||
attrs))
|
||||
attrs)))
|
||||
|
||||
(defn add-stroke!
|
||||
[attrs data render-id index open-path?]
|
||||
|
@ -165,8 +167,10 @@
|
|||
(obj/map->obj)))))
|
||||
|
||||
(defn get-fill-style
|
||||
[fill-data index render-id type]
|
||||
(add-fill! #js {} fill-data render-id index type))
|
||||
([fill-data index render-id type]
|
||||
(add-fill! #js {} fill-data render-id index type))
|
||||
([fill-data index render-id type fill-default]
|
||||
(add-fill! #js {} fill-data render-id index type fill-default)))
|
||||
|
||||
(defn add-fill-props!
|
||||
([props shape render-id]
|
||||
|
@ -242,8 +246,10 @@
|
|||
(obj/set! style "fillOpacity" opacity)))
|
||||
|
||||
^boolean (d/not-empty? shape-fills)
|
||||
(let [fill (nth shape-fills 0)]
|
||||
(obj/merge! style (get-fill-style fill render-id 0 shape-type)))
|
||||
(let [fill (nth shape-fills 0)
|
||||
svg-fill (obj/get svg-attrs "fill")
|
||||
fill-default (d/nilv svg-fill "none")]
|
||||
(obj/merge! style (get-fill-style fill render-id 0 shape-type fill-default)))
|
||||
|
||||
(and ^boolean (cfh/path-shape? shape)
|
||||
^boolean (empty? shape-fills))
|
||||
|
|
|
@ -476,7 +476,8 @@
|
|||
svg-attrs (attrs/get-svg-props shape render-id)
|
||||
|
||||
style (-> (obj/get props "style")
|
||||
(obj/clone))
|
||||
(obj/clone)
|
||||
(obj/merge! (obj/get svg-attrs "style")))
|
||||
|
||||
props (mf/spread-props svg-attrs
|
||||
{:id stroke-id
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.config :as cf]
|
||||
[app.main.ui.context :as muc]
|
||||
|
@ -119,7 +119,7 @@
|
|||
points (dm/get-prop shape :points)
|
||||
|
||||
bounds (mf/with-memo [bounds points]
|
||||
(or bounds (grc/points->rect points)))
|
||||
(or bounds (gsb/get-frame-bounds shape)))
|
||||
|
||||
thumb (:thumbnail shape)
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
.layer-title {
|
||||
@include bodySmallTypography;
|
||||
@include text-ellipsis;
|
||||
@include textEllipsis;
|
||||
height: $s-32;
|
||||
padding: $s-8 0;
|
||||
color: var(--assets-item-name-foreground-color-rest);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
width: $s-272;
|
||||
padding: $s-6;
|
||||
max-height: calc(100vh - 3 * ($s-2 + $s-48));
|
||||
overflow: scroll;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dropdown-element {
|
||||
|
|
|
@ -228,48 +228,54 @@
|
|||
(mf/defc context-menu-group
|
||||
[{:keys [shapes]}]
|
||||
|
||||
(let [multiple? (> (count shapes) 1)
|
||||
single? (= (count shapes) 1)
|
||||
do-create-artboard-from-selection #(st/emit! (dwsh/create-artboard-from-selection))
|
||||
(let [multiple? (> (count shapes) 1)
|
||||
single? (= (count shapes) 1)
|
||||
|
||||
objects (deref refs/workspace-page-objects)
|
||||
any-in-copy? (some true? (map #(ctn/has-any-copy-parent? objects %) shapes))
|
||||
|
||||
;; components can't be ungrouped
|
||||
has-frame? (->> shapes (d/seek #(and (cfh/frame-shape? %) (not (ctk/instance-head? %)))))
|
||||
has-group? (->> shapes (d/seek #(and (cfh/group-shape? %) (not (ctk/instance-head? %)))))
|
||||
has-bool? (->> shapes (d/seek cfh/bool-shape?))
|
||||
has-mask? (->> shapes (d/seek :masked-group))
|
||||
has-bool? (->> shapes (d/seek cfh/bool-shape?))
|
||||
has-mask? (->> shapes (d/seek :masked-group))
|
||||
|
||||
is-group? (and single? has-group?)
|
||||
is-bool? (and single? has-bool?)
|
||||
is-group? (and single? has-group?)
|
||||
is-bool? (and single? has-bool?)
|
||||
|
||||
do-create-group #(st/emit! dw/group-selected)
|
||||
do-mask-group #(st/emit! dw/mask-group)
|
||||
do-remove-group #(st/emit! dw/ungroup-selected)
|
||||
do-unmask-group #(st/emit! dw/unmask-group)]
|
||||
do-unmask-group #(st/emit! dw/unmask-group)
|
||||
do-create-artboard-from-selection
|
||||
#(st/emit! (dwsh/create-artboard-from-selection))]
|
||||
|
||||
[:*
|
||||
(when (or has-bool? has-group? has-mask? has-frame?)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.ungroup")
|
||||
:shortcut (sc/get-tooltip :ungroup)
|
||||
:on-click do-remove-group}])
|
||||
(when (not any-in-copy?)
|
||||
[:*
|
||||
(when (or has-bool? has-group? has-mask? has-frame?)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.ungroup")
|
||||
:shortcut (sc/get-tooltip :ungroup)
|
||||
:on-click do-remove-group}])
|
||||
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.group")
|
||||
:shortcut (sc/get-tooltip :group)
|
||||
:on-click do-create-group}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.group")
|
||||
:shortcut (sc/get-tooltip :group)
|
||||
:on-click do-create-group}]
|
||||
|
||||
(when (or multiple? (and is-group? (not has-mask?)) is-bool?)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.mask")
|
||||
:shortcut (sc/get-tooltip :mask)
|
||||
:on-click do-mask-group}])
|
||||
(when (or multiple? (and is-group? (not has-mask?)) is-bool?)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.mask")
|
||||
:shortcut (sc/get-tooltip :mask)
|
||||
:on-click do-mask-group}])
|
||||
|
||||
(when has-mask?
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.unmask")
|
||||
:shortcut (sc/get-tooltip :unmask)
|
||||
:on-click do-unmask-group}])
|
||||
(when has-mask?
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.unmask")
|
||||
:shortcut (sc/get-tooltip :unmask)
|
||||
:on-click do-unmask-group}])
|
||||
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.create-artboard-from-selection")
|
||||
:shortcut (sc/get-tooltip :artboard-selection)
|
||||
:on-click do-create-artboard-from-selection}]
|
||||
[:& menu-separator]]))
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.create-artboard-from-selection")
|
||||
:shortcut (sc/get-tooltip :artboard-selection)
|
||||
:on-click do-create-artboard-from-selection}]
|
||||
[:& menu-separator]])]))
|
||||
|
||||
(mf/defc context-focus-mode-menu
|
||||
[{:keys []}]
|
||||
|
@ -391,7 +397,9 @@
|
|||
(mf/defc context-menu-layout
|
||||
{::mf/props :obj}
|
||||
[{:keys [shapes]}]
|
||||
(let [single? (= (count shapes) 1)
|
||||
(let [single? (= (count shapes) 1)
|
||||
objects (deref refs/workspace-page-objects)
|
||||
any-in-copy? (some true? (map #(ctn/has-any-copy-parent? objects %) shapes))
|
||||
|
||||
has-flex?
|
||||
(and single? (every? ctl/flex-layout? shapes))
|
||||
|
@ -414,29 +422,30 @@
|
|||
(fn [_event]
|
||||
(let [ids (map :id shapes)]
|
||||
(st/emit! (dwsl/remove-layout ids)))))]
|
||||
[:*
|
||||
(when (not any-in-copy?)
|
||||
(if (or ^boolean has-flex?
|
||||
^boolean has-grid?)
|
||||
[:div
|
||||
[:& menu-separator]
|
||||
(if has-flex?
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.remove-flex")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-flex)
|
||||
:on-click on-remove-layout}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.remove-grid")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-grid)
|
||||
:on-click on-remove-layout}])]
|
||||
|
||||
(if (or ^boolean has-flex?
|
||||
^boolean has-grid?)
|
||||
[:div
|
||||
[:& menu-separator]
|
||||
(if has-flex?
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.remove-flex")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-flex)
|
||||
:on-click on-remove-layout}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.remove-grid")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-grid)
|
||||
:on-click on-remove-layout}])]
|
||||
|
||||
[:div
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.add-flex")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-flex)
|
||||
:value "flex"
|
||||
:on-click on-add-layout}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.add-grid")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-grid)
|
||||
:value "grid"
|
||||
:on-click on-add-layout}]])))
|
||||
[:div
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.add-flex")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-flex)
|
||||
:value "flex"
|
||||
:on-click on-add-layout}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.add-grid")
|
||||
:shortcut (sc/get-tooltip :toggle-layout-grid)
|
||||
:value "grid"
|
||||
:on-click on-add-layout}]]))]))
|
||||
|
||||
(mf/defc context-menu-component
|
||||
[{:keys [shapes]}]
|
||||
|
|
|
@ -62,14 +62,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.submenu-icon {
|
||||
position: absolute;
|
||||
right: $s-16;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--menu-foreground-color);
|
||||
}
|
||||
.submenu-icon svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--menu-foreground-color);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--menu-background-color-hover);
|
||||
.title {
|
||||
|
|
|
@ -81,11 +81,6 @@
|
|||
height: fit-content;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
@include bodyLargeTypography;
|
||||
color: var(--library-name-foreground-color);
|
||||
}
|
||||
|
||||
.item-publish,
|
||||
.item-unpublish {
|
||||
@extend .button-primary;
|
||||
|
@ -216,8 +211,11 @@
|
|||
}
|
||||
|
||||
.item-name {
|
||||
@include bodyLargeTypography;
|
||||
@include textEllipsis;
|
||||
margin: 0;
|
||||
max-width: $s-244;
|
||||
color: var(--library-name-foreground-color);
|
||||
}
|
||||
|
||||
.item-update {
|
||||
|
@ -254,6 +252,7 @@
|
|||
.modal-v2-info {
|
||||
width: $s-664;
|
||||
height: fit-content;
|
||||
max-height: fit-content;
|
||||
}
|
||||
|
||||
.modal-v2-title {
|
||||
|
|
|
@ -179,6 +179,10 @@
|
|||
(mf/use-fn
|
||||
(mf/deps selected-drawtool)
|
||||
(fn [_]
|
||||
(when (contains? layout :document-history)
|
||||
(st/emit! (-> (dw/remove-layout-flag :document-history)
|
||||
(vary-meta assoc ::ev/origin "workspace-header"))))
|
||||
|
||||
(if (= :comments selected-drawtool)
|
||||
(st/emit! :interrupt)
|
||||
(active-comments))))
|
||||
|
@ -187,8 +191,11 @@
|
|||
(mf/use-fn
|
||||
(mf/deps selected-drawtool)
|
||||
(fn []
|
||||
|
||||
(when (= :comments selected-drawtool)
|
||||
(st/emit! :interrupt))
|
||||
(st/emit! :interrupt
|
||||
(-> (dw/toggle-layout-flag :comments)
|
||||
(vary-meta assoc ::ev/origin "workspace-header"))))
|
||||
|
||||
(st/emit! (-> (dw/toggle-layout-flag :document-history)
|
||||
(vary-meta assoc ::ev/origin "workspace-header")))))]
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
container-ref (mf/use-ref nil)
|
||||
content-ref (mf/use-ref nil)
|
||||
|
||||
bounds (gsb/get-object-bounds objects shape)
|
||||
bounds (gsb/get-object-bounds objects shape {:ignore-margin? false})
|
||||
|
||||
x (dm/get-prop bounds :x)
|
||||
y (dm/get-prop bounds :y)
|
||||
|
|
|
@ -219,7 +219,9 @@
|
|||
:auto-focus true
|
||||
:default-value (cfh/merge-path-item (:path color) (:name color))}]
|
||||
|
||||
[:div {:title (:name color)
|
||||
[:div {:title (if (= (:name color) default-name)
|
||||
default-name
|
||||
(dm/str (:name color) " (" default-name ")"))
|
||||
:class (stl/css :name-block)
|
||||
:on-double-click rename-color-clicked}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@
|
|||
:style {"--depth" depth "--parent-size" parent-size}
|
||||
:ref ref
|
||||
:on-double-click start-edit}
|
||||
(d/nilv shape-name "")]
|
||||
(if (dbg/enabled? :show-ids)
|
||||
(str (d/nilv shape-name "") " | " (str/slice (str shape-id) 24))
|
||||
(d/nilv shape-name ""))]
|
||||
(when (and (dbg/enabled? :show-touched) ^boolean shape-touched?)
|
||||
[:span {:class (stl/css :element-name-touched)} "*"])])))
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
height: $s-32;
|
||||
min-height: $s-32;
|
||||
margin: $s-8 0 $s-4 $s-8;
|
||||
padding-right: $s-8;
|
||||
padding-right: $s-12;
|
||||
|
||||
&.search {
|
||||
padding: 0 $s-8 0 $s-12;
|
||||
padding: 0 $s-12 0 $s-8;
|
||||
gap: $s-4;
|
||||
.filter-button {
|
||||
@include flexCenter;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.util.debug :as dbg]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.timers :as tm]
|
||||
|
@ -639,4 +640,6 @@
|
|||
[:& component-swap {:shapes copies}])
|
||||
|
||||
(when (and (not swap-opened?) (not multi) components-v2)
|
||||
[:& component-annotation {:id id :shape shape :component component}])])])))
|
||||
[:& component-annotation {:id id :shape shape :component component}])
|
||||
(when (dbg/enabled? :display-touched)
|
||||
[:div ":touched " (str (:touched shape))])])])))
|
||||
|
|
|
@ -187,15 +187,15 @@
|
|||
(def ^:private corner-bottom-icon
|
||||
(i/icon-xref :corner-bottom (stl/css :corner-icon)))
|
||||
(def ^:private corner-bottomleft-icon
|
||||
(i/icon-xref :corner-bottomleft (stl/css :corner-icon)))
|
||||
(i/icon-xref :corner-bottom-left (stl/css :corner-icon)))
|
||||
(def ^:private corner-bottomright-icon
|
||||
(i/icon-xref :corner-bottomright (stl/css :corner-icon)))
|
||||
(i/icon-xref :corner-bottom-right (stl/css :corner-icon)))
|
||||
(def ^:private corner-top-icon
|
||||
(i/icon-xref :corner-top (stl/css :corner-icon)))
|
||||
(def ^:private corner-topleft-icon
|
||||
(i/icon-xref :corner-topleft (stl/css :corner-icon)))
|
||||
(i/icon-xref :corner-top-left (stl/css :corner-icon)))
|
||||
(def ^:private corner-topright-icon
|
||||
(i/icon-xref :corner-topright (stl/css :corner-icon)))
|
||||
(i/icon-xref :corner-top-right (stl/css :corner-icon)))
|
||||
|
||||
(mf/defc interaction-entry
|
||||
[{:keys [index shape interaction update-interaction remove-interaction]}]
|
||||
|
|
|
@ -227,5 +227,5 @@
|
|||
.title-spacing-sitemap {
|
||||
padding-inline-start: $s-8;
|
||||
margin-block-start: $s-8;
|
||||
padding-inline-end: $s-20;
|
||||
margin-block-end: $s-4;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
[app.common.geom.point :as gpt]
|
||||
[app.main.store :as st]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
[app.util.mouse :as mse]
|
||||
[goog.events :as events]
|
||||
[rumext.v2 :as mf])
|
||||
(:import goog.events.EventType))
|
||||
|
||||
(defonce viewport-ref (atom nil))
|
||||
(defonce current-observer (atom nil))
|
||||
|
@ -45,6 +48,8 @@
|
|||
#(fn [node]
|
||||
(mf/set-ref-val! ref node)
|
||||
(reset! viewport-ref node)
|
||||
(when (some? node)
|
||||
(events/listen node EventType.MOUSELEAVE (fn [] (st/emit! (mse/->BlurEvent)))))
|
||||
(init-observer node on-change-bounds)))]))
|
||||
|
||||
(defn point->viewport
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
;; Show an asterisk for touched copies
|
||||
:show-touched
|
||||
|
||||
;; Show the id with the name
|
||||
:show-ids
|
||||
|
||||
;;
|
||||
:grid-layout
|
||||
|
||||
|
@ -80,7 +83,10 @@
|
|||
:grid-cells
|
||||
|
||||
;; Show info about shapes
|
||||
:shape-panel})
|
||||
:shape-panel
|
||||
|
||||
;; Show what is touched in copies
|
||||
:display-touched})
|
||||
|
||||
(defn enable!
|
||||
[option]
|
||||
|
|
|
@ -588,7 +588,7 @@
|
|||
(t/is (= (:fill-color shape1) clr/black))
|
||||
(t/is (= (:fill-opacity shape1) 0))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (= (:touched shape2) #{:fill-group}))
|
||||
(t/is (= (:fill-color shape2) clr/test))
|
||||
(t/is (= (:fill-opacity shape2) 0.5))
|
||||
(t/is (= (:name c-instance2) "Board"))
|
||||
|
|
|
@ -5064,7 +5064,7 @@ msgstr "Click to close the path"
|
|||
|
||||
#, markdown
|
||||
msgid "workspace.top-bar.view-only"
|
||||
msgstr "**Inspecting mode** (View Only)"
|
||||
msgstr "**Inspecting code** (View Only)"
|
||||
|
||||
msgid "workspace.top-bar.read-only.done"
|
||||
msgstr "Done"
|
||||
|
|
|
@ -5149,7 +5149,7 @@ msgstr "Pulsar para cerrar la ruta"
|
|||
|
||||
#, markdown
|
||||
msgid "workspace.top-bar.view-only"
|
||||
msgstr "**Modo inspección** (View only)"
|
||||
msgstr "**Inspeccionando código** (View only)"
|
||||
|
||||
msgid "workspace.top-bar.read-only.done"
|
||||
msgstr "Hecho"
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.21.0
|
||||
2.0.0
|
||||
|
|
Loading…
Add table
Reference in a new issue