0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-30 16:41:20 -05:00

💄 Update inspect tab in code area

This commit is contained in:
Eva 2023-10-17 16:49:36 +02:00
parent 82f0cc7cff
commit dfe1022d7b
77 changed files with 2239 additions and 698 deletions

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="M3.333 10h-.666a1.334 1.334 0 01-1.334-1.333v-6c0-.737.597-1.334 1.334-1.334h6c.736 0 1.333.597 1.333 1.334v.666M6 8a2 2 0 012-2h4.667c1.103 0 2 .896 2 2v4.667c0 1.103-.897 2-2 2H8c-1.104 0-2-.897-2-2V8z"/>
</svg>

After

Width:  |  Height:  |  Size: 335 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="M10.666 12l4-4-4-4M5.333 4l-4 4 4 4"/>
</svg>

After

Width:  |  Height:  |  Size: 167 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="M6.06 6a2 2 0 013.886.667c0 1.333-2 2-2 2M8 11.334h.006M14.666 8A6.667 6.667 0 111.333 8a6.667 6.667 0 0113.333 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 246 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="M1.333 11.333L8 14.667l6.667-3.334M1.333 8L8 11.333 14.667 8M8 1.333L1.333 4.667 8 8l6.667-3.333L8 1.333z"/>
</svg>

After

Width:  |  Height:  |  Size: 237 B

View file

@ -98,6 +98,7 @@
background-color: var(--button-secondary-background-color-hover);
border: $s-1 solid var(--button-secondary-border-color-hover);
color: var(--button-secondary-foreground-color-hover);
text-decoration: none;
svg,
span svg {
stroke: var(--button-secondary-foreground-color-hover);
@ -524,10 +525,80 @@
}
}
.empty-icon {
@include flexCenter;
height: $s-48;
width: $s-48;
border-radius: $br-circle;
background-color: var(--empty-message-background-color);
svg {
@extend .button-icon;
height: $s-28;
width: $s-28;
stroke: var(--empty-message-foreground-color);
}
}
.attr-title {
div {
margin-left: 0;
color: var(--entry-foreground-color-hover);
}
button {
@extend .button-tertiary;
display: none;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
&:hover {
button {
display: flex;
}
}
}
.attr-row {
display: grid;
grid-template-areas: "name content";
grid-template-columns: $s-92 1fr;
gap: $s-4;
height: $s-32;
:global(.attr-label) {
@include titleTipography;
@include twoLineTextEllipsis;
width: $s-92;
margin: auto 0;
color: var(--entry-foreground-color);
grid-area: name;
}
:global(.attr-value) {
grid-area: content;
display: flex;
color: var(--entry-foreground-color-hover);
@include titleTipography;
}
}
.copy-button-children {
@include titleTipography;
color: var(--color-foreground-primary);
text-align: left;
display: grid;
grid-template-columns: 1fr 22px;
grid-template-areas: "name button";
width: 100%;
margin: 0;
padding: 0;
height: fit-content;
&:hover {
div {
color: var(--entry-foreground-color-hover);
}
}
}
.comment-bubbles {
@ -555,10 +626,8 @@
// SELECTS AND DROPDOWNS
.menu-dropdown {
@include menuShadow;
@include flexColumn;
position: absolute;
display: flex;
flex-direction: column;
gap: $s-4;
padding: $s-4;
border-radius: $br-8;
z-index: $z-index-10;

View file

@ -122,6 +122,7 @@
--search-bar-input-background-color: var(--color-background-tertiary);
--search-bar-input-border-color: var(--color-background-tertiary);
// INPUTS, SELECTS, DROPDOWNS
--input-background-color: var(--color-background-tertiary);
--input-foreground-color: var(--color-foreground-secondary);
--input-placeholder-color: var(--color-foreground-secondary);
@ -137,9 +138,6 @@
--input-border-color-disabled: var(--color-background-quaternary);
--input-details-color: var(--color-background-primary);
--pill-background-color: var(--color-background-tertiary);
--pill-foreground-color: var(--color-foreground-primary);
--menu-background-color: var(--color-background-tertiary);
--menu-foreground-color: var(--color-foreground-primary);
--menu-background-color-selected: var(--color-background-tertiary);
@ -158,6 +156,9 @@
--menu-foreground-color-disabled: var(--color-foreground-secondary);
--menu-border-color-disabled: var(--color-background-quaternary);
--pill-background-color: var(--color-background-tertiary);
--pill-foreground-color: var(--color-foreground-primary);
--tag-background-color: var(--color-accent-primary);
--palette-background-color: var(--color-background-primary);

View file

@ -10,6 +10,18 @@
align-items: center;
}
@mixin flexColumn {
display: flex;
flex-direction: column;
gap: $s-4;
}
@mixin flexRow {
display: flex;
align-items: center;
gap: $s-4;
}
@mixin buttonStyle {
border: none;
background: none;
@ -61,6 +73,27 @@
-webkit-box-orient: vertical;
}
@mixin inspectValue {
@include titleTipography;
display: inline-block;
width: fit-content;
padding: 0;
margin: 0;
text-align: left;
color: var(--menu-foreground-color);
}
@mixin copyWrapper {
@include flexColumn;
position: relative;
min-height: $s-32;
width: $s-156;
max-width: $s-156;
padding: calc($s-8 - $s-1) 0 calc($s-8 - $s-1) calc($s-8 - $s-1);
border-radius: $s-8;
box-sizing: border-box;
}
@keyframes spin-animation {
0% {
transform: rotate(0deg);

View file

@ -5,17 +5,21 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.components.code-block
(:require-macros [app.main.style :as stl])
(:require
["highlight.js" :as hljs]
[app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[rumext.v2 :as mf]))
(mf/defc code-block
{::mf/wrap-props false}
[{:keys [code type]}]
(let [block-ref (mf/use-ref)]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
block-ref (mf/use-ref)]
(mf/with-effect [code type]
(when-let [node (mf/ref-val block-ref)]
(hljs/highlightElement node)))
[:pre.code-display {:class type :ref block-ref} code]))
[:pre {:class (dm/str type " " (stl/css new-css-system :code-display)) :ref block-ref} code]))

View file

@ -0,0 +1,14 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.code-display {
border-radius: $br-8;
margin-top: $s-8;
padding: $s-12;
background-color: var(--menu-background-color);
}

View file

@ -36,7 +36,6 @@
:is-gradient (some? gradient)
:is-transparent (and opacity (> 1 opacity))
:grid-area area)
:on-click on-click}
(if (some? gradient)
@ -56,8 +55,9 @@
(let [{:keys [name color gradient]} (if (string? color) {:color color :opacity 1} color)]
(when (or (not size) (> size 64))
[:span {:class (stl/css-case
:color-text true
:small-text (and (>= size 64) (< size 72)))
:color-text (< size 72)
:small-text (and (>= size 64) (< size 72))
:big-text (>= size 72))
:on-click on-click
:on-double-click on-double-click}
(or name color (uc/gradient-type->string (:type gradient)))])))

View file

@ -80,6 +80,11 @@
}
}
.big-text {
@include inspectValue;
height: $s-16;
}
.no-text {
display: none;
}

View file

@ -5,15 +5,19 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.components.copy-button
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.timers :as timers]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[rumext.v2 :as mf]))
(mf/defc copy-button [{:keys [data on-copied]}]
(let [just-copied (mf/use-state false)]
(mf/defc copy-button [{:keys [data on-copied children class]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
just-copied (mf/use-state false)]
(mf/use-effect
(mf/deps @just-copied)
(fn []
@ -23,11 +27,24 @@
(let [sub (timers/schedule 1000 #(reset! just-copied false))]
;; On unmount we dispose the timer
#(rx/-dispose sub)))))
(if new-css-system
[:button {:class (dm/str class " " (stl/css-case :copy-button true
:copy-wrapper (some? children)))
:on-click #(when-not @just-copied
(reset! just-copied true)
(wapi/write-to-clipboard (if (fn? data) (data) data)))}
[:button.copy-button
{:on-click #(when-not @just-copied
(reset! just-copied true)
(wapi/write-to-clipboard (if (fn? data) (data) data)))}
(if @just-copied
i/tick
i/copy)]))
(when children
children)
[:span {:class (stl/css :icon-btn)}
(if @just-copied
i/tick-refactor
i/clipboard-refactor)]]
[:button.copy-button
{:on-click #(when-not @just-copied
(reset! just-copied true)
(wapi/write-to-clipboard (if (fn? data) (data) data)))}
(if @just-copied
i/tick
i/copy)])))

View file

@ -0,0 +1,77 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.copy-button {
@include buttonStyle;
@include flexCenter;
height: $s-32;
width: $s-28;
border: $s-1 solid transparent;
border-radius: $br-8;
background-color: transparent;
box-sizing: border-box;
.icon-btn {
@include flexCenter;
height: $s-32;
min-width: $s-28;
width: $s-28;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
&:hover {
background-color: var(--color-background-tertiary);
color: var(--color-foreground-primary);
border: $s-1 solid var(--color-background-tertiary);
.icon-btn {
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
&:focus,
&:focus-visible {
outline: none;
border: $s-1 solid var(--button-tertiary-border-color-focus);
background-color: transparent;
color: var(--button-tertiary-foreground-color-focus);
.icon-btn svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
&.copy-wrapper {
@include copyWrapper;
height: fit-content;
text-align: left;
.icon-btn {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 0;
right: 0;
height: 32px;
width: 28px;
svg {
@extend .button-icon-small;
display: none;
}
}
&:hover {
.icon-btn {
svg {
display: flex;
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
}
}

View file

@ -47,3 +47,39 @@
#_:default i/bool-union)
:svg-raw i/file-svg
nil)))
(mf/defc element-icon-refactor
[{:keys [shape main-instance?] :as props}]
(if (ctk/instance-head? shape)
(if main-instance?
i/component-refactor
i/copy-refactor)
(case (:type shape)
:frame (cond
(and (ctl/flex-layout? shape) (ctl/col? shape))
i/flex-vertical-refactor
(and (ctl/flex-layout? shape) (ctl/row? shape))
i/flex-horizontal-refactor
(ctl/grid-layout? shape)
i/grid-refactor
:else
i/board-refactor)
:image i/img-refactor
:line i/path-refactor
:circle i/elipse-refactor
:path i/curve-refactor
:rect i/rectangle-refactor
:text i/text-refactor
:group (if (:masked-group shape)
i/mask-refactor
i/group-refactor)
:bool (case (:bool-type shape)
:difference i/boolean-difference-refactor
:exclude i/boolean-exclude-refactor
:intersection i/boolean-intersection-refactor
#_:default i/boolean-union-refactor)
:svg-raw i/svg-refactor
nil)))

View file

@ -26,7 +26,6 @@
:rotated collapsed?)}
i/arrow-refactor]
[:div {:class (stl/css :title)} title]]
[:*
[:button {:class (stl/css-case
:collapsabled-icon true

View file

@ -305,8 +305,10 @@
(def boolean-intersection-refactor (icon-xref :boolean-intersection-refactor))
(def boolean-union-refactor (icon-xref :boolean-union-refactor))
(def clip-content-refactor (icon-xref :clip-content-refactor))
(def clipboard-refactor (icon-xref :clipboard-refactor))
(def close-refactor (icon-xref :close-refactor))
(def close-small-refactor (icon-xref :close-small-refactor))
(def code-refactor (icon-xref :code-refactor))
(def component-refactor (icon-xref :component-refactor))
(def comments-refactor (icon-xref :comments-refactor))
(def copy-refactor (icon-xref :copy-refactor))
@ -351,6 +353,7 @@
(def graphics-refactor (icon-xref :graphics-refactor))
(def gap-horizontal-refactor (icon-xref :gap-horizontal-refactor))
(def gap-vertical-refactor (icon-xref :gap-vertical-refactor))
(def help-refactor (icon-xref :help-refactor))
(def hide-refactor (icon-xref :hide-refactor))
(def history-refactor (icon-xref :history-refactor))
(def hsva-refactor (icon-xref :hsva-refactor))
@ -371,6 +374,7 @@
(def justify-content-row-between-refactor (icon-xref :justify-content-row-between-refactor))
(def justify-content-row-around-refactor (icon-xref :justify-content-row-around-refactor))
(def justify-content-row-evenly-refactor (icon-xref :justify-content-row-evenly-refactor))
(def layers-refactor (icon-xref :layers-refactor))
(def lock-refactor (icon-xref :lock-refactor))
(def library-refactor (icon-xref :library-refactor))
(def margin-bottom-refactor (icon-xref :margin-bottom-refactor))

View file

@ -5,8 +5,10 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes
(:require-macros [app.main.style :as stl])
(:require
[app.common.types.components-list :as ctkl]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.viewer.inspect.annotation :refer [annotation]]
[app.main.ui.viewer.inspect.attributes.blur :refer [blur-panel]]
@ -34,35 +36,65 @@
(mf/defc attributes
[{:keys [page-id file-id shapes frame from libraries share-id objects]}]
(let [shapes (hooks/use-equal-memo shapes)
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (hooks/use-equal-memo shapes)
type (if (= (count shapes) 1) (-> shapes first :type) :multiple)
options (type->options type)
content (when (= (count shapes) 1)
(ctkl/get-component-annotation (first shapes) libraries))]
[:div.element-options
(for [[idx option] (map-indexed vector options)]
[:> (case option
:geometry geometry-panel
:layout layout-panel
:layout-element layout-element-panel
:fill fill-panel
:stroke stroke-panel
:shadow shadow-panel
:blur blur-panel
:image image-panel
:text text-panel
:svg svg-panel)
{:key idx
:shapes shapes
:objects objects
:frame frame
:from from}])
(when content
[:& annotation {:content content}])
[:& exports
{:shapes shapes
:type type
:page-id page-id
:file-id file-id
:share-id share-id}]]))
(if new-css-system
[:div {:class (stl/css :element-options)}
(for [[idx option] (map-indexed vector options)]
[:> (case option
:geometry geometry-panel
:layout layout-panel
:layout-element layout-element-panel
:fill fill-panel
:stroke stroke-panel
:shadow shadow-panel
:blur blur-panel
:image image-panel
:text text-panel
:svg svg-panel)
{:key idx
:shapes shapes
:objects objects
:frame frame
:from from}])
(when content
[:& annotation {:content content}])
[:& exports
{:shapes shapes
:type type
:page-id page-id
:file-id file-id
:share-id share-id}]]
[:div.element-options
(for [[idx option] (map-indexed vector options)]
[:> (case option
:geometry geometry-panel
:layout layout-panel
:layout-element layout-element-panel
:fill fill-panel
:stroke stroke-panel
:shadow shadow-panel
:blur blur-panel
:image image-panel
:text text-panel
:svg svg-panel)
{:key idx
:shapes shapes
:objects objects
:frame frame
:from from}])
(when content
[:& annotation {:content content}])
[:& exports
{:shapes shapes
:type type
:page-id page-id
:file-id file-id
:share-id share-id}]])))

View file

@ -0,0 +1,15 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.element-options {
display: flex;
flex-direction: column;
gap: $s-16;
width: 100%;
height: 100%;
}

View file

@ -5,8 +5,11 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.blur
(:require-macros [app.main.style :as stl])
(:require
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.util.code-gen.style-css :as css]
[app.util.i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -16,16 +19,36 @@
(mf/defc blur-panel
[{:keys [objects shapes]}]
(let [shapes (->> shapes (filter has-blur?))]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.blur")]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-css-property objects (first shapes) :filter)}])]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (->> shapes (filter has-blur?))]
(if new-css-system
(when (seq shapes)
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.blur")
:class (stl/css :title-spacing-blur)}
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-css-property objects (first shapes) :filter)}])]
(for [shape shapes]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.blur.value")]
[:div.attributes-value (css/get-css-value objects shape :filter)]
[:& copy-button {:data (css/get-css-property objects shape :filter)}]])])))
[:div {:class (stl/css :attributes-content)}
(for [shape shapes]
[:div {:class (stl/css :blur-row)}
[:div {:class (stl/css :global/attr-label)} "Filter"]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects shape :filter)}
[:div {:class (stl/css :button-children)}
(css/get-css-value objects shape :filter)]]]])]])
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.blur")]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-css-property objects (first shapes) :filter)}])]
(for [shape shapes]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.blur.value")]
[:div.attributes-value (css/get-css-value objects shape :filter)]
[:& copy-button {:data (css/get-css-property objects shape :filter)}]])]))))

View file

@ -0,0 +1,22 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-blur {
@extend .attr-title;
}
}
.attributes-content {
.blur-row {
@extend .attr-row;
}
.button-children {
@extend .copy-button-children;
}
}

View file

@ -5,11 +5,15 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.common
(:require-macros [app.main.style :as stl])
(:require
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.color-bullet :refer [color-bullet color-name]]
[app.main.ui.components.color-bullet-new :as cbn]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.util.color :as uc]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
@ -41,41 +45,143 @@
(or (mf/deref file-colors-ref) (mf/deref refs/workspace-file-colors)))
(mf/defc color-row [{:keys [color format copy-data on-change-format]}]
(let [colors-library (get-colors-library color)
file-colors (get-file-colors)
(let [new-css-system (mf/use-ctx ctx/new-css-system)
colors-library (get-colors-library color)
file-colors (get-file-colors)
color-library-name (get-in (or colors-library file-colors) [(:id color) :name])
color (assoc color :color-library-name color-library-name)]
[:div.attributes-color-row
(when color-library-name
[:div.attributes-color-id
[:& color-bullet {:color color}]
[:div color-library-name]])
color (assoc color :color-library-name color-library-name)]
[:div.attributes-color-value {:class (when color-library-name "hide-color")}
[:& color-bullet {:color color}]
(if new-css-system
[:div {:class (stl/css :attributes-color-row)}
[:div {:class (stl/css :bullet-wrapper)
:style #js {"--bullet-size" "16px"}}
[:& cbn/color-bullet {:color color
:mini? true}]]
(if (:gradient color)
[:& color-name {:color color}]
(case format
:rgba (let [[r g b a] (uc/hex->rgba (:color color) (:opacity color))]
[:div (str/fmt "%s, %s, %s, %s" r g b a)])
:hsla (let [[h s l a] (uc/hex->hsla (:color color) (:opacity color))
result (uc/format-hsla [h s l a])]
[:div result])
[:div {:class (stl/css :format-wrapper)}
(when-not (and on-change-format (:gradient color))
[:div {:class (stl/css :select-format-wrapper)}
[:& select
{:default-value format
:options [{:value :hex :label (tr "inspect.attributes.color.hex")}
{:value :rgba :label (tr "inspect.attributes.color.rgba")}
{:value :hsla :label (tr "inspect.attributes.color.hsla")}]
:on-change on-change-format}]])
(when (:gradient color)
[:div {:class (stl/css :format-info)} "rgba"])]
(if copy-data
[:& copy-button {:data copy-data
:class (stl/css :color-row-copy-btn)}
[:*
[:& color-name {:color color}]
(when-not (:gradient color) [:div (str (* 100 (:opacity color)) "%")])]))
[:div {:class (stl/css :first-row)}
[:div {:class (stl/css :name-opacity)}
[:span {:class (stl/css-case :color-value-wrapper true
:gradient-name (:gradient color))}
(if (:gradient color)
[:& cbn/color-name {:color color
:size 80}]
(case format
:hex [:& cbn/color-name {:color color
:size 80}]
:rgba (let [[r g b a] (uc/hex->rgba (:color color) (:opacity color))]
[:* (str/fmt "%s, %s, %s, %s" r g b a)])
:hsla (let [[h s l a] (uc/hex->hsla (:color color) (:opacity color))
result (uc/format-hsla [h s l a])]
[:* result])))]
(when-not (and on-change-format (:gradient color))
[:select.color-format-select {:on-change #(-> (dom/get-target-val %) keyword on-change-format)}
[:option {:value "hex"}
(tr "inspect.attributes.color.hex")]
(when-not (:gradient color)
[:span {:class (stl/css :opacity-info)}
(str (* 100 (:opacity color)) "%")])]]
[:option {:value "rgba"}
(tr "inspect.attributes.color.rgba")]
(when color-library-name
[:div {:class (stl/css :second-row)}
[:div {:class (stl/css :color-name-library)}
color-library-name]])]]
[:option {:value "hsla"}
(tr "inspect.attributes.color.hsla")]])]
(when copy-data
[:& copy-button {:data copy-data}])]))
[:div {:class (stl/css :color-info)}
[:div {:class (stl/css :first-row)}
[:div {:class (stl/css :name-opacity)}
[:span {:class (stl/css-case :color-value-wrapper true
:gradient-name (:gradient color))}
(if (:gradient color)
[:& cbn/color-name {:color color
:size 80}]
(case format
:hex [:& cbn/color-name {:color color
:size 80}]
:rgba (let [[r g b a] (uc/hex->rgba (:color color) (:opacity color))]
[:* (str/fmt "%s, %s, %s, %s" r g b a)])
:hsla (let [[h s l a] (uc/hex->hsla (:color color) (:opacity color))
result (uc/format-hsla [h s l a])]
[:* result])))]
(when-not (:gradient color)
[:span {:class (stl/css :opacity-info)}
(str (* 100 (:opacity color)) "%")])]]
(when color-library-name
[:div {:class (stl/css :second-row)}
[:div {:class (stl/css :color-name-library)}
color-library-name]])
;; [:span {:class (stl/css-case :color-name-wrapper true
;; :gradient-color (:gradient color))}
;; [:div {:class (stl/css :color-value-wrapper)}
;; (if (:gradient color)
;; [:& cbn/color-name {:color color
;; :size 80}]
;; (case format
;; :hex [:& cbn/color-name {:color color
;; :size 80}]
;; :rgba (let [[r g b a] (uc/hex->rgba (:color color) (:opacity color))]
;; [:* (str/fmt "%s, %s, %s, %s" r g b a)])
;; :hsla (let [[h s l a] (uc/hex->hsla (:color color) (:opacity color))
;; result (uc/format-hsla [h s l a])]
;; [:* result])))]
;; (when color-library-name
;; [:div {:class (stl/css :color-name-library)}
;; color-library-name])]
;; (when-not (:gradient color)
;; [:div {:class (stl/css :opacity-info)}
;; (str (* 100 (:opacity color)) "%")])
])]
[:div.attributes-color-row
(when color-library-name
[:div.attributes-color-id
[:& color-bullet {:color color}]
[:div color-library-name]])
[:div.attributes-color-value {:class (when color-library-name "hide-color")}
[:& color-bullet {:color color}]
(if (:gradient color)
[:& color-name {:color color}]
(case format
:rgba (let [[r g b a] (uc/hex->rgba (:color color) (:opacity color))]
[:div (str/fmt "%s, %s, %s, %s" r g b a)])
:hsla (let [[h s l a] (uc/hex->hsla (:color color) (:opacity color))
result (uc/format-hsla [h s l a])]
[:div result])
[:*
[:& color-name {:color color}]
(when-not (:gradient color) [:div (str (* 100 (:opacity color)) "%")])]))
(when-not (and on-change-format (:gradient color))
[:select.color-format-select {:on-change #(-> (dom/get-target-val %) keyword on-change-format)}
[:option {:value "hex"}
(tr "inspect.attributes.color.hex")]
[:option {:value "rgba"}
(tr "inspect.attributes.color.rgba")]
[:option {:value "hsla"}
(tr "inspect.attributes.color.hsla")]])]
(when copy-data
[:& copy-button {:data copy-data}])])))

View file

@ -0,0 +1,131 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-color-row {
display: grid;
grid-template-columns: $s-16 $s-72 $s-156;
gap: $s-4;
.bullet-wrapper {
@include flexCenter;
height: $s-32;
}
.format-wrapper {
width: $s-72;
height: $s-32;
.select-format-wrapper {
width: 100%;
div {
background-color: transparent;
border: none;
padding-left: $s-2;
color: var(--menu-foreground-color-rest);
}
}
.format-info {
@include tabTitleTipography;
display: flex;
align-items: center;
width: 100%;
height: 100%;
padding-left: $s-2;
font-size: $fs-12;
color: var(--menu-foreground-color-rest);
}
}
}
.color-info {
display: flex;
align-items: flex-start;
gap: $s-4;
flex-grow: 1;
.color-name-wrapper {
@include titleTipography;
@include flexColumn;
padding: $s-8 $s-4 $s-8 $s-8;
height: $s-32;
max-width: $s-80;
&.gradient-color {
max-width: $s-124;
}
.color-name-library {
@include titleTipography;
@include textEllipsis;
text-align: left;
height: $s-16;
color: var(--menu-foreground-color-rest);
}
.color-value-wrapper {
@include titleTipography;
height: $s-16;
color: var(--menu-foreground-color);
}
}
.opacity-info {
@include titleTipography;
color: var(--menu-foreground-color);
padding: $s-8 0;
height: $s-32;
}
button {
visibility: hidden;
min-width: $s-28;
}
&:hover button {
visibility: visible;
}
}
.color-info,
.color-row-copy-btn {
@include copyWrapper;
.first-row {
display: grid;
grid-template-columns: 1fr $s-20;
grid-template-areas: "name button";
height: fit-content;
width: 100%;
padding: 0;
margin: 0;
.name-opacity {
grid-area: name;
height: fit-content;
max-width: $s-124;
line-height: $s-16;
.color-value-wrapper {
@include inspectValue;
text-transform: uppercase;
max-width: $s-124;
padding-right: $s-8;
&.gradient-name {
text-transform: none;
}
}
.opacity-info {
@include inspectValue;
text-transform: uppercase;
}
}
}
.second-row {
min-height: $s-16;
padding-right: $s-8;
width: 100%;
text-align: left;
margin: 0;
padding: 0;
.color-name-library {
@include inspectValue;
color: var(--menu-foreground-color-rest);
}
}
}

View file

@ -5,7 +5,10 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.fill
(:require-macros [app.main.style :as stl])
(:require
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.viewer.inspect.attributes.common :refer [color-row]]
[app.util.code-gen.style-css :as css]
[app.util.i18n :refer [tr]]
@ -30,33 +33,63 @@
(mf/defc fill-block
{::mf/wrap-props false}
[{:keys [objects shape]}]
(let [format* (mf/use-state :hex)
(let [new-css-system (mf/use-ctx ctx/new-css-system)
format* (mf/use-state :hex)
format (deref format*)
color (shape->color shape)
on-change (mf/use-fn #(reset! format* %))]
on-change
(mf/use-fn
(fn [format]
(reset! format* format)))]
(if new-css-system
[:div {:class (stl/css :attributes-fill-block)}
[:& color-row
{:color color
:format format
:on-change-format on-change
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]]
[:div.attributes-fill-block
[:& color-row
{:color color
:format format
:on-change-format on-change
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]]))
[:div.attributes-fill-block
[:& color-row
{:color color
:format format
:on-change-format on-change
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]])))
(mf/defc fill-panel
{::mf/wrap-props false}
[{:keys [shapes]}]
(let [shapes (filter has-fill? shapes)]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.fill")]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (filter has-fill? shapes)]
(if new-css-system
(when (seq shapes)
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.fill")
:class (stl/css :title-spacing-fill)}]
[:div.attributes-fill-blocks
(for [shape shapes]
(if (seq (:fills shape))
(for [value (:fills shape [])]
[:& fill-block {:key (str "fill-block-" (:id shape) value)
:shape value}])
[:& fill-block {:key (str "fill-block-only" (:id shape))
:shape shape}]))]])))
[:div {:class (stl/css :attributes-content)}
(for [shape shapes]
(if (seq (:fills shape))
(for [value (:fills shape [])]
[:& fill-block {:key (str "fill-block-" (:id shape) value)
:shape value}])
[:& fill-block {:key (str "fill-block-only" (:id shape))
:shape shape}]))]])
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.fill")]]
[:div.attributes-fill-blocks
(for [shape shapes]
(if (seq (:fills shape))
(for [value (:fills shape [])]
[:& fill-block {:key (str "fill-block-" (:id shape) value)
:shape value}])
[:& fill-block {:key (str "fill-block-only" (:id shape))
:shape shape}]))]]))))

View file

@ -0,0 +1,14 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-fill {
@extend .attr-title;
}
}

View file

@ -5,9 +5,12 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.geometry
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.util.code-gen.style-css :as css]
[app.util.i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -16,23 +19,51 @@
(mf/defc geometry-block
[{:keys [objects shape]}]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div {:class (stl/css :geometry-row)}
[:div {:class (stl/css :global/attr-label)} (d/name property)]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects shape property)}
[:div {:class (stl/css :button-children)} value]]]]))]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])))
(mf/defc geometry-panel
[{:keys [objects shapes]}]
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.size")]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.size")
:class (stl/css :title-spacing-geometry)}
(for [shape shapes]
[:& geometry-block {:shape shape
:objects objects
:key (:id shape)}])])
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& geometry-block {:shape shape
:objects objects
:key (:id shape)}])]
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.size")]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& geometry-block {:shape shape
:objects objects
:key (:id shape)}])])))

View file

@ -0,0 +1,21 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-geometry {
@extend .attr-title;
}
}
.geometry-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}

View file

@ -5,11 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.image
(:require-macros [app.main.style :as stl])
(:require
[app.common.media :as cm]
[app.common.pages.helpers :as cph]
[app.config :as cf]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.context :as ctx]
[app.util.code-gen.style-css :as css]
[app.util.i18n :refer [tr]]
[cuerdas.core :as str]
@ -20,26 +22,58 @@
(mf/defc image-panel
[{:keys [objects shapes]}]
(for [shape (filter cph/image-shape? shapes)]
[:div.attributes-block {:key (str "image-" (:id shape))}
[:div.attributes-image-row
[:div.attributes-image
[:img {:src (cf/resolve-file-media (-> shape :metadata))}]]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
(for [shape (filter cph/image-shape? shapes)]
[:div {:class (stl/css :attributes-block)
:key (str "image-" (:id shape))}
[:div {:class (stl/css :image-wrapper)}
[:img {:src (cf/resolve-file-media (-> shape :metadata))}]]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.image.width")]
[:div.attributes-value (css/get-css-value objects (:metadata shape) :width)]
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :width)}]]
[:div {:class (stl/css :image-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.image.width")]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :width)}
[:div {:class (stl/css :button-children)} (css/get-css-value objects (:metadata shape) :width)]]]]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.image.height")]
[:div.attributes-value (css/get-css-value objects (:metadata shape) :height)]
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :height)}]]
[:div {:class (stl/css :image-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.image.height")]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :height)}
[:div {:class (stl/css :button-children)} (css/get-css-value objects (:metadata shape) :height)]]]]
(let [mtype (-> shape :metadata :mtype)
name (:name shape)
extension (cm/mtype->extension mtype)]
[:a.download-button {:target "_blank"
:download (cond-> name extension (str/concat extension))
:href (cf/resolve-file-media (-> shape :metadata))}
(tr "inspect.attributes.image.download")])]))
(let [mtype (-> shape :metadata :mtype)
name (:name shape)
extension (cm/mtype->extension mtype)]
[:a {:class (stl/css :download-button)
:target "_blank"
:download (cond-> name extension (str/concat extension))
:href (cf/resolve-file-media (-> shape :metadata))}
(tr "inspect.attributes.image.download")])])
(for [shape (filter cph/image-shape? shapes)]
[:div.attributes-block {:key (str "image-" (:id shape))}
[:div.attributes-image-row
[:div.attributes-image
[:img {:src (cf/resolve-file-media (-> shape :metadata))}]]]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.image.width")]
[:div.attributes-value (css/get-css-value objects (:metadata shape) :width)]
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :width)}]]
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.image.height")]
[:div.attributes-value (css/get-css-value objects (:metadata shape) :height)]
[:& copy-button {:data (css/get-css-property objects (:metadata shape) :height)}]]
(let [mtype (-> shape :metadata :mtype)
name (:name shape)
extension (cm/mtype->extension mtype)]
[:a.download-button {:target "_blank"
:download (cond-> name extension (str/concat extension))
:href (cf/resolve-file-media (-> shape :metadata))}
(tr "inspect.attributes.image.download")])]))))

View file

@ -0,0 +1,41 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
margin-bottom: $s-16;
.image-wrapper {
background-color: var(--menu-background-color);
position: relative;
@include flexCenter;
width: $s-248;
height: $s-160;
max-height: $s-160;
max-width: $s-248;
margin: $s-8 0;
border-radius: $br-8;
img {
height: 100%;
width: 100%;
object-fit: contain;
}
}
.image-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}
.download-button {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
margin-top: $s-4;
}
}

View file

@ -5,10 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.layout
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.util.code-gen.style-css :as css]
[rumext.v2 :as mf]))
@ -27,25 +30,56 @@
(mf/defc layout-block
[{:keys [objects shape]}]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div {:class (stl/css :layout-row)}
[:div {:class (stl/css :global/attr-label)} (d/name property)]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects shape property)}
[:div {:class (stl/css :button-children)} value]]]]))]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])))
(mf/defc layout-panel
[{:keys [objects shapes]}]
(let [shapes (->> shapes (filter ctl/any-layout?))]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text "Layout"]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(let [shapes (->> shapes (filter ctl/any-layout?))
new-css-system (mf/use-ctx ctx/new-css-system)]
(for [shape shapes]
[:& layout-block {:shape shape
:objects objects
:key (:id shape)}])])))
(if new-css-system
(when (seq shapes)
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title "Layout"
:class (stl/css :title-spacing-layout)}
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& layout-block {:shape shape
:objects objects
:key (:id shape)}])])
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text "Layout"]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& layout-block {:shape shape
:objects objects
:key (:id shape)}])]))))

View file

@ -0,0 +1,21 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-layout {
@extend .attr-title;
}
}
.layout-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}

View file

@ -5,10 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.layout-element
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.util.code-gen.style-css :as css]
[rumext.v2 :as mf]))
@ -27,34 +30,66 @@
(mf/defc layout-element-block
[{:keys [objects shape]}]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div {:class (stl/css :layout-element-row)}
[:div {:class (stl/css :global/attr-label)} (d/name property)]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (css/get-css-property objects shape property)}
[:div {:class (stl/css :button-children)} value]]]]))]
[:*
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
[:div.attributes-unit-row
[:div.attributes-label (d/name property)]
[:div.attributes-value value]
[:& copy-button {:data (css/get-css-property objects shape property)}]]))])))
(mf/defc layout-element-panel
[{:keys [objects shapes]}]
(let [shapes (->> shapes (filter #(ctl/any-layout-immediate-child? objects %)))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (->> shapes (filter #(ctl/any-layout-immediate-child? objects %)))
only-flex? (every? #(ctl/flex-layout-immediate-child? objects %) shapes)
only-grid? (every? #(ctl/grid-layout-immediate-child? objects %) shapes)]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (cond
only-flex?
"Flex element"
only-grid?
"Flex element"
:else
"Layout element"
)]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(if new-css-system
(when (seq shapes)
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (cond
only-flex?
"Flex element"
only-grid?
"Flex element"
:else
"Layout element")
:class (stl/css :title-spacing-layout-element)}
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& layout-element-block {:shape shape
:objects objects
:key (:id shape)}])])))
(for [shape shapes]
[:& layout-element-block {:shape shape
:objects objects
:key (:id shape)}])])
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (cond
only-flex?
"Flex element"
only-grid?
"Flex element"
:else
"Layout element")]
(when (= (count shapes) 1)
[:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])]
(for [shape shapes]
[:& layout-element-block {:shape shape
:objects objects
:key (:id shape)}])]))))

View file

@ -0,0 +1,21 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-layout-element {
@extend .attr-title;
}
}
.layout-element-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}

View file

@ -5,47 +5,71 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.shadow
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.viewer.inspect.attributes.common :refer [color-row]]
[app.util.code-gen.style-css-formats :as cssf]
[app.util.i18n :refer [tr]]
[rumext.v2 :as mf]))
(defn has-shadow? [shape]
(:shadow shape))
(mf/defc shadow-block [{:keys [shadow]}]
(let [color-format (mf/use-state :hex)]
[:div.attributes-shadow-block
[:div.attributes-shadow-row
[:div.attributes-label (->> shadow :style d/name (str "workspace.options.shadow-options.") (tr))]
[:div.attributes-shadow {:title (tr "workspace.options.shadow-options.offsetx")}
[:div.attributes-value (str (:offset-x shadow) "px")]]
[:div {:class (stl/css :attributes-shadow-block)}
[:div {:class (stl/css :shadow-row)}
[:div {:class (stl/css :global/attr-label)} (->> shadow :style d/name (str "workspace.options.shadow-options.") (tr))]
[:div {:class (stl/css :global/attr-value)}
[:div.attributes-shadow {:title (tr "workspace.options.shadow-options.offsety")}
[:div.attributes-value (str (:offset-y shadow) "px")]]
[:div.attributes-shadow {:title (tr "workspace.options.shadow-options.blur")}
[:div.attributes-value (str (:blur shadow) "px")]]
[:div.attributes-shadow {:title (tr "workspace.options.shadow-options.spread")}
[:div.attributes-value (str (:spread shadow) "px")]]
#_[:& copy-button {:data (shadow-copy-data shadow)}]]
[:& copy-button {:data (cssf/format-shadow (cssf/format-value :shadows shadow) shadow)
:class (stl/css :color-row-copy-btn)}
[:div {:class (stl/css :button-children)
:title (dm/str (tr "workspace.options.shadow-options.offsetx") " "
(tr "workspace.options.shadow-options.offsety") " "
(tr "workspace.options.shadow-options.blur") " "
(tr "workspace.options.shadow-options.spread"))}
(str (:offset-x shadow) "px") " "
(str (:offset-y shadow) "px") " "
(str (:blur shadow) "px") " "
(str (:spread shadow) "px")]]]]
[:& color-row {:color (:color shadow)
:format @color-format
:on-change-format #(reset! color-format %)}]]))
(mf/defc shadow-panel [{:keys [shapes]}]
(let [shapes (->> shapes (filter has-shadow?))]
(when (and (seq shapes) (> (count shapes) 0))
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.shadow")]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (->> shapes (filter has-shadow?))]
[:div.attributes-shadow-blocks
(for [shape shapes]
(for [shadow (:shadow shape)]
[:& shadow-block {:shape shape
:shadow shadow}]))]])))
(if new-css-system
(when (and (seq shapes) (> (count shapes) 0))
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.shadow")
:class (stl/css :title-spacing-shadow)}]
[:div {:class (stl/css :attributes-content)}
(for [shape shapes]
(for [shadow (:shadow shape)]
[:& shadow-block {:shape shape
:shadow shadow}]))]])
(when (and (seq shapes) (> (count shapes) 0))
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.shadow")]]
[:div.attributes-shadow-blocks
(for [shape shapes]
(for [shadow (:shadow shape)]
[:& shadow-block {:shape shape
:shadow shadow}]))]]))))

View file

@ -0,0 +1,22 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-shadow {
@extend .attr-title;
}
}
.attributes-shadow-block {
.shadow-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}
}

View file

@ -5,10 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.stroke
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.formats :as fmt]
[app.main.ui.viewer.inspect.attributes.common :refer [color-row]]
[app.util.code-gen.style-css-formats :as cssf]
@ -29,42 +32,82 @@
(mf/defc stroke-block
[{:keys [stroke]}]
(let [color-format (mf/use-state :hex)
color (stroke->color stroke)]
[:div.attributes-stroke-block
(let [{:keys [stroke-style stroke-alignment]} stroke
stroke-style (if (= stroke-style :svg) :solid stroke-style)
stroke-alignment (or stroke-alignment :center)]
[:div.attributes-stroke-row
[:div.attributes-label (tr "inspect.attributes.stroke.width")]
[:div.attributes-value (fmt/format-pixels (:stroke-width stroke))]
;; Execution time translation strings:
;; inspect.attributes.stroke.style.dotted
;; inspect.attributes.stroke.style.mixed
;; inspect.attributes.stroke.style.none
;; inspect.attributes.stroke.style.solid
[:div.attributes-value (tr (dm/str "inspect.attributes.stroke.style." (d/name stroke-style)))]
;; Execution time translation strings:
;; inspect.attributes.stroke.alignment.center
;; inspect.attributes.stroke.alignment.inner
;; inspect.attributes.stroke.alignment.outer
[:div.attributes-label (tr (dm/str "inspect.attributes.stroke.alignment." (d/name stroke-alignment)))]
[:& copy-button {:data (cssf/format-value :border (cssv/get-stroke-data stroke))}]])
[:& color-row {:color color
:format @color-format
:copy-data (uc/color->background color)
:on-change-format #(reset! color-format %)}]]))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
color-format (mf/use-state :hex)
color (stroke->color stroke)]
(if new-css-system
[:div {:class (stl/css :attributes-stroke-block)}
(let [{:keys [stroke-style stroke-alignment]} stroke
stroke-style (if (= stroke-style :svg) :solid stroke-style)
stroke-alignment (or stroke-alignment :center)
stroke-def (dm/str (fmt/format-pixels (:stroke-width stroke)) " "
(tr (dm/str "inspect.attributes.stroke.style." (or (d/name stroke-style) "none"))) " "
(tr (dm/str "inspect.attributes.stroke.alignment." (d/name stroke-alignment))))]
[:*
[:& color-row {:color color
:format @color-format
:copy-data (uc/color->background color)
:on-change-format #(reset! color-format %)}]
[:div {:class (stl/css :stroke-row)}
[:div {:class (stl/css :global/attr-label)}
"Border"]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (cssf/format-value :border (cssv/get-stroke-data stroke))}
[:div {:class (stl/css :button-children)} stroke-def]]]]])]
[:div.attributes-stroke-block
(let [{:keys [stroke-style stroke-alignment]} stroke
stroke-style (if (= stroke-style :svg) :solid stroke-style)
stroke-alignment (or stroke-alignment :center)]
[:div.attributes-stroke-row
[:div.attributes-label (tr "inspect.attributes.stroke.width")]
[:div.attributes-value (fmt/format-pixels (:stroke-width stroke))]
;; Execution time translation strings:
;; inspect.attributes.stroke.style.dotted
;; inspect.attributes.stroke.style.mixed
;; inspect.attributes.stroke.style.none
;; inspect.attributes.stroke.style.solid
[:div.attributes-value (tr (dm/str "inspect.attributes.stroke.style." (d/name stroke-style)))]
;; Execution time translation strings:
;; inspect.attributes.stroke.alignment.center
;; inspect.attributes.stroke.alignment.inner
;; inspect.attributes.stroke.alignment.outer
[:div.attributes-label (tr (dm/str "inspect.attributes.stroke.alignment." (d/name stroke-alignment)))]
[:& copy-button {:data (cssf/format-value :border (cssv/get-stroke-data stroke))}]])
[:& color-row {:color color
:format @color-format
:copy-data (uc/color->background color)
:on-change-format #(reset! color-format %)}]])))
(mf/defc stroke-panel
[{:keys [shapes]}]
(let [shapes (->> shapes (filter has-stroke?))]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.stroke")]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shapes (->> shapes (filter has-stroke?))]
(if new-css-system
(when (seq shapes)
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.stroke")
:class (stl/css :title-spacing-stroke)}]
[:div.attributes-stroke-blocks
(for [shape shapes]
(for [value (:strokes shape)]
[:& stroke-block {:key (str "stroke-color-" (:id shape) value)
:stroke value}]))]])))
[:div {:class (stl/css :attributes-content)}
(for [shape shapes]
(for [value (:strokes shape)]
[:& stroke-block {:key (str "stroke-color-" (:id shape) value)
:stroke value}]))]])
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.stroke")]]
[:div.attributes-stroke-blocks
(for [shape shapes]
(for [value (:strokes shape)]
[:& stroke-block {:key (str "stroke-color-" (:id shape) value)
:stroke value}]))]]))))

View file

@ -0,0 +1,23 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-stroke {
@extend .attr-title;
}
}
.attributes-stroke-block {
@include flexColumn;
.stroke-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}
}

View file

@ -5,9 +5,12 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.svg
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.util.i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
@ -18,19 +21,38 @@
(str/join "; ")))
(mf/defc svg-attr [{:keys [attr value]}]
(if (map? value)
[:*
[:div.attributes-block-title
[:div.attributes-block-title-text (d/name attr)]
[:& copy-button {:data (map->css value)}]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
(for [[attr-key attr-value] value]
[:& svg-attr {:attr attr-key :value attr-value}])]
(if (map? value)
[:*
[:div {:class (stl/css :attributes-subtitle)}
[:span (d/name attr)]
[:& copy-button {:data (map->css value)}]]
[:div.attributes-unit-row
[:div.attributes-label (d/name attr)]
[:div.attributes-value (str value)]
[:& copy-button {:data (d/name value)}]]))
(for [[attr-key attr-value] value]
[:& svg-attr {:attr attr-key :value attr-value}])]
[:div {:class (stl/css :svg-row)}
[:div {:class (stl/css :global/attr-label)} (d/name attr)]
[:div {:class (stl/css :global/attr-value)}
[:& copy-button {:data (d/name value)}
[:div {:class (stl/css :button-children)} (str value)]]]])
(if (map? value)
[:*
[:div.attributes-block-title
[:div.attributes-block-title-text (d/name attr)]
[:& copy-button {:data (map->css value)}]]
(for [[attr-key attr-value] value]
[:& svg-attr {:attr attr-key :value attr-value}])]
[:div.attributes-unit-row
[:div.attributes-label (d/name attr)]
[:div.attributes-value (str value)]
[:& copy-button {:data (d/name value)}]]))))
(mf/defc svg-block
[{:keys [shape]}]
@ -42,9 +64,19 @@
(mf/defc svg-panel
[{:keys [shapes]}]
(let [shape (first shapes)]
(when (seq (:svg-attrs shape))
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "workspace.sidebar.options.svg-attrs.title")]]
[:& svg-block {:shape shape}]])))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
shape (first shapes)]
(if new-css-system
(when (seq (:svg-attrs shape))
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "workspace.sidebar.options.svg-attrs.title")
:class (stl/css :title-spacing-svg)}]
[:& svg-block {:shape shape}]])
(when (seq (:svg-attrs shape))
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "workspace.sidebar.options.svg-attrs.title")]]
[:& svg-block {:shape shape}]]))))

View file

@ -0,0 +1,40 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-svg {
@extend .attr-title;
}
}
.svg-row {
@extend .attr-row;
.button-children {
@extend .copy-button-children;
}
}
.attributes-subtitle {
@include tabTitleTipography;
display: flex;
justify-content: space-between;
height: $s-32;
span {
height: $s-32;
display: flex;
align-items: center;
}
button {
display: none;
}
&:hover {
button {
display: block;
}
}
}

View file

@ -5,12 +5,16 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.attributes.text
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.common.text :as txt]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.formats :as fmt]
[app.main.ui.viewer.inspect.attributes.common :refer [color-row]]
[app.util.i18n :refer [tr]]
@ -39,105 +43,211 @@
(mf/defc typography-block
[{:keys [text style]}]
(let [typography-library-ref
(let [new-css-system (mf/use-ctx ctx/new-css-system)
typography-library-ref
(mf/use-memo
(mf/deps (:typography-ref-file style))
(make-typographies-library-ref (:typography-ref-file style)))
typography-library (mf/deref typography-library-ref)
file-typographies (mf/deref file-typographies-ref)
file-typographies-viewer (mf/deref file-typographies-ref)
file-typographies-workspace (mf/deref refs/workspace-file-typography)
file-library-workspace (get (mf/deref refs/workspace-libraries) (:typography-ref-file style))
typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)])
color-format (mf/use-state :hex)
typography (get (or typography-library file-typographies) (:typography-ref-id style))]
typography (or (get (or typography-library file-typographies-viewer file-typographies-workspace) (:typography-ref-id style)) typography-external-lib)]
[:div.attributes-text-block
(if (:typography-ref-id style)
[:div.attributes-typography-name-row
[:div.typography-entry
[:div.typography-sample
{:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.text-styles")]]
[:div.typography-entry-name (:name typography)]
#_[:& copy-button {:data (copy-style-data typography)}]]
(if new-css-system
[:div {:class (stl/css :attributes-content)}
(when (:fills style)
(for [[idx fill] (map-indexed vector (:fills style))]
[:& color-row {:key idx
:format @color-format
:color (fill->color fill)
;;:copy-data (copy-style-data fill :fill-color :fill-color-gradient)
:on-change-format #(reset! color-format %)}]))
[:div.attributes-typography-row
[:div.typography-sample
{:style {:font-family (:font-family style)
:font-weight (:font-weight style)
:font-style (:font-style style)}}
(tr "workspace.assets.typography.text-styles")]
#_[:& copy-button {:data (copy-style-data style)}]])
(when (:typography-ref-id style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography")]
[:div {:class (stl/css :global/attr-value)}
[:div (:name typography)]
#_[:& copy-button {:data (copy-style-data typography)}]]])
(when (:fills style)
(for [[idx fill] (map-indexed vector (:fills style))]
[:& color-row {:key idx
:format @color-format
:color (fill->color fill)
;;:copy-data (copy-style-data fill :fill-color :fill-color-gradient)
:on-change-format #(reset! color-format %)}]))
(when (:font-id style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)} (tr "inspect.attributes.typography.font-family")]
[:div {:class (stl/css :global/attr-value)}
[:div (-> style :font-id fonts/get-font-data :name)]
#_[:& copy-button {:data (copy-style-data style :font-family)}]]])
(when (:font-id style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-family")]
[:div.attributes-value (-> style :font-id fonts/get-font-data :name)]
#_[:& copy-button {:data (copy-style-data style :font-family)}]])
(when (:font-style style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.font-style")]
[:div {:class (stl/css :global/attr-value)}
[:div (str (:font-style style))]
#_[:& copy-button {:data (copy-style-data style :font-style)}]]])
(when (:font-style style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-style")]
[:div.attributes-value (str (:font-style style))]
#_[:& copy-button {:data (copy-style-data style :font-style)}]])
(when (:font-size style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.font-size")]
[:div {:class (stl/css :global/attr-value)}
[:div (fmt/format-pixels (:font-size style))]
#_[:& copy-button {:data (copy-style-data style :font-size)}]]])
(when (:font-size style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-size")]
[:div.attributes-value (fmt/format-pixels (:font-size style))]
#_[:& copy-button {:data (copy-style-data style :font-size)}]])
(when (:font-weight style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.font-weight")]
[:div {:class (stl/css :global/attr-value)}
[:span (str (:font-weight style))]
#_[:& copy-button {:data (copy-style-data style :font-weight)}]]])
(when (:font-weight style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-weight")]
[:div.attributes-value (str (:font-weight style))]
#_[:& copy-button {:data (copy-style-data style :font-weight)}]])
(when (:line-height style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.line-height")]
[:div {:class (stl/css :global/attr-value)}
[:div (fmt/format-number (:line-height style))]
#_[:& copy-button {:data (copy-style-data style :line-height)}]]])
(when (:line-height style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.line-height")]
[:div.attributes-value (fmt/format-number (:line-height style))]
#_[:& copy-button {:data (copy-style-data style :line-height)}]])
(when (:letter-spacing style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.letter-spacing")]
[:div {:class (stl/css :global/attr-value)}
[:div (fmt/format-pixels (:letter-spacing style))]
#_[:& copy-button {:data (copy-style-data style :letter-spacing)}]]])
(when (:letter-spacing style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.letter-spacing")]
[:div.attributes-value (fmt/format-pixels (:letter-spacing style))]
#_[:& copy-button {:data (copy-style-data style :letter-spacing)}]])
(when (:text-decoration style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.text-decoration")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-decoration.none
;; inspect.attributes.typography.text-decoration.strikethrough
;; inspect.attributes.typography.text-decoration.underline
[:div {:class (stl/css :global/attr-value)}
[:div (tr (dm/str "inspect.attributes.typography.text-decoration." (:text-decoration style)))]
#_[:& copy-button {:data (copy-style-data style :text-decoration)}]]])
(when (:text-decoration style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.text-decoration")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-decoration.none
;; inspect.attributes.typography.text-decoration.strikethrough
;; inspect.attributes.typography.text-decoration.underline
[:div.attributes-value (tr (dm/str "inspect.attributes.typography.text-decoration." (:text-decoration style)))]
#_[:& copy-button {:data (copy-style-data style :text-decoration)}]])
(when (:text-transform style)
[:div {:class (stl/css :text-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.typography.text-transform")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-transform.lowercase
;; inspect.attributes.typography.text-transform.none
;; inspect.attributes.typography.text-transform.titlecase
;; inspect.attributes.typography.text-transform.uppercase
;; inspect.attributes.typography.text-transform.unset
[:div {:class (stl/css :global/attr-value)}
[:div (tr (dm/str "inspect.attributes.typography.text-transform." (:text-transform style)))]
#_[:& copy-button {:data (copy-style-data style :text-transform)}]]])
(when (:text-transform style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.text-transform")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-transform.lowercase
;; inspect.attributes.typography.text-transform.none
;; inspect.attributes.typography.text-transform.titlecase
;; inspect.attributes.typography.text-transform.uppercase
[:div.attributes-value (tr (dm/str "inspect.attributes.typography.text-transform." (:text-transform style)))]
#_[:& copy-button {:data (copy-style-data style :text-transform)}]])
[:& copy-button {:data (str/trim text)
:class (stl/css :attributes-content-row)}
[:span {:class (stl/css :content)
:style {:font-family (:font-family style)
:font-weight (:font-weight style)
:font-style (:font-style style)}}
(str/trim text)]]]
[:div.attributes-content-row
[:pre.attributes-content (str/trim text)]
[:& copy-button {:data (str/trim text)}]]]))
[:div.attributes-text-block
(if (:typography-ref-id style)
[:div.attributes-typography-name-row
[:div.typography-entry
[:div.typography-sample
{:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.text-styles")]]
[:div.typography-entry-name (:name typography)]
#_[:& copy-button {:data (copy-style-data typography)}]]
[:div.attributes-typography-row
[:div.typography-sample
{:style {:font-family (:font-family style)
:font-weight (:font-weight style)
:font-style (:font-style style)}}
(tr "workspace.assets.typography.text-styles")]
#_[:& copy-button {:data (copy-style-data style)}]])
(when (:fills style)
(for [[idx fill] (map-indexed vector (:fills style))]
[:& color-row {:key idx
:format @color-format
:color (fill->color fill)
;;:copy-data (copy-style-data fill :fill-color :fill-color-gradient)
:on-change-format #(reset! color-format %)}]))
(when (:font-id style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-family")]
[:div.attributes-value (-> style :font-id fonts/get-font-data :name)]
#_[:& copy-button {:data (copy-style-data style :font-family)}]])
(when (:font-style style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-style")]
[:div.attributes-value (str (:font-style style))]
#_[:& copy-button {:data (copy-style-data style :font-style)}]])
(when (:font-size style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-size")]
[:div.attributes-value (fmt/format-pixels (:font-size style))]
#_[:& copy-button {:data (copy-style-data style :font-size)}]])
(when (:font-weight style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.font-weight")]
[:div.attributes-value (str (:font-weight style))]
#_[:& copy-button {:data (copy-style-data style :font-weight)}]])
(when (:line-height style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.line-height")]
[:div.attributes-value (fmt/format-number (:line-height style))]
#_[:& copy-button {:data (copy-style-data style :line-height)}]])
(when (:letter-spacing style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.letter-spacing")]
[:div.attributes-value (fmt/format-pixels (:letter-spacing style))]
#_[:& copy-button {:data (copy-style-data style :letter-spacing)}]])
(when (:text-decoration style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.text-decoration")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-decoration.none
;; inspect.attributes.typography.text-decoration.strikethrough
;; inspect.attributes.typography.text-decoration.underline
[:div.attributes-value (tr (dm/str "inspect.attributes.typography.text-decoration." (:text-decoration style)))]
#_[:& copy-button {:data (copy-style-data style :text-decoration)}]])
(when (:text-transform style)
[:div.attributes-unit-row
[:div.attributes-label (tr "inspect.attributes.typography.text-transform")]
;; Execution time translation strings:
;; inspect.attributes.typography.text-transform.lowercase
;; inspect.attributes.typography.text-transform.none
;; inspect.attributes.typography.text-transform.titlecase
;; inspect.attributes.typography.text-transform.uppercase
[:div.attributes-value (tr (dm/str "inspect.attributes.typography.text-transform." (:text-transform style)))]
#_[:& copy-button {:data (copy-style-data style :text-transform)}]])
[:div.attributes-content-row
[:pre.attributes-content (str/trim text)]
[:& copy-button {:data (str/trim text)}]]])))
(mf/defc text-block [{:keys [shape]}]
@ -147,7 +257,7 @@
(mapv (fn [[style text]] (vector (merge txt/default-text-attrs style) text))))]
(for [[idx [full-style text]] (map-indexed vector style-text-blocks)]
[:& typography-block {:key idx
[:& typography-block {:key idx
:shape shape
:style full-style
:text text}])))
@ -155,10 +265,21 @@
(mf/defc text-panel
[{:keys [shapes]}]
(when-let [shapes (seq (filter has-text? shapes))]
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.typography")]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :attributes-block)}
[:& title-bar {:collapsable? false
:title (tr "inspect.attributes.typography")
:class (stl/css :title-spacing-text)}]
(for [shape shapes]
[:& text-block {:shape shape
:key (str "text-block" (:id shape))}])]))
(for [shape shapes]
[:& text-block {:shape shape
:key (str "text-block" (:id shape))}])]
[:div.attributes-block
[:div.attributes-block-title
[:div.attributes-block-title-text (tr "inspect.attributes.typography")]]
(for [shape shapes]
[:& text-block {:shape shape
:key (str "text-block" (:id shape))}])]))))

View file

@ -0,0 +1,45 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.attributes-block {
@include flexColumn;
.title-spacing-text {
@extend .attr-title;
}
}
.attributes-content {
@include flexColumn;
.text-row {
@extend .attr-row;
:global(.attr-value) {
align-items: center;
}
}
.attributes-content-row {
width: $s-252;
max-width: $s-252;
min-height: calc($s-2 + $s-32);
border-radius: $br-8;
border: $s-1 solid var(--menu-border-color-disabled);
margin-top: $s-4;
.content {
@include titleTipography;
width: 100%;
padding: 0;
color: var(--color-foreground-secondary);
}
&:hover {
border: $s-1 solid var(--color-background-tertiary);
background-color: var(--menu-background-color);
.content {
color: var(--menu-foreground-color-hover);
}
}
}
}

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.code
(:require-macros [app.main.style :as stl])
(:require
["js-beautify" :as beautify]
[app.common.data :as d]
@ -14,13 +15,14 @@
[app.common.types.shape-tree :as ctst]
[app.config :as cfg]
[app.main.data.events :as ev]
;; [app.main.data.preview :as dp]
[app.main.fonts :as fonts]
;; [app.main.data.preview :as dp]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.code-block :refer [code-block]]
[app.main.ui.components.copy-button :refer [copy-button]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.icons :as i]
@ -108,7 +110,8 @@
(mf/defc code
[{:keys [shapes frame on-expand from]}]
(let [style-type* (mf/use-state "css")
(let [new-css-system (mf/use-ctx ctx/new-css-system)
style-type* (mf/use-state "css")
markup-type* (mf/use-state "html")
fontfaces-css* (mf/use-state nil)
images-data* (mf/use-state nil)
@ -227,55 +230,120 @@
(fn [result]
(reset! images-data* result)))))
[:div.element-options
[:div.attributes-block
[:button.download-button {:on-click handle-copy-all-code}
"Copy all code"]]
(if new-css-system
[:div {:class (stl/css :element-options)}
[:div {:class (stl/css :attributes-block)}
[:button {:class (stl/css :download-button)
:on-click handle-copy-all-code}
"Copy all code"]]
#_[:div.attributes-block
[:button.download-button {:on-click handle-open-review}
"Preview"]]
#_[:div.attributes-block
[:button.download-button {:on-click handle-open-review}
"Preview"]]
[:div.code-block
[:div.code-row-lang
[:& select {:default-value style-type
:class "custom-select"
:options [{:label "CSS" :value "css"}]
:on-change set-style}]
[:button.expand-button
{:on-click on-expand}
i/full-screen]
[:div {:class (stl/css :code-block)}
[:div {:class (stl/css :code-row-lang)}
[:span {:class (stl/css :code-lang)} "CSS"]
;; Active select when we have more than one option
;; [:& select {:default-value style-type
;; :class (stl/css :code-lang-select)
;; :options [{:label "CSS" :value "css"}]
;; :on-change set-style}]
[:div {:class (stl/css :action-btns)}
[:button {:class (stl/css :expand-button)
:on-click on-expand}
i/code-refactor]
[:& copy-button {:data style-code
:on-copied on-style-copied}]]
[:& copy-button {:data style-code
:on-copied on-style-copied}]]]
[:div.code-row-display {:style #js {"--code-height" (str (or style-size 400) "px")}}
[:& code-block {:type style-type
:code style-code}]]
[:div {:class (stl/css :code-row-display)
:style #js {"--code-height" (str (or style-size 400) "px")}}
[:& code-block {:type style-type
:code style-code}]]
[:div.resize-area {:on-pointer-down on-style-pointer-down
:on-lost-pointer-capture on-style-lost-pointer-capture
:on-pointer-move on-style-pointer-move}]]
[:div {:class (stl/css :resize-area)
:on-pointer-down on-style-pointer-down
:on-lost-pointer-capture on-style-lost-pointer-capture
:on-pointer-move on-style-pointer-move}]]
[:div.code-block
[:div.code-row-lang
[:& select {:default-value markup-type
:class "input-option"
:options [{:label "HTML" :value "html"}
{:label "SVG" :value "svg"}]
:on-change set-markup}]
[:div {:class (stl/css :code-block)}
[:div {:class (stl/css :code-row-lang)}
[:& select {:default-value markup-type
:class (stl/css :code-lang-select)
:options [{:label "HTML" :value "html"}
{:label "SVG" :value "svg"}]
:on-change set-markup}]
[:button.expand-button
{:on-click on-expand}
i/full-screen]
[:div {:class (stl/css :action-btns)}
[:button {:class (stl/css :expand-button)
:on-click on-expand}
i/code-refactor]
[:& copy-button {:data #(replace-map markup-code images-data)
:on-copied on-markup-copied}]]
[:& copy-button {:data #(replace-map markup-code images-data)
:on-copied on-markup-copied}]]]
[:div.code-row-display {:style #js {"--code-height" (str (or markup-size 400) "px")}}
[:& code-block {:type markup-type
:code markup-code}]]
[:div {:class (stl/css :code-row-display)
:style #js {"--code-height" (str (or markup-size 400) "px")}}
[:& code-block {:type markup-type
:code markup-code}]]
[:div.resize-area {:on-pointer-down on-markup-pointer-down
:on-lost-pointer-capture on-markup-lost-pointer-capture
:on-pointer-move on-markup-pointer-move}]]]))
[:div {:class (stl/css :resize-area)
:on-pointer-down on-markup-pointer-down
:on-lost-pointer-capture on-markup-lost-pointer-capture
:on-pointer-move on-markup-pointer-move}]]]
[:div.element-options
[:div.attributes-block
[:button.download-button {:on-click handle-copy-all-code}
"Copy all code"]]
#_[:div.attributes-block
[:button.download-button {:on-click handle-open-review}
"Preview"]]
[:div.code-block
[:div.code-row-lang
[:& select {:default-value style-type
:class "custom-select"
:options [{:label "CSS" :value "css"}]
:on-change set-style}]
[:button.expand-button
{:on-click on-expand}
i/full-screen]
[:& copy-button {:data style-code
:on-copied on-style-copied}]]
[:div.code-row-display {:style #js {"--code-height" (str (or style-size 400) "px")}}
[:& code-block {:type style-type
:code style-code}]]
[:div.resize-area {:on-pointer-down on-style-pointer-down
:on-lost-pointer-capture on-style-lost-pointer-capture
:on-pointer-move on-style-pointer-move}]]
[:div.code-block
[:div.code-row-lang
[:& select {:default-value markup-type
:class "input-option"
:options [{:label "HTML" :value "html"}
{:label "SVG" :value "svg"}]
:on-change set-markup}]
[:button.expand-button
{:on-click on-expand}
i/full-screen]
[:& copy-button {:data #(replace-map markup-code images-data)
:on-copied on-markup-copied}]]
[:div.code-row-display {:style #js {"--code-height" (str (or markup-size 400) "px")}}
[:& code-block {:type markup-type
:code markup-code}]]
[:div.resize-area {:on-pointer-down on-markup-pointer-down
:on-lost-pointer-capture on-markup-lost-pointer-capture
:on-pointer-move on-markup-pointer-move}]]])))

View file

@ -0,0 +1,57 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.element-options {
.attributes-block {
.download-button {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
width: 100%;
margin: $s-8 0;
}
}
.code-block {
.code-row-lang {
display: flex;
justify-content: space-between;
gap: $s-4;
width: 100%;
.code-lang {
@include tabTitleTipography;
display: flex;
align-items: center;
}
.action-btns {
display: flex;
gap: $s-4;
.expand-button {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
}
.code-lang-select {
@include tabTitleTipography;
width: $s-92;
border: $s-1 solid transparent;
background-color: transparent;
color: var(--menu-foreground-color-disabled);
}
}
.code-row-display {
margin-bottom: $s-8;
}
}
}

View file

@ -5,11 +5,15 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.exports
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.main.data.exports :as de]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :refer [tr c]]
@ -19,7 +23,8 @@
(mf/defc exports
{::mf/wrap [#(mf/memo % =)]}
[{:keys [shapes page-id file-id share-id type] :as props}]
(let [exports (mf/use-state [])
(let [new-css-system (mf/use-ctx ctx/new-css-system)
exports (mf/use-state [])
xstate (mf/deref refs/export)
vstate (mf/deref refs/viewer-data)
page (get-in vstate [:pages page-id])
@ -109,7 +114,20 @@
(fn [event]
(let [esc? (kbd/esc? event)]
(when esc?
(dom/blur! (dom/get-target event))))))]
(dom/blur! (dom/get-target event))))))
size-options [{:value "0.5" :label "0.5x"}
{:value "0.75" :label "0.75x"}
{:value "1" :label "1x"}
{:value "1.5" :label "1.5x"}
{:value "2" :label "2x"}
{:value "4" :label "4x"}
{:value "6" :label "6"}]
format-options [{:value "png" :label "PNG"}
{:value "jpeg" :label "JPE"}
{:value "svg" :label "SVG"}
{:value "pdf" :label "PDF"}]]
(mf/use-effect
(mf/deps shapes)
@ -118,46 +136,111 @@
flatten
distinct
vec))))
(if new-css-system
[:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-title)}
[:& title-bar {:collapsable? false
:title (tr "workspace.options.export")
:class (stl/css :title-spacing-export-viewer)}
[:button {:class (stl/css :add-export)
:on-click add-export} i/add-refactor]]]
[:div.element-set.exports-options
[:div.element-set-title
[:span (tr "workspace.options.export")]
[:div.add-page {:on-click add-export} i/close]]
(cond
(= :multiple exports)
[:div {:class (stl/css :multiple-exports)}
[:div {:class (stl/css :label)} (tr "settings.multiple")]
[:div {:class (stl/css :actions)}
[:button {:class (stl/css :action-btn)
:on-click ()}
i/remove-refactor]]]
(when (seq @exports)
[:div.element-set-content
(for [[index export] (d/enumerate @exports)]
[:div.element-set-options-group
{:key index}
(when (scale-enabled? export)
[:select.input-select {:on-change (partial on-scale-change index)
:value (:scale export)}
[:option {:value "0.5"} "0.5x"]
[:option {:value "0.75"} "0.75x"]
[:option {:value "1"} "1x"]
[:option {:value "1.5"} "1.5x"]
[:option {:value "2"} "2x"]
[:option {:value "4"} "4x"]
[:option {:value "6"} "6x"]])
(seq @exports)
[:div {:class (stl/css :element-set-content)}
(for [[index export] (d/enumerate @exports)]
[:div {:class (stl/css :element-group)
:key index}
[:div {:class (stl/css :input-wrapper)}
[:div {:class (stl/css :format-select)}
[:& select
{:default-value (d/name (:type export))
:options format-options
:dropdown-class (stl/css :dropdown-upwards)
:on-change (partial on-type-change index)}]]
(when (scale-enabled? export)
[:div {:class (stl/css :size-select)}
[:& select
{:default-value (str (:scale export))
:options size-options
:dropdown-class (stl/css :dropdown-upwards)
:on-change (partial on-scale-change index)}]])
[:label {:class (stl/css :suffix-input)
:for "suffix-export-input"}
[:input {:class (stl/css :type-input)
:id "suffix-export-input"
:type "text"
:value (:suffix export)
:placeholder (tr "workspace.options.export.suffix")
:data-value index
:on-change on-suffix-change
:on-key-down manage-key-down}]]]
[:input.input-text {:value (:suffix export)
:placeholder (tr "workspace.options.export.suffix")
:on-change (partial on-suffix-change index)
:on-key-down manage-key-down}]
[:select.input-select {:value (d/name (:type export))
:on-change (partial on-type-change index)}
[:option {:value "png"} "PNG"]
[:option {:value "jpeg"} "JPEG"]
[:option {:value "svg"} "SVG"]
[:option {:value "pdf"} "PDF"]]
[:div.delete-icon {:on-click (partial delete-export index)}
i/minus]])
[:button {:class (stl/css :action-btn)
:on-click (partial delete-export index)}
i/remove-refactor]])
])
(when (or (= :multiple exports) (seq @exports))
[:button
{:on-click (when-not in-progress? on-download)
:class (stl/css-case
:export-btn true
:btn-disabled in-progress?)
:disabled in-progress?}
(if in-progress?
(tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count shapes))))])
]
[:div.btn-icon-dark.download-button
{:on-click (when-not in-progress? on-download)
:class (dom/classnames :btn-disabled in-progress?)
:disabled in-progress?}
(if in-progress?
(tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count shapes))))]])]))
[:div.element-set.exports-options
[:div.element-set-title
[:span (tr "workspace.options.export")]
[:div.add-page {:on-click add-export} i/close]]
(when (seq @exports)
[:div.element-set-content
(for [[index export] (d/enumerate @exports)]
[:div.element-set-options-group
{:key index}
(when (scale-enabled? export)
[:select.input-select {:on-change (partial on-scale-change index)
:value (:scale export)}
[:option {:value "0.5"} "0.5x"]
[:option {:value "0.75"} "0.75x"]
[:option {:value "1"} "1x"]
[:option {:value "1.5"} "1.5x"]
[:option {:value "2"} "2x"]
[:option {:value "4"} "4x"]
[:option {:value "6"} "6x"]])
[:input.input-text {:value (:suffix export)
:placeholder (tr "workspace.options.export.suffix")
:on-change (partial on-suffix-change index)
:on-key-down manage-key-down}]
[:select.input-select {:value (d/name (:type export))
:on-change (partial on-type-change index)}
[:option {:value "png"} "PNG"]
[:option {:value "jpeg"} "JPEG"]
[:option {:value "svg"} "SVG"]
[:option {:value "pdf"} "PDF"]]
[:div.delete-icon {:on-click (partial delete-export index)}
i/minus]])
[:div.btn-icon-dark.download-button
{:on-click (when-not in-progress? on-download)
:class (dom/classnames :btn-disabled in-progress?)
:disabled in-progress?}
(if in-progress?
(tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count shapes))))]])])))

View file

@ -0,0 +1,87 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.element-set {
.element-title {
.title-spacing-export-viewer {
@extend .attr-title;
}
.add-export {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
.element-set-content {
@include flexColumn;
margin-bottom: $s-4;
.multiple-exports {
@include flexRow;
.label {
@extend .mixed-bar;
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
}
.element-group {
@include flexRow;
.input-wrapper {
@include flexRow;
.format-select {
width: $s-60;
padding: 0;
.dropdown-upwards {
bottom: $s-36;
width: $s-80;
top: unset;
}
}
.size-select {
width: $s-60;
padding: 0;
.dropdown-upwards {
bottom: $s-36;
top: unset;
width: $s-80;
}
}
.suffix-input {
@extend .input-element;
min-width: $s-92;
flex-grow: 1;
}
}
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
}
.export-btn {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
width: $s-252;
}
}

View file

@ -5,12 +5,15 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.right-sidebar
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.common.types.component :as ctk]
[app.main.refs :as refs]
[app.main.ui.components.shape-icon :as si]
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.viewer.inspect.attributes :refer [attributes]]
[app.main.ui.viewer.inspect.code :refer [code]]
@ -40,24 +43,25 @@
(mf/defc right-sidebar
[{:keys [frame page objects file selected shapes page-id file-id share-id from on-change-section on-expand]
:or {from :inspect}}]
(let [section (mf/use-state :info #_:code)
objects (or objects (:objects page))
shapes (or shapes
(resolve-shapes objects selected))
first-shape (first shapes)
page-id (or page-id (:id page))
file-id (or file-id (:id file))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
section (mf/use-state :info #_:code)
objects (or objects (:objects page))
shapes (or shapes
(resolve-shapes objects selected))
first-shape (first shapes)
page-id (or page-id (:id page))
file-id (or file-id (:id file))
libraries (get-libraries from)
libraries (get-libraries from)
file (mf/deref refs/viewer-file)
components-v2 (dm/get-in file [:data :options :components-v2])
main-instance? (if components-v2
(ctk/main-instance? first-shape)
true)
file (mf/deref refs/viewer-file)
components-v2 (dm/get-in file [:data :options :components-v2])
main-instance? (if components-v2
(ctk/main-instance? first-shape)
true)
handle-change-tab
(mf/use-callback
(mf/use-fn
(mf/deps from on-change-section)
(fn [new-section]
(reset! section new-section)
@ -65,10 +69,15 @@
(on-change-section new-section))))
handle-expand
(mf/use-callback
(mf/use-fn
(mf/deps on-expand)
(fn []
(when on-expand (on-expand))))]
(when on-expand (on-expand))))
navigate-to-help
(mf/use-fn
(fn []
(dom/open-new-window "https://help.penpot.app/user-guide/inspect/")))]
(mf/use-effect
(mf/deps shapes handle-change-tab)
@ -76,52 +85,113 @@
(when-not (seq shapes)
(handle-change-tab :info))))
[:aside.settings-bar.settings-bar-right
[:div.settings-bar-inside
(if (seq shapes)
[:div.tool-window
[:div.tool-window-bar.big
(if (> (count shapes) 1)
[:*
[:span.tool-window-bar-icon i/layers]
[:span.tool-window-bar-title (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
[:*
[:span.tool-window-bar-icon
[:& si/element-icon {:shape first-shape :main-instance? main-instance?}]]
;; Execution time translation strings:
;; inspect.tabs.code.selected.circle
;; inspect.tabs.code.selected.component
;; inspect.tabs.code.selected.curve
;; inspect.tabs.code.selected.frame
;; inspect.tabs.code.selected.group
;; inspect.tabs.code.selected.image
;; inspect.tabs.code.selected.mask
;; inspect.tabs.code.selected.path
;; inspect.tabs.code.selected.rect
;; inspect.tabs.code.selected.svg-raw
;; inspect.tabs.code.selected.text
[:span.tool-window-bar-title (:name first-shape)]])]
[:div.tool-window-content.inspect
[:& tabs-container {:on-change-tab handle-change-tab
:selected @section}
[:& tabs-element {:id :info :title (tr "inspect.tabs.info")}
[:& attributes {:page-id page-id
:objects objects
:file-id file-id
:frame frame
:shapes shapes
:from from
:libraries libraries
:share-id share-id}]]
(if new-css-system
[:aside {:class (stl/css :settings-bar-right)}
[:& tabs-element {:id :code :title (tr "inspect.tabs.code")}
[:& code {:frame frame
:shapes shapes
:on-expand handle-expand
:from from}]]]]]
[:div.empty
[:span.tool-window-bar-icon i/code]
[:div (tr "inspect.empty.select")]
[:span.tool-window-bar-icon i/help]
[:div (tr "inspect.empty.help")]
[:button.btn-primary.action {:on-click #(dom/open-new-window "https://help.penpot.app/user-guide/inspect/")} (tr "inspect.empty.more-info")]])]]))
(if (seq shapes)
[:div {:class (stl/css :tool-windows)}
[:div {:class (stl/css :shape-row)}
(if (> (count shapes) 1)
[:*
[:span {:class (stl/css :layers-icon)} i/layers-refactor]
[:span {:class (stl/css :layer-title)} (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
[:*
[:span {:class (stl/css :shape-icon)}
[:& si/element-icon-refactor {:shape first-shape :main-instance? main-instance?}]]
;; Execution time translation strings:
;; inspect.tabs.code.selected.circle
;; inspect.tabs.code.selected.component
;; inspect.tabs.code.selected.curve
;; inspect.tabs.code.selected.frame
;; inspect.tabs.code.selected.group
;; inspect.tabs.code.selected.image
;; inspect.tabs.code.selected.mask
;; inspect.tabs.code.selected.path
;; inspect.tabs.code.selected.rect
;; inspect.tabs.code.selected.svg-raw
;; inspect.tabs.code.selected.text
[:span {:class (stl/css :layer-title)} (:name first-shape)]])]
[:div {:class (stl/css :inspect-content)}
[:& tab-container {:on-change-tab handle-change-tab
:selected @section}
[:& tab-element {:id :info :title (tr "inspect.tabs.info")}
[:& attributes {:page-id page-id
:objects objects
:file-id file-id
:frame frame
:shapes shapes
:from from
:libraries libraries
:share-id share-id}]]
[:& tab-element {:id :code :title (tr "inspect.tabs.code")}
[:& code {:frame frame
:shapes shapes
:on-expand handle-expand
:from from}]]]]]
[:div {:class (stl/css :empty)}
[:div {:class (stl/css :code-info)}
[:span {:class (stl/css :placeholder-icon)}
i/code-refactor]
[:span {:class (stl/css :placeholder-label)}
(tr "inspect.empty.select")]]
[:div {:class (stl/css :help-info)}
[:span {:class (stl/css :placeholder-icon)}
i/help-refactor]
[:span {:class (stl/css :placeholder-label)}
(tr "inspect.empty.help")]]
[:button {:class (stl/css :more-info-btn)
:on-click navigate-to-help}
(tr "inspect.empty.more-info")]])]
[:aside.settings-bar.settings-bar-right
[:div.settings-bar-inside
(if (seq shapes)
[:div.tool-window
[:div.tool-window-bar.big
(if (> (count shapes) 1)
[:*
[:span.tool-window-bar-icon i/layers]
[:span.tool-window-bar-title (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
[:*
[:span.tool-window-bar-icon
[:& si/element-icon {:shape first-shape :main-instance? main-instance?}]]
;; Execution time translation strings:
;; inspect.tabs.code.selected.circle
;; inspect.tabs.code.selected.component
;; inspect.tabs.code.selected.curve
;; inspect.tabs.code.selected.frame
;; inspect.tabs.code.selected.group
;; inspect.tabs.code.selected.image
;; inspect.tabs.code.selected.mask
;; inspect.tabs.code.selected.path
;; inspect.tabs.code.selected.rect
;; inspect.tabs.code.selected.svg-raw
;; inspect.tabs.code.selected.text
[:span.tool-window-bar-title (:name first-shape)]])]
[:div.tool-window-content.inspect
[:& tabs-container {:on-change-tab handle-change-tab
:selected @section}
[:& tabs-element {:id :info :title (tr "inspect.tabs.info")}
[:& attributes {:page-id page-id
:objects objects
:file-id file-id
:frame frame
:shapes shapes
:from from
:libraries libraries
:share-id share-id}]]
[:& tabs-element {:id :code :title (tr "inspect.tabs.code")}
[:& code {:frame frame
:shapes shapes
:on-expand handle-expand
:from from}]]]]]
[:div.empty
[:span.tool-window-bar-icon i/code]
[:div (tr "inspect.empty.select")]
[:span.tool-window-bar-icon i/help]
[:div (tr "inspect.empty.help")]
[:button.btn-primary.action {:on-click navigate-to-help} (tr "inspect.empty.more-info")]])]])
))

View file

@ -0,0 +1,64 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@import "refactor/common-refactor.scss";
.settings-bar-right {
min-width: $s-252;
width: 100%;
height: 100%;
position: relative;
left: unset;
right: unset;
grid-area: right-sidebar;
.tool-windows {
.shape-row {
display: flex;
gap: $s-8;
align-items: center;
margin-bottom: $s-16;
.layers-icon,
.shape-icon {
@include flexCenter;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
.layer-title {
@include titleTipography;
}
}
}
.empty {
display: flex;
flex-direction: column;
align-items: center;
gap: $s-40;
padding-top: $s-24;
.code-info,
.help-info {
@include flexColumn;
align-items: center;
justify-content: flex-start;
gap: $s-8;
.placeholder-icon {
@extend .empty-icon;
}
.placeholder-label {
@include titleTipography;
text-align: center;
width: $s-200;
}
}
.more-info-btn {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
padding: $s-8 $s-24;
}
}
}

View file

@ -7,25 +7,19 @@
@import "refactor/common-refactor.scss";
.color-values {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
&.disable-opacity {
grid-template-columns: 3.5rem repeat(3, 1fr);
}
.colors-row {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.input-wrapper {
@extend .input-element;
width: $s-84;
}
}
.hex-alpha-wrapper {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.input-wrapper {
@extend .input-element;
width: $s-84;

View file

@ -35,9 +35,7 @@
}
.handlers-wrapper {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
height: $s-200;
width: $s-52;
flex-grow: 1;

View file

@ -7,9 +7,7 @@
@import "refactor/common-refactor.scss";
.hsva-selector {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
padding: $s-4;
grid-row-gap: $s-8;
margin-bottom: $s-8;

View file

@ -112,11 +112,9 @@
gap: $s-24;
}
.thread-group-placeholder {
display: flex;
flex-direction: column;
@include flexColumn;
align-items: center;
justify-content: flex-start;
gap: $s-4;
margin-top: $s-36;
.placeholder-icon {
@include flexCenter;

View file

@ -80,12 +80,10 @@
}
.sections-container {
@include menuShadow;
@include flexColumn;
position: absolute;
top: $s-84;
left: $s-12;
display: flex;
flex-direction: column;
gap: $s-4;
width: $s-192;
padding: $s-4;
border-radius: $br-8;

View file

@ -50,17 +50,9 @@
text-align: center;
.history-entry-empty-icon {
@include flexCenter;
height: $s-48;
width: $s-48;
border-radius: $br-circle;
background-color: var(--empty-message-background-color);
@extend .empty-icon;
svg {
@extend .button-icon;
height: $s-28;
width: $s-28;
margin-left: calc(-1 * $s-2);
stroke: var(--empty-message-foreground-color);
}
}

View file

@ -130,10 +130,8 @@
}
}
.active-filters {
display: flex;
align-items: center;
@include flexRow;
flex-wrap: wrap;
gap: $s-4;
margin: 0 $s-12;
.layer-filter {
@extend .button-tag;

View file

@ -7,7 +7,5 @@
@import "refactor/common-refactor.scss";
.advanced-options-wrapper {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
}

View file

@ -8,13 +8,11 @@
.align-options {
display: flex;
gap: $s-4;
height: $s-32;
margin: 0 calc(-1 * $s-2);
gap: $s-4;
.align-group {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.align-button {
@extend .button-tertiary;
height: $s-28;

View file

@ -21,14 +21,10 @@
}
}
.element-set-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
margin-bottom: $s-4;
.first-row {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
width: 100%;
.blur-info {
display: flex;
@ -65,9 +61,7 @@
}
}
.actions {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;

View file

@ -8,8 +8,8 @@
.boolean-options {
display: flex;
height: $s-32;
gap: $s-4;
height: $s-32;
margin: 0 calc(-1 * $s-2);
.bool-group {
display: flex;

View file

@ -21,13 +21,9 @@
}
}
.element-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.selected-color-group {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.more-colors-btn {
@extend .button-secondary;
@include tabTitleTipography;

View file

@ -7,17 +7,13 @@
@import "refactor/common-refactor.scss";
.element-set {
.element-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.component-wrapper {
display: flex;
gap: $s-4;
.component-name-wrapper {
@extend .asset-element;
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
flex-grow: 1;
.component-icon {
@include flexCenter;

View file

@ -105,9 +105,7 @@
}
}
.contraints-selects {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.horizontal-select,
.vertical-select {

View file

@ -21,21 +21,15 @@
}
}
.element-set-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
margin-bottom: $s-4;
.multiple-exports {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.label {
@extend .mixed-bar;
}
.actions {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
@ -47,13 +41,9 @@
}
}
.element-group {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.input-wrapper {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.format-select {
width: $s-60;
padding: 0;

View file

@ -25,9 +25,7 @@
flex-direction: column;
gap: $s-12;
.element-set-options-group {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.group-label {
@extend .mixed-bar;
}

View file

@ -19,14 +19,10 @@
}
}
.element-set-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.grid-option {
.grid-title {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.option-row {
display: flex;
align-items: center;
@ -130,9 +126,7 @@
}
.actions {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
@ -145,15 +139,11 @@
}
}
.grid-advanced-options {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
margin-top: $s-4;
.column-row,
.square-row {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
position: relative;
.advanced-row {
position: relative;
@ -193,12 +183,10 @@
}
.more-options {
@include menuShadow;
@include flexColumn;
position: absolute;
top: $s-36;
right: 0;
display: flex;
flex-direction: column;
gap: $s-4;
width: $s-156;
max-height: $s-300;
padding: $s-2;

View file

@ -11,9 +11,7 @@
flex-direction: column;
gap: $s-8;
.interaction-options {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.element-title {
.add-interaction-btn {
@extend .button-tertiary;
@ -50,18 +48,12 @@
}
}
.groups {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.element-set-options-group {
&.open {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.extended-options {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.property-row {
@extend .attr-row;
.interaction-name {
@ -155,9 +147,7 @@
}
.inputs-wrapper {
grid-area: content;
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.radio-btn {
@extend .input-checkbox;
}
@ -202,9 +192,7 @@
}
}
.element-set {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.add-flow-btn {
@extend .button-tertiary;
height: $s-32;

View file

@ -62,9 +62,7 @@
margin-bottom: $s-12;
}
.forth-row {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.gap-group {
display: flex;
gap: $s-4;

View file

@ -19,9 +19,7 @@
}
}
.flex-element-menu {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.first-row {
display: flex;
gap: $s-4;
@ -111,9 +109,7 @@
}
.forth-row .advanced-options {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.horizontal-fill,
.vertical-fill {
display: flex;

View file

@ -7,9 +7,7 @@
@import "refactor/common-refactor.scss";
.element-set {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.presets {
display: flex;
align-items: flex-start;
@ -94,9 +92,7 @@
}
}
.size {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.height,
.width {
@extend .input-element;
@ -120,9 +116,7 @@
}
}
.position {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.x-position,
.y-position {
@extend .input-element;

View file

@ -21,20 +21,14 @@
}
}
.element-set-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.multiple-shadows {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.label {
@extend .mixed-bar;
}
.actions {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
@ -46,13 +40,9 @@
}
}
.shadow-element {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.basic-options {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.shadow-info {
display: flex;
align-items: center;
@ -85,9 +75,7 @@
}
}
.actions {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
@ -99,14 +87,10 @@
}
}
.shadow-advanced-options {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.first-row,
.second-row {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.offset-x-input,
.blur-input,
.spread-input,

View file

@ -26,9 +26,7 @@
flex-direction: column;
gap: $s-12;
.element-set-options-group {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.group-label {
@extend .mixed-bar;
}

View file

@ -11,9 +11,7 @@
padding-left: $s-12;
}
.element-set-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.attr-row {
display: flex;
gap: $s-4;

View file

@ -18,9 +18,7 @@
}
}
.element-content {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.multiple-typography {
@extend .mixed-bar;
.multiple-text {

View file

@ -143,9 +143,7 @@
width: 100%;
background-color: var(--assets-title-background-color);
.typography-info-wrapper {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
margin-bottom: $s-12;
.typography-name-wrapper {
@extend .asset-element;
@ -248,9 +246,7 @@
.text-options {
position: relative;
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.font-option {
@include titleTipography;
@extend .asset-element;
@ -319,13 +315,9 @@
}
}
.typography-variations {
display: flex;
gap: $s-4;
align-items: center;
@include flexRow;
.spacing-options {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.line-height,
.letter-spacing {
@extend .input-element;

View file

@ -7,9 +7,7 @@
@import "refactor/common-refactor.scss";
.color-data {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.color-info {
display: flex;
align-items: center;
@ -103,7 +101,9 @@
}
}
.gradient-name-wrapper {
border-radius: 0 $br-8 $br-8 0;
.color-name {
@include flexRow;
border-radius: 0 $br-8 $br-8 0;
}
}

View file

@ -7,13 +7,9 @@
@import "refactor/common-refactor.scss";
.stroke-data {
display: flex;
flex-direction: column;
gap: $s-4;
@include flexColumn;
.stroke-options {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.stroke-width-input-element {
@extend .input-element;
width: $s-60;
@ -30,9 +26,7 @@
}
}
.stroke-caps-options {
display: flex;
align-items: center;
gap: $s-4;
@include flexRow;
.cap-select {
width: $s-124;
}

View file

@ -115,8 +115,7 @@ body {
;; Grid cell properties
:grid-column
:grid-row
:grid-area
])
:grid-area])
(def text-node-css-properties
[:font-family

View file

@ -1190,6 +1190,9 @@ msgstr "Lower Case"
msgid "inspect.attributes.typography.text-transform.none"
msgstr "None"
msgid "inspect.attributes.typography.text-transform.unset"
msgstr "Unset"
msgid "inspect.attributes.typography.text-transform.titlecase"
msgstr "Title Case"

View file

@ -1228,6 +1228,9 @@ msgstr "Minúsculas"
msgid "inspect.attributes.typography.text-transform.none"
msgstr "Ninguna"
msgid "inspect.attributes.typography.text-transform.unset"
msgstr "Sin asignar"
msgid "inspect.attributes.typography.text-transform.titlecase"
msgstr "Primera en mayúscula"