0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-26 14:41:36 -05:00

♻️ Remove new-css-system from design tab

This commit is contained in:
Eva 2024-01-02 14:35:46 +01:00 committed by Alonso Torres
parent 0a123a3917
commit 67c692fdbd
42 changed files with 3852 additions and 6809 deletions

View file

@ -158,7 +158,6 @@
::mf/wrap [mf/memo]} ::mf/wrap [mf/memo]}
[{:keys [layout section file page-id ] :as props}] [{:keys [layout section file page-id ] :as props}]
(let [drawing-tool (:tool (mf/deref refs/workspace-drawing)) (let [drawing-tool (:tool (mf/deref refs/workspace-drawing))
new-css-system (mf/use-ctx ctx/new-css-system)
is-comments? (= drawing-tool :comments) is-comments? (= drawing-tool :comments)
is-history? (contains? layout :document-history) is-history? (contains? layout :document-history)
@ -195,10 +194,7 @@
(obj/set! "on-change-section" handle-change-section) (obj/set! "on-change-section" handle-change-section)
(obj/set! "on-expand" handle-expand))] (obj/set! "on-expand" handle-expand))]
[:aside {:class (stl/css-case new-css-system [:aside {:class (stl/css-case :right-settings-bar true
:global/settings-bar (not new-css-system)
:global/settings-bar-right (not new-css-system)
:right-settings-bar true
:not-expand (not can-be-expanded?) :not-expand (not can-be-expanded?)
:expanded (> size 276)) :expanded (> size 276))
@ -206,14 +202,13 @@
:data-size size :data-size size
:style #js {"--width" (when can-be-expanded? (dm/str size "px"))}} :style #js {"--width" (when can-be-expanded? (dm/str size "px"))}}
(when can-be-expanded? (when can-be-expanded?
[:div {:class (stl/css new-css-system :resize-area) [:div {:class (stl/css :resize-area)
:on-pointer-down on-pointer-down :on-pointer-down on-pointer-down
:on-lost-pointer-capture on-lost-pointer-capture :on-lost-pointer-capture on-lost-pointer-capture
:on-pointer-move on-pointer-move}]) :on-pointer-move on-pointer-move}])
(when new-css-system [:& right-header {:file file :layout layout :page-id page-id}]
[:& right-header {:file file :layout layout :page-id page-id}])
[:div {:class (stl/css new-css-system :settings-bar-inside)} [:div {:class (stl/css :settings-bar-inside)}
(cond (cond
(true? is-comments?) (true? is-comments?)
[:& comments-sidebar] [:& comments-sidebar]

View file

@ -16,7 +16,6 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.tab-container :refer [tab-container tab-element]] [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.context :as ctx]
[app.main.ui.viewer.inspect.right-sidebar :as hrs] [app.main.ui.viewer.inspect.right-sidebar :as hrs]
[app.main.ui.workspace.sidebar.options.menus.align :refer [align-options]] [app.main.ui.workspace.sidebar.options.menus.align :refer [align-options]]
@ -78,8 +77,7 @@
(mf/defc options-content (mf/defc options-content
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [selected section shapes shapes-with-children page-id file-id on-change-section on-expand]}] [{:keys [selected section shapes shapes-with-children page-id file-id on-change-section on-expand]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [drawing (mf/deref refs/workspace-drawing)
drawing (mf/deref refs/workspace-drawing)
objects (mf/deref refs/workspace-page-objects) objects (mf/deref refs/workspace-page-objects)
shared-libs (mf/deref refs/workspace-libraries) shared-libs (mf/deref refs/workspace-libraries)
edition (mf/deref refs/selected-edition) edition (mf/deref refs/selected-edition)
@ -100,144 +98,74 @@
(if (= options-mode :inspect) (if (= options-mode :inspect)
(st/emit! :interrupt (udw/set-workspace-read-only true)) (st/emit! :interrupt (udw/set-workspace-read-only true))
(st/emit! :interrupt (udw/set-workspace-read-only false))))] (st/emit! :interrupt (udw/set-workspace-read-only false))))]
(if ^boolean new-css-system
[:div {:class (stl/css :tool-window)}
[:& tab-container
{:on-change-tab on-change-tab
:selected section
:collapsable? false
:content-class (stl/css :content-class)
:class (stl/css :tab-spacing)}
[:& tab-element {:id :design
:title (tr "workspace.options.design")}
[:div {:class (stl/css :element-options)}
[:& align-options]
[:& bool-options]
(cond [:div {:class (stl/css :tool-window)}
(and edit-grid? (d/not-empty? selected-cells)) [:& tab-container
[:& grid-cell/options {:on-change-tab on-change-tab
{:shape (get objects edition) :selected section
:cells selected-cells}] :collapsable? false
:content-class (stl/css :content-class)
:class (stl/css :tab-spacing)}
[:& tab-element {:id :design
:title (tr "workspace.options.design")}
[:div {:class (stl/css :element-options)}
[:& align-options]
[:& bool-options]
edit-grid? (cond
[:& layout-container/grid-layout-edition (and edit-grid? (d/not-empty? selected-cells))
{:ids [edition] [:& grid-cell/options
:values (get objects edition)}] {:shape (get objects edition)
:cells selected-cells}]
(not (nil? sp-panel)) edit-grid?
[:& specialized-panel {:panel sp-panel}] [:& layout-container/grid-layout-edition
{:ids [edition]
:values (get objects edition)}]
(d/not-empty? drawing) (not (nil? sp-panel))
[:& shape-options [:& specialized-panel {:panel sp-panel}]
{:shape (:object drawing)
:page-id page-id
:file-id file-id
:shared-libs shared-libs}]
(= 0 (count selected)) (d/not-empty? drawing)
[:& page/options] [:& shape-options
{:shape (:object drawing)
:page-id page-id
:file-id file-id
:shared-libs shared-libs}]
(= 1 (count selected)) (= 0 (count selected))
[:& shape-options [:& page/options]
{:shape (first selected-shapes)
:page-id page-id
:file-id file-id
:shared-libs shared-libs
:shapes-with-children shapes-with-children}]
:else (= 1 (count selected))
[:& multiple/options [:& shape-options
{:shapes-with-children shapes-with-children {:shape (first selected-shapes)
:shapes selected-shapes :page-id page-id
:page-id page-id :file-id file-id
:file-id file-id :shared-libs shared-libs
:shared-libs shared-libs}])]] :shapes-with-children shapes-with-children}]
[:& tab-element {:id :prototype
:title (tr "workspace.options.prototype")}
[:div {:class (stl/css :element-options)}
[:& interactions-menu {:shape (first shapes)}]]]
[:& tab-element {:id :inspect
:title (tr "workspace.options.inspect")}
[:div {:class (stl/css :element-options)}
[:& hrs/right-sidebar {:page-id page-id
:objects objects
:file-id file-id
:frame shape-parent-frame
:shapes selected-shapes
:on-change-section on-change-section
:on-expand on-expand
:from :workspace}]]]]]
[:div.tool-window :else
[:div.tool-window-content [:& multiple/options
[:& tabs-container {:on-change-tab on-change-tab {:shapes-with-children shapes-with-children
:selected section} :shapes selected-shapes
[:& tabs-element {:id :design :page-id page-id
:title (tr "workspace.options.design")} :file-id file-id
[:div.element-options :shared-libs shared-libs}])]]
[:& align-options] [:& tab-element {:id :prototype
[:& bool-options] :title (tr "workspace.options.prototype")}
(cond [:div {:class (stl/css :element-options)}
(d/not-empty? selected-cells) [:& interactions-menu {:shape (first shapes)}]]]
[:& grid-cell/options [:& tab-element {:id :inspect
{:shape (get objects edition) :title (tr "workspace.options.inspect")}
:cells selected-cells}] [:div {:class (stl/css :element-options)}
[:& hrs/right-sidebar {:page-id page-id
edit-grid? :objects objects
[:& layout-container/grid-layout-edition :file-id file-id
{:ids [edition] :frame shape-parent-frame
:values (get objects edition)}] :shapes selected-shapes
:on-change-section on-change-section
sp-panel :on-expand on-expand
[:& specialized-panel {:panel sp-panel}] :from :workspace}]]]]]))
(d/not-empty? drawing)
[:& shape-options
{:shape (:object drawing)
:page-id page-id
:file-id file-id
:shared-libs shared-libs}]
(= 0 (count selected))
[:& page/options]
(= 1 (count selected))
[:& shape-options
{:shape (first selected-shapes)
:page-id page-id
:file-id file-id
:shared-libs shared-libs
:shapes-with-children shapes-with-children}]
:else
[:& multiple/options
{:shapes-with-children shapes-with-children
:shapes selected-shapes
:page-id page-id
:file-id file-id
:shared-libs shared-libs}])]]
[:& tabs-element
{:id :prototype
:title (tr "workspace.options.prototype")}
[:div.element-options
[:& interactions-menu {:shape (first shapes)}]]]
[:& tabs-element {:id :inspect
:title (tr "workspace.options.inspect")}
[:div.element-options.element-options-inspect
[:& hrs/right-sidebar {:page-id page-id
:objects objects
:file-id file-id
:frame shape-parent-frame
:shapes selected-shapes
:on-change-section on-change-section
:on-expand on-expand
:from :workspace}]]]]]])))
;; TODO: this need optimizations, selected-objects and ;; TODO: this need optimizations, selected-objects and
;; selected-objects-with-children are derefed always but they only ;; selected-objects-with-children are derefed always but they only

View file

@ -13,24 +13,24 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
padding-left: $s-12; padding-left: $s-12;
}
.tab-spacing {
margin-right: $s-12; .tab-spacing {
margin-bottom: $s-8; margin-right: $s-12;
} margin-bottom: $s-8;
}
.content-class {
overflow-y: auto; .content-class {
overflow-x: hidden; overflow-y: auto;
height: calc(100vh - $s-96); overflow-x: hidden;
scrollbar-gutter: stable; height: calc(100vh - $s-96);
} scrollbar-gutter: stable;
}
.element-options {
width: 100%; .element-options {
height: 100%; width: 100%;
display: flex; height: 100%;
flex-direction: column; display: flex;
gap: $s-8; flex-direction: column;
} gap: $s-8;
} }

View file

@ -8,27 +8,19 @@
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[app.util.dom :as dom] [app.util.dom :as dom]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc advanced-options [{:keys [visible? class children]}] (mf/defc advanced-options [{:keys [visible? class children]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [ref (mf/use-ref nil)]
ref (mf/use-ref nil)]
(mf/use-effect (mf/use-effect
(mf/deps visible?) (mf/deps visible?)
(fn [] (fn []
(when-let [node (mf/ref-val ref)] (when-let [node (mf/ref-val ref)]
(when visible? (when visible?
(dom/scroll-into-view-if-needed! node))))) (dom/scroll-into-view-if-needed! node)))))
(if new-css-system (when visible?
(when visible? [:div {:class (dm/str class " " (stl/css :advanced-options-wrapper))
[:div {:class (dm/str class " " (stl/css :advanced-options-wrapper)) :ref ref}
:ref ref} children])))
children])
(when visible?
[:div.advanced-options-wrapper {:ref ref}
[:div.advanced-options {}
children]]))))

View file

@ -11,7 +11,6 @@
[app.main.data.workspace.shortcuts :as sc] [app.main.data.workspace.shortcuts :as sc]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -19,9 +18,8 @@
(mf/defc align-options (mf/defc align-options
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [selected (mf/deref refs/selected-shapes)
selected (mf/deref refs/selected-shapes) ;; don't need to watch objects, only read the value
;; don't need to watch objects, only read the value
objects (deref refs/workspace-page-objects) objects (deref refs/workspace-page-objects)
disabled-align (not (dw/can-align? selected objects)) disabled-align (not (dw/can-align? selected objects))
@ -44,130 +42,70 @@
(st/emit! (dw/distribute-objects value)))))] (st/emit! (dw/distribute-objects value)))))]
(when (not (and disabled-align disabled-distribute)) (when (not (and disabled-align disabled-distribute))
(if new-css-system [:div {:class (stl/css :align-options)}
[:div {:class (stl/css :align-options)} [:div {:class (stl/css :align-group)}
[:div {:class (stl/css :align-group)} [:button {:class (stl/css-case :align-button true
[:button {:class (stl/css-case :align-button true :disabled disabled-align)
:disabled disabled-align) :disabled disabled-align
:disabled disabled-align :title (tr "workspace.align.hleft" (sc/get-tooltip :align-left))
:title (tr "workspace.align.hleft" (sc/get-tooltip :align-left)) :data-value :hleft
:data-value :hleft :on-click align-objects}
:on-click align-objects} i/align-left-refactor]
i/align-left-refactor]
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-align) :disabled disabled-align)
:disabled disabled-align :disabled disabled-align
:title (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter)) :title (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter))
:data-value :hcenter :data-value :hcenter
:on-click align-objects} :on-click align-objects}
i/align-horizontal-center-refactor] i/align-horizontal-center-refactor]
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-align) :disabled disabled-align)
:disabled disabled-align :disabled disabled-align
:title (tr "workspace.align.hright" (sc/get-tooltip :align-right)) :title (tr "workspace.align.hright" (sc/get-tooltip :align-right))
:data-value :hright :data-value :hright
:on-click align-objects} :on-click align-objects}
i/align-right-refactor] i/align-right-refactor]
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-distribute) :disabled disabled-distribute)
:disabled disabled-distribute :disabled disabled-distribute
:title (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute)) :title (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute))
:data-value :horizontal :data-value :horizontal
:on-click distribute-objects} :on-click distribute-objects}
i/distribute-horizontally-refactor]] i/distribute-horizontally-refactor]]
[:div {:class (stl/css :align-group)} [:div {:class (stl/css :align-group)}
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-align) :disabled disabled-align)
:disabled disabled-align :disabled disabled-align
:title (tr "workspace.align.vtop" (sc/get-tooltip :align-top)) :title (tr "workspace.align.vtop" (sc/get-tooltip :align-top))
:data-value :vtop :data-value :vtop
:on-click align-objects} :on-click align-objects}
i/align-top-refactor] i/align-top-refactor]
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-align) :disabled disabled-align)
:disabled disabled-align :disabled disabled-align
:title (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter)) :title (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter))
:data-value :vcenter :data-value :vcenter
:on-click align-objects} :on-click align-objects}
i/align-vertical-center-refactor] i/align-vertical-center-refactor]
[:button {:class (stl/css-case :align-button true [:button {:class (stl/css-case :align-button true
:disabled disabled-align) :disabled disabled-align)
:disabled disabled-align :disabled disabled-align
:title (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom)) :title (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom))
:data-value :vbottom :data-value :vbottom
:on-click align-objects} :on-click align-objects}
i/align-bottom-refactor] i/align-bottom-refactor]
[:button {:title (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute)) [:button {:title (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:class (stl/css-case :align-button true :class (stl/css-case :align-button true
:disabled disabled-distribute) :disabled disabled-distribute)
:disabled disabled-distribute :disabled disabled-distribute
:data-value :vertical :data-value :vertical
:on-click distribute-objects} :on-click distribute-objects}
i/distribute-vertical-spacing-refactor]]] i/distribute-vertical-spacing-refactor]]])))
[:div.align-options
[:div.align-group
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.align.hleft" (sc/get-tooltip :align-left))
:class (when disabled-align "disabled")
:data-value :hleft
:on-click align-objects}
i/shape-halign-left]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter))
:class (when disabled-align "disabled")
:data-value :hcenter
:on-click align-objects}
i/shape-halign-center]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.align.hright" (sc/get-tooltip :align-right))
:class (when disabled-align "disabled")
:data-value :hright
:on-click align-objects}
i/shape-halign-right]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute))
:class (when disabled-distribute "disabled")
:data-value :horizontal
:on-click distribute-objects}
i/shape-hdistribute]]
[:div.align-group
[:div.align-button.tooltip.tooltip-bottom-left
{:alt (tr "workspace.align.vtop" (sc/get-tooltip :align-top))
:class (when disabled-align "disabled")
:data-value :vtop
:on-click align-objects}
i/shape-valign-top]
[:div.align-button.tooltip.tooltip-bottom-left
{:alt (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter))
:class (when disabled-align "disabled")
:data-value :vcenter
:on-click align-objects}
i/shape-valign-center]
[:div.align-button.tooltip.tooltip-bottom-left
{:alt (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom))
:class (when disabled-align "disabled")
:data-value :vbottom
:on-click align-objects}
i/shape-valign-bottom]
[:div.align-button.tooltip.tooltip-bottom-left
{:alt (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:class (when disabled-distribute "disabled")
:data-value :vertical
:on-click distribute-objects}
i/shape-vdistribute]]]))))

View file

@ -11,29 +11,30 @@
gap: $s-4; gap: $s-4;
height: $s-32; height: $s-32;
margin: 0 calc(-1 * $s-2); margin: 0 calc(-1 * $s-2);
.align-group { }
@include flexRow; .align-group {
.align-button { @include flexRow;
@extend .button-tertiary; }
height: $s-28;
width: $s-28; .align-button {
padding: 0; @extend .button-tertiary;
border-radius: $br-8; height: $s-28;
width: $s-28;
padding: 0;
border-radius: $br-8;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
&.disabled {
cursor: default;
svg {
stroke: var(--button-background-color-disabled);
}
&:hover {
background-color: var(--panel-background-color);
svg { svg {
@extend .button-icon; stroke: var(--button-background-color-disabled);
stroke: var(--icon-foreground);
}
&.disabled {
cursor: default;
svg {
stroke: var(--button-background-color-disabled);
}
&:hover {
background-color: var(--panel-background-color);
svg {
stroke: var(--button-background-color-disabled);
}
}
} }
} }
} }

View file

@ -12,9 +12,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -28,10 +26,8 @@
:hidden false})) :hidden false}))
(mf/defc blur-menu [{:keys [ids type values]}] (mf/defc blur-menu [{:keys [ids type values]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [blur (:blur values)
blur (:blur values)
has-value? (not (nil? blur)) has-value? (not (nil? blur))
multiple? (= blur :multiple)
state* (mf/use-state {:show-content true state* (mf/use-state {:show-content true
:show-more-options false}) :show-more-options false})
@ -79,76 +75,47 @@
(fn [] (fn []
(change! #(update-in % [:blur :hidden] not))))] (change! #(update-in % [:blur :hidden] not))))]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-value?
[:& title-bar {:collapsable? has-value? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (case type
:title (case type :multiple (tr "workspace.options.blur-options.title.multiple")
:multiple (tr "workspace.options.blur-options.title.multiple") :group (tr "workspace.options.blur-options.title.group")
:group (tr "workspace.options.blur-options.title.group") (tr "workspace.options.blur-options.title"))
(tr "workspace.options.blur-options.title")) :class (stl/css-case :title-spacing-blur (not has-value?))}
:class (stl/css-case :title-spacing-blur (not has-value?))} (when-not has-value?
(when-not has-value? [:button {:class (stl/css :add-blur)
[:button {:class (stl/css :add-blur) :on-click handle-add} i/add-refactor])]]
:on-click handle-add} i/add-refactor])]] (when (and open? has-value?)
(when (and open? has-value?) [:div {:class (stl/css :element-set-content)}
[:div {:class (stl/css :element-set-content)} [:div {:class (stl/css-case :first-row true
[:div {:class (stl/css-case :first-row true :hidden hidden?)}
:hidden hidden?)} [:div {:class (stl/css :blur-info)}
[:div {:class (stl/css :blur-info)} [:button {:class (stl/css-case :show-more true
[:button {:class (stl/css-case :show-more true :selected more-options?)
:selected more-options?) :on-click toggle-more-options}
:on-click toggle-more-options} i/menu-refactor]
i/menu-refactor] [:span {:class (stl/css :label)}
[:span {:class (stl/css :label)} (tr "workspace.options.blur-options.title")]]
(tr "workspace.options.blur-options.title")]] [:div {:class (stl/css :actions)}
[:div {:class (stl/css :actions)} [:button {:class (stl/css :action-btn)
[:button {:class (stl/css :action-btn) :on-click handle-toggle-visibility}
:on-click handle-toggle-visibility} (if hidden?
(if hidden? i/hide-refactor
i/hide-refactor i/shown-refactor)]
i/shown-refactor)] [:button {:class (stl/css :action-btn)
[:button {:class (stl/css :action-btn) :on-click handle-delete} i/remove-refactor]]]
:on-click handle-delete} i/remove-refactor]]] (when more-options?
(when more-options? [:div {:class (stl/css :second-row)}
[:div {:class (stl/css :second-row)} [:label {:class (stl/css :label)
[:label {:class (stl/css :label) :for "blur-input-sidebar"}
:for "blur-input-sidebar"} (tr "inspect.attributes.blur.value")]
(tr "inspect.attributes.blur.value")] [:> numeric-input*
[:> numeric-input* {:className (stl/css :numeric-input)
{:className (stl/css :numeric-input) :placeholder "--"
:placeholder "--" :id "blur-input-sidebar"
:id "blur-input-sidebar" :min "0"
:min "0" :on-change handle-change
:on-change handle-change :value (:value blur)}]])])]))
:value (:value blur)}]])])]
[:div.element-set
[:div.element-set-title
[:span
(case type
:multiple (tr "workspace.options.blur-options.title.multiple")
:group (tr "workspace.options.blur-options.title.group")
(tr "workspace.options.blur-options.title"))]
[:div.element-set-title-actions
(when (and has-value? (not multiple?))
[:div.add-page {:on-click handle-toggle-visibility}
(if hidden? i/eye-closed i/eye)])
(if has-value?
[:div.add-page {:on-click handle-delete} i/minus]
[:div.add-page {:on-click handle-add} i/close])]]
(cond
has-value?
[:div.element-set-content
[:& input-row {:label "Value"
:class "pixels"
:min "0"
:value (:value blur)
:placeholder (tr "settings.multiple")
:on-change handle-change}]])])))

View file

@ -8,13 +8,74 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
.title-spacing-blur {
padding-left: $s-2; .title-spacing-blur {
margin: 0; padding-left: $s-2;
margin: 0;
}
.add-blur {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.element-set-content {
@include flexColumn;
margin-bottom: $s-8;
}
.first-row {
@include flexRow;
width: 100%;
.blur-info {
display: flex;
align-items: center;
gap: $s-1;
flex-grow: 1;
border-radius: $br-8;
background-color: var(--input-details-color);
.show-more {
@extend .button-secondary;
height: $s-32;
width: $s-28;
border-radius: $br-8 0 0 $br-8;
box-sizing: border-box;
border: $s-1 solid var(--button-secondary-background-color-rest);
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-radio-background-color-active);
svg {
stroke: var(--button-radio-foreground-color-active);
}
}
} }
.add-blur { .label {
@include titleTipography;
flex-grow: 1;
display: flex;
align-items: center;
height: $s-32;
padding: 0 $s-8;
border-radius: 0 $br-8 $br-8 0;
background-color: var(--input-background-color);
color: var(--menu-foreground-color);
box-sizing: border-box;
border: $s-1 solid var(--input-background-color);
}
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary; @extend .button-tertiary;
box-sizing: border-box;
border: $s-1 solid var(--button-tertiary-background-color-rest);
height: $s-32; height: $s-32;
width: $s-28; width: $s-28;
svg { svg {
@ -22,85 +83,27 @@
} }
} }
} }
.element-set-content {
@include flexColumn;
margin-bottom: $s-8;
.first-row {
@include flexRow;
width: 100%;
.blur-info {
display: flex;
align-items: center;
gap: $s-1;
flex-grow: 1;
border-radius: $br-8;
background-color: var(--input-details-color);
.show-more {
@extend .button-secondary;
height: $s-32;
width: $s-28;
border-radius: $br-8 0 0 $br-8;
box-sizing: border-box;
border: $s-1 solid var(--button-secondary-background-color-rest);
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-radio-background-color-active);
svg {
stroke: var(--button-radio-foreground-color-active);
}
}
}
.label {
@include titleTipography;
flex-grow: 1;
display: flex;
align-items: center;
height: $s-32;
padding: 0 $s-8;
border-radius: 0 $br-8 $br-8 0;
background-color: var(--input-background-color);
color: var(--menu-foreground-color);
box-sizing: border-box;
border: $s-1 solid var(--input-background-color);
}
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary;
box-sizing: border-box;
border: $s-1 solid var(--button-tertiary-background-color-rest);
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
&.hidden { &.hidden {
.blur-info { .blur-info {
@include hiddenElement; @include hiddenElement;
.show-more { .show-more {
@include hiddenElement; @include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled); border: $s-1 solid var(--input-border-color-disabled);
}
.label {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
}
}
} }
}
.second-row {
@extend .input-element;
width: $s-92;
.label { .label {
padding-left: $s-8; @include hiddenElement;
width: $s-60; border: $s-1 solid var(--input-border-color-disabled);
} }
} }
} }
} }
.second-row {
@extend .input-element;
width: $s-92;
.label {
padding-left: $s-8;
width: $s-60;
}
}

View file

@ -13,19 +13,13 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc bool-options (mf/defc bool-options
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [selected (mf/deref refs/selected-objects)
selected (mf/deref refs/selected-objects)
head (first selected) head (first selected)
selected-with-children (mf/deref refs/selected-shapes-with-children) selected-with-children (mf/deref refs/selected-shapes-with-children)
has-invalid-shapes? (->> selected-with-children has-invalid-shapes? (->> selected-with-children
@ -42,39 +36,10 @@
disabled-flatten (or (empty? selected) has-invalid-shapes?) disabled-flatten (or (empty? selected) has-invalid-shapes?)
set-bool set-bool
(mf/use-fn
(mf/deps head head-bool-type selected)
(fn [event]
(let [bool-type (-> (dom/get-current-target event)
(dom/get-data "value")
(keyword))]
(cond
(> (count selected) 1)
(st/emit! (dw/create-bool (if new-css-system
(keyword bool-type)
bool-type)))
(and (= (count selected) 1) is-group?)
(st/emit! (dw/group-to-bool (:id head) (if new-css-system
(keyword bool-type)
bool-type)))
(and (= (count selected) 1) is-bool?)
(if (= head-bool-type (if new-css-system
(keyword bool-type)
bool-type))
(st/emit! (dw/bool-to-group (:id head)))
(st/emit! (dw/change-bool-type (:id head) (if new-css-system
(keyword bool-type)
bool-type))))))))
set-bool-refactor
(mf/use-fn (mf/use-fn
(mf/deps selected is-group? is-bool?) (mf/deps selected is-group? is-bool?)
(fn [bool-type] (fn [bool-type]
(let [bool-type (if new-css-system (let [bool-type (keyword bool-type)]
(keyword bool-type)
bool-type)]
(cond (cond
(> (count selected) 1) (> (count selected) 1)
(st/emit! (dw/create-bool bool-type)) (st/emit! (dw/create-bool bool-type))
@ -90,82 +55,40 @@
flatten-objects (mf/use-fn #(st/emit! (dw/convert-selected-to-path)))] flatten-objects (mf/use-fn #(st/emit! (dw/convert-selected-to-path)))]
(when (not (and disabled-bool-btns disabled-flatten)) (when (not (and disabled-bool-btns disabled-flatten))
(if new-css-system [:div {:class (stl/css :boolean-options)}
[:div {:class (stl/css :boolean-options)} [:div {:class (stl/css :bool-group)}
[:div {:class (stl/css :bool-group)} [:& radio-buttons {:selected (d/name head-bool-type)
[:& radio-buttons {:selected (d/name head-bool-type) :class (stl/css :boolean-radio-btn)
:class (stl/css :boolean-radio-btn) :on-change set-bool
:on-change set-bool-refactor :name "bool-options"}
:name "bool-options"} [:& radio-button {:icon i/boolean-union-refactor
[:& radio-button {:icon i/boolean-union-refactor :value "union"
:value "union" :disabled disabled-bool-btns
:disabled disabled-bool-btns :title (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
:title (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")") :id "bool-opt-union"}]
:id "bool-opt-union"}] [:& radio-button {:icon i/boolean-difference-refactor
[:& radio-button {:icon i/boolean-difference-refactor :value "difference"
:value "difference" :disabled disabled-bool-btns
:disabled disabled-bool-btns :title (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
:title (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")") :id "bool-opt-differente"}]
:id "bool-opt-differente"}] [:& radio-button {:icon i/boolean-intersection-refactor
[:& radio-button {:icon i/boolean-intersection-refactor :value "intersection"
:value "intersection" :disabled disabled-bool-btns
:disabled disabled-bool-btns :title (str (tr "intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:title (str (tr "intersection") " (" (sc/get-tooltip :bool-intersection) ")") :id "bool-opt-intersection"}]
:id "bool-opt-intersection"}] [:& radio-button {:icon i/boolean-exclude-refactor
[:& radio-button {:icon i/boolean-exclude-refactor :value "exclude"
:value "exclude" :disabled disabled-bool-btns
:disabled disabled-bool-btns :title (str (tr "exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:title (str (tr "exclude") " (" (sc/get-tooltip :bool-exclude) ")") :id "bool-opt-exclude"}]]]
:id "bool-opt-exclude"}]]]
[:div {:class (stl/css :bool-group)} [:div {:class (stl/css :bool-group)}
[:button [:button
{:title (tr "workspace.shape.menu.flatten") {:title (tr "workspace.shape.menu.flatten")
:class (stl/css-case :class (stl/css-case
:flatten true :flatten true
:disabled disabled-flatten) :disabled disabled-flatten)
:disabled disabled-flatten :disabled disabled-flatten
:on-click flatten-objects} :on-click flatten-objects}
i/boolean-flatten-refactor]]] i/boolean-flatten-refactor]]])))
[:div.align-options
[:div.align-group
[:div.align-button.tooltip.tooltip-bottom
{:alt (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
:class (dom/classnames :disabled disabled-bool-btns
:selected (= head-bool-type :union))
:data-value :union
:on-click set-bool}
i/bool-union]
[:div.align-button.tooltip.tooltip-bottom
{:alt (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
:class (dom/classnames :disabled disabled-bool-btns
:selected (= head-bool-type :difference))
:data-value :difference
:on-click set-bool}
i/bool-difference]
[:div.align-button.tooltip.tooltip-bottom
{:alt (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:class (dom/classnames :disabled disabled-bool-btns
:selected (= head-bool-type :intersection))
:data-value :intersection
:on-click set-bool}
i/bool-intersection]
[:div.align-button.tooltip.tooltip-bottom
{:alt (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:class (dom/classnames :disabled disabled-bool-btns
:selected (= head-bool-type :exclude))
:data-value :exclude
:on-click set-bool}
i/bool-exclude]]
[:div.align-group
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.shape.menu.flatten")
:class (dom/classnames :disabled disabled-flatten)
:on-click flatten-objects}
i/bool-flatten]]]))))

View file

@ -11,33 +11,36 @@
gap: $s-4; gap: $s-4;
height: $s-32; height: $s-32;
margin: 0 calc(-1 * $s-2); margin: 0 calc(-1 * $s-2);
.bool-group { }
display: flex;
align-items: center; .bool-group {
.flatten { display: flex;
@extend .button-tertiary; align-items: center;
height: $s-28; }
width: $s-28;
border-radius: $br-8; .flatten {
svg { @extend .button-tertiary;
@extend .button-icon; height: $s-28;
stroke: var(--icon-foreground); width: $s-28;
} border-radius: $br-8;
&.disabled { svg {
cursor: default; @extend .button-icon;
svg { stroke: var(--icon-foreground);
stroke: var(--button-background-color-disabled); }
} &.disabled {
&:hover { cursor: default;
background-color: var(--panel-background-color); svg {
svg { stroke: var(--button-background-color-disabled);
stroke: var(--button-background-color-disabled);
}
}
}
} }
.boolean-radio-btn { &:hover {
background-color: transparent; background-color: var(--panel-background-color);
svg {
stroke: var(--button-background-color-disabled);
}
} }
} }
} }
.boolean-radio-btn {
background-color: transparent;
}

View file

@ -14,8 +14,6 @@
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str] [cuerdas.core :as str]
@ -158,7 +156,6 @@
[{:keys [shapes file-id shared-libs] :as props}] [{:keys [shapes file-id shared-libs] :as props}]
(let [{:keys [grouped-colors library-colors colors]} (mf/with-memo [shapes file-id shared-libs] (let [{:keys [grouped-colors library-colors colors]} (mf/with-memo [shapes file-id shared-libs]
(prepare-colors shapes file-id shared-libs)) (prepare-colors shapes file-id shared-libs))
new-css-system (mf/use-ctx ctx/new-css-system)
state* (mf/use-state true) state* (mf/use-state true)
open? (deref state*) open? (deref state*)
@ -216,71 +213,17 @@
(mf/with-effect [grouped-colors] (mf/with-effect [grouped-colors]
(reset! grouped-colors* grouped-colors)) (reset! grouped-colors* grouped-colors))
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-colors?
[:& title-bar {:collapsable? has-colors? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (tr "workspace.options.selection-color")
:title (tr "workspace.options.selection-color") :class (stl/css-case :title-spacing-selected-colors (not has-colors?))}]]
:class (stl/css-case :title-spacing-selected-colors (not has-colors?))}]]
(when open? (when open?
[:div {:class (stl/css :element-content)} [:div {:class (stl/css :element-content)}
[:div {:class (stl/css :selected-color-group)} [:div {:class (stl/css :selected-color-group)}
(for [[index color] (d/enumerate (take 3 library-colors))]
[:& color-row {:key (dm/str "library-color-" (:color color))
:color color
:index index
:on-detach on-detach
:select-only select-only
:on-change #(on-change %1 color %2)
:on-open on-open
:on-close on-close}])
(when (and (false? @expand-lib-color) (< 3 (count library-colors)))
[:button {:class (stl/css :more-colors-btn)
:on-click #(reset! expand-lib-color true)}
(tr "workspace.options.more-lib-colors")])
(when @expand-lib-color
(for [[index color] (d/enumerate (drop 3 library-colors))]
[:& color-row {:key (dm/str "library-color-" (:color color))
:color color
:index index
:on-detach on-detach
:select-only select-only
:on-change #(on-change %1 color %2)
:on-open on-open
:on-close on-close}]))]
[:div {:class (stl/css :selected-color-group)}
(for [[index color] (d/enumerate (take 3 colors))]
[:& color-row {:key (dm/str "color-" index)
:color color
:index index
:select-only select-only
:on-change #(on-change %1 color %2)
:on-open on-open
:on-close on-close}])
(when (and (false? @expand-color) (< 3 (count colors)))
[:button {:class (stl/css :more-colors-btn)
:on-click #(reset! expand-color true)}
(tr "workspace.options.more-colors")])
(when @expand-color
(for [[index color] (d/enumerate (drop 3 colors))]
[:& color-row {:key (dm/str "color-" (:color color))
:color color
:index index
:select-only select-only
:on-change #(on-change %1 color %2)
:on-open on-open
:on-close on-close}]))]])]
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.options.selection-color")]]
[:div.element-set-content
[:div.selected-colors
(for [[index color] (d/enumerate (take 3 library-colors))] (for [[index color] (d/enumerate (take 3 library-colors))]
[:& color-row {:key (dm/str "library-color-" (:color color)) [:& color-row {:key (dm/str "library-color-" (:color color))
:color color :color color
@ -291,9 +234,9 @@
:on-open on-open :on-open on-open
:on-close on-close}]) :on-close on-close}])
(when (and (false? @expand-lib-color) (< 3 (count library-colors))) (when (and (false? @expand-lib-color) (< 3 (count library-colors)))
[:div.expand-colors {:on-click #(reset! expand-lib-color true)} [:button {:class (stl/css :more-colors-btn)
[:span i/actions] :on-click #(reset! expand-lib-color true)}
[:span.text (tr "workspace.options.more-lib-colors")]]) (tr "workspace.options.more-lib-colors")])
(when @expand-lib-color (when @expand-lib-color
(for [[index color] (d/enumerate (drop 3 library-colors))] (for [[index color] (d/enumerate (drop 3 library-colors))]
[:& color-row {:key (dm/str "library-color-" (:color color)) [:& color-row {:key (dm/str "library-color-" (:color color))
@ -304,8 +247,7 @@
:on-change #(on-change %1 color %2) :on-change #(on-change %1 color %2)
:on-open on-open :on-open on-open
:on-close on-close}]))] :on-close on-close}]))]
[:div {:class (stl/css :selected-color-group)}
[:div.selected-colors
(for [[index color] (d/enumerate (take 3 colors))] (for [[index color] (d/enumerate (take 3 colors))]
[:& color-row {:key (dm/str "color-" index) [:& color-row {:key (dm/str "color-" index)
:color color :color color
@ -315,9 +257,10 @@
:on-open on-open :on-open on-open
:on-close on-close}]) :on-close on-close}])
(when (and (false? @expand-color) (< 3 (count colors))) (when (and (false? @expand-color) (< 3 (count colors)))
[:div.expand-colors {:on-click #(reset! expand-color true)} [:button {:class (stl/css :more-colors-btn)
[:span i/actions] :on-click #(reset! expand-color true)}
[:span.text (tr "workspace.options.more-colors")]]) (tr "workspace.options.more-colors")])
(when @expand-color (when @expand-color
(for [[index color] (d/enumerate (drop 3 colors))] (for [[index color] (d/enumerate (drop 3 colors))]
[:& color-row {:key (dm/str "color-" (:color color)) [:& color-row {:key (dm/str "color-" (:color color))
@ -326,4 +269,4 @@
:select-only select-only :select-only select-only
:on-change #(on-change %1 color %2) :on-change #(on-change %1 color %2)
:on-open on-open :on-open on-open
:on-close on-close}]))]]]))) :on-close on-close}]))]])]))

View file

@ -8,30 +8,33 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
.title-spacing-selected-colors {
padding-left: $s-2; .title-spacing-selected-colors {
margin: 0; padding-left: $s-2;
} margin: 0;
.add-fill { }
@extend .button-tertiary;
height: $s-32; .add-fill {
width: $s-28; @extend .button-tertiary;
svg { height: $s-32;
@extend .button-icon; width: $s-28;
} svg {
} @extend .button-icon;
}
.element-content {
@include flexColumn;
margin-bottom: $s-8;
.selected-color-group {
@include flexColumn;
.more-colors-btn {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
}
}
} }
} }
.element-content {
@include flexColumn;
margin-bottom: $s-8;
}
.selected-color-group {
@include flexColumn;
}
.more-colors-btn {
@extend .button-secondary;
@include tabTitleTipography;
height: $s-32;
}

View file

@ -147,7 +147,6 @@
(when (or @editing? creating?) (when (or @editing? creating?)
[:div.counter (str @size "/300")])]]))) [:div.counter (str @size "/300")])]])))
(mf/defc component-swap-item (mf/defc component-swap-item
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [item loop shapes file-id root-shape container component-id is-search listing-thumbs] :as props}] [{:keys [item loop shapes file-id root-shape container component-id is-search listing-thumbs] :as props}]
@ -190,7 +189,6 @@
[:span {:class (stl/css :component-group-name)} (cfh/last-path group-name)]] [:span {:class (stl/css :component-group-name)} (cfh/last-path group-name)]]
[:span i/arrow-slide]])) [:span i/arrow-slide]]))
(mf/defc component-swap (mf/defc component-swap
[{:keys [shapes] :as props}] [{:keys [shapes] :as props}]
(let [single? (= 1 (count shapes)) (let [single? (= 1 (count shapes))
@ -405,7 +403,6 @@
[:span {:class (stl/css :dropdown-label)} [:span {:class (stl/css :dropdown-label)}
(tr (:msg entry))]])]])) (tr (:msg entry))]])]]))
(mf/defc component-menu (mf/defc component-menu
[{:keys [shapes swap-opened?] :as props}] [{:keys [shapes swap-opened?] :as props}]
(let [current-file-id (mf/use-ctx ctx/current-file-id) (let [current-file-id (mf/use-ctx ctx/current-file-id)

View file

@ -16,7 +16,6 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -31,9 +30,7 @@
(mf/defc constraints-menu (mf/defc constraints-menu
[{:keys [ids values] :as props}] [{:keys [ids values] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [state* (mf/use-state true)
state* (mf/use-state true)
open? (deref state*) open? (deref state*)
toggle-content (mf/use-fn #(swap! state* not)) toggle-content (mf/use-fn #(swap! state* not))
@ -109,19 +106,6 @@
ids ids
#(assoc % constraint new-value)))))) #(assoc % constraint new-value))))))
on-constraint-select-changed
(mf/use-fn
(mf/deps ids)
(fn [event]
(let [constraint (-> (dom/get-current-target event)
(dom/get-data "value")
(keyword))
value (-> (dom/get-target-val event) (keyword))]
(when-not (str/empty? value)
(st/emit! (dch/update-shapes
ids
#(assoc % constraint value)))))))
on-constraint-h-select-changed on-constraint-h-select-changed
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
@ -171,154 +155,79 @@
;; CONSTRAINTS ;; CONSTRAINTS
(when in-frame? (when in-frame?
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? true
[:& title-bar {:collapsable? true :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (tr "workspace.options.constraints")}]]
:title (tr "workspace.options.constraints")}]] (when open?
(when open? [:div {:class (stl/css :element-set-content)}
[:div {:class (stl/css :element-set-content)} [:div {:class (stl/css :constraints-widget)}
[:div {:class (stl/css :constraints-widget)} [:div {:class (stl/css :constraints-top)}
[:div {:class (stl/css :constraints-top)} [:button {:class (stl/css-case :constraint-btn true
[:button {:class (stl/css-case :constraint-btn true :active (or (= constraints-v :top)
:active (or (= constraints-v :top) (= constraints-v :topbottom)))
(= constraints-v :topbottom))) :data-value :top
:data-value :top :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]]
[:span {:class (stl/css :resalted-area)}]]] [:div {:class (stl/css :constraints-left)}
[:div {:class (stl/css :constraints-left)} [:button {:class (stl/css-case :constraint-btn true
[:button {:class (stl/css-case :constraint-btn true :constraint-btn-rotated true
:constraint-btn-rotated true :active (or (= constraints-h :left)
:active (or (= constraints-h :left) (= constraints-h :leftright)))
(= constraints-h :leftright))) :data-value :left
:data-value :left :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]]
[:span {:class (stl/css :resalted-area)}]]] [:div {:class (stl/css :constraints-center)}
[:div {:class (stl/css :constraints-center)} [:button {:class (stl/css-case :constraint-btn true
[:button {:class (stl/css-case :constraint-btn true :active (= constraints-h :center))
:active (= constraints-h :center)) :data-value :centerh
:data-value :centerh :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]
[:span {:class (stl/css :resalted-area)}]] [:button {:class (stl/css-case :constraint-btn-special true
[:button {:class (stl/css-case :constraint-btn-special true :constraint-btn-rotated true
:constraint-btn-rotated true :active (= constraints-v :center))
:active (= constraints-v :center)) :data-value :centerv
:data-value :centerv :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]]
[:span {:class (stl/css :resalted-area)}]]] [:div {:class (stl/css :constraints-right)}
[:div {:class (stl/css :constraints-right)} [:button {:class (stl/css-case :constraint-btn true
[:button {:class (stl/css-case :constraint-btn true :constraint-btn-rotated true
:constraint-btn-rotated true :active (or (= constraints-h :right)
:active (or (= constraints-h :right) (= constraints-h :leftright)))
(= constraints-h :leftright))) :data-value :right
:data-value :right :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]]
[:span {:class (stl/css :resalted-area)}]]] [:div {:class (stl/css :constraints-bottom)}
[:div {:class (stl/css :constraints-bottom)} [:button {:class (stl/css-case :constraint-btn true
[:button {:class (stl/css-case :constraint-btn true :active (or (= constraints-v :bottom)
:active (or (= constraints-v :bottom) (= constraints-v :topbottom)))
(= constraints-v :topbottom))) :data-value :bottom
:data-value :bottom :on-click on-constraint-button-clicked}
:on-click on-constraint-button-clicked} [:span {:class (stl/css :resalted-area)}]]]]
[:span {:class (stl/css :resalted-area)}]]]] [:div {:class (stl/css :contraints-selects)}
[:div {:class (stl/css :contraints-selects)} [:div {:class (stl/css :horizontal-select)}
[:div {:class (stl/css :horizontal-select)} [:& select
[:& select {:default-value (d/name constraints-h "scale")
{:default-value (d/name constraints-h "scale") :options options-h
:options options-h :on-change on-constraint-h-select-changed}]]
:on-change on-constraint-h-select-changed}]] [:div {:class (stl/css :vertical-select)}
[:div {:class (stl/css :vertical-select)} [:& select
[:& select {:default-value (d/name constraints-v "scale")
{:default-value (d/name constraints-v "scale") :options options-v
:options options-v :on-change on-constraint-v-select-changed}]]
:on-change on-constraint-v-select-changed}]] (when first-level?
(when first-level? [:div {:class (stl/css :checkbox)}
[:div {:class (stl/css :checkbox)}
[:label {:for "fixed-on-scroll" [:label {:for "fixed-on-scroll"
:class (stl/css-case :checked (:fixed-scroll values))} :class (stl/css-case :checked (:fixed-scroll values))}
[:span {:class (stl/css-case :check-mark true [:span {:class (stl/css-case :check-mark true
:checked (:fixed-scroll values))} :checked (:fixed-scroll values))}
(when (:fixed-scroll values) (when (:fixed-scroll values)
i/status-tick-refactor)] i/status-tick-refactor)]
(tr "workspace.options.constraints.fix-when-scrolling") (tr "workspace.options.constraints.fix-when-scrolling")
[:input {:type "checkbox" [:input {:type "checkbox"
:id "fixed-on-scroll" :id "fixed-on-scroll"
:checked (:fixed-scroll values) :checked (:fixed-scroll values)
:on-change on-fixed-scroll-clicked}]]])]])] :on-change on-fixed-scroll-clicked}]]])]])])))
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.options.constraints")]]
[:div.element-set-content
[:div.row-flex.align-top
[:div.constraints-widget
[:div.constraints-box]
[:div.constraint-button.top
{:class (dom/classnames :active (or (= constraints-v :top)
(= constraints-v :topbottom)))
:data-value :top
:on-click on-constraint-button-clicked}]
[:div.constraint-button.bottom
{:class (dom/classnames :active (or (= constraints-v :bottom)
(= constraints-v :topbottom)))
:data-value :bottom
:on-click on-constraint-button-clicked}]
[:div.constraint-button.left
{:class (dom/classnames :active (or (= constraints-h :left)
(= constraints-h :leftright)))
:data-value :left
:on-click on-constraint-button-clicked}]
[:div.constraint-button.right
{:class (dom/classnames :active (or (= constraints-h :right)
(= constraints-h :leftright)))
:data-value :right
:on-click on-constraint-button-clicked}]
[:div.constraint-button.centerv
{:class (dom/classnames :active (= constraints-v :center))
:data-value :centerv
:on-click on-constraint-button-clicked}]
[:div.constraint-button.centerh
{:class (dom/classnames :active (= constraints-h :center))
:data-value :centerh
:on-click on-constraint-button-clicked}]]
[:div.constraints-form
[:div.row-flex
[:span.left-right i/full-screen]
[:select.input-select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:data-value :constraints-h
:on-change on-constraint-select-changed
:value (d/name constraints-h "scale")}
(when (= constraints-h :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "left"} (tr "workspace.options.constraints.left")]
[:option {:value "right"} (tr "workspace.options.constraints.right")]
[:option {:value "leftright"} (tr "workspace.options.constraints.leftright")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
[:div.row-flex
[:span.top-bottom i/full-screen]
[:select.input-select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:data-value :constraints-v
:on-change on-constraint-select-changed
:value (d/name constraints-v "scale")}
(when (= constraints-v :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "top"} (tr "workspace.options.constraints.top")]
[:option {:value "bottom"} (tr "workspace.options.constraints.bottom")]
[:option {:value "topbottom"} (tr "workspace.options.constraints.topbottom")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
(when first-level?
[:div.row-flex
[:div.fix-when {:class (dom/classnames :active (:fixed-scroll values))
:on-click on-fixed-scroll-clicked}
(if (:fixed-scroll values)
i/pin-fill
i/pin)
[:span (tr "workspace.options.constraints.fix-when-scrolling")]]])]]]]))))

View file

@ -8,149 +8,156 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-set-content { }
display: flex;
gap: $s-4; .element-set-content {
.constraints-widget { display: flex;
background-color: var(--constraint-widget-background-color); gap: $s-4;
display: grid; }
grid-template-columns: $s-24 $s-60 $s-24;
grid-template-rows: $s-24 $s-60 $s-24; .constraints-widget {
grid-template-areas: background-color: var(--constraint-widget-background-color);
"top top top" display: grid;
"left center right" grid-template-columns: $s-24 $s-60 $s-24;
"bottom bottom bottom"; grid-template-rows: $s-24 $s-60 $s-24;
height: $s-108; grid-template-areas:
width: $s-108; "top top top"
"left center right"
"bottom bottom bottom";
height: $s-108;
width: $s-108;
border-radius: $br-8;
}
.constraints-top,
.constraints-left,
.constraints-center,
.constraints-right,
.constraints-bottom {
@include flexCenter;
grid-area: top;
.constraint-btn,
.constraint-btn-special,
.constraint-btn-rotated {
@include buttonStyle;
@include flexCenter;
width: 100%;
height: 100%;
.resalted-area {
width: $s-32;
height: $s-3;
border-radius: $br-8; border-radius: $br-8;
.constraints-top, background-color: var(--button-constraint-background-color-rest);
.constraints-left, padding: 0;
.constraints-center, margin: 0;
.constraints-right,
.constraints-bottom {
@include flexCenter;
grid-area: top;
.constraint-btn,
.constraint-btn-special,
.constraint-btn-rotated {
@include buttonStyle;
@include flexCenter;
width: 100%;
height: 100%;
.resalted-area {
width: $s-32;
height: $s-3;
border-radius: $br-8;
background-color: var(--button-constraint-background-color-rest);
padding: 0;
margin: 0;
}
&.active .resalted-area {
outline: $s-4 solid var(--button-constraint-border-color-hover);
background-color: var(--button-constraint-background-color-hover);
}
&:hover .resalted-area,
&:focus .resalted-area {
outline: $s-4 solid var(--button-constraint-border-color-hover);
background-color: var(--button-constraint-background-color-hover);
}
}
}
.constraints-left {
grid-area: left;
.constraint-btn-rotated {
height: $s-60;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.constraints-center {
grid-area: center;
position: relative;
background-color: var(--constraint-center-area-background-color);
border-radius: $br-8;
.constraint-btn {
width: $s-60;
height: $s-24;
.resalted-area {
width: $s-32;
height: $s-3;
}
}
.constraint-btn-special {
position: absolute;
height: $s-60;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.constraints-right {
grid-area: right;
.constraint-btn-rotated {
height: $s-72;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.constraints-bottom {
grid-area: bottom;
}
} }
.contraints-selects { &.active .resalted-area {
@include flexColumn; outline: $s-4 solid var(--button-constraint-border-color-hover);
background-color: var(--button-constraint-background-color-hover);
}
&:hover .resalted-area,
&:focus .resalted-area {
outline: $s-4 solid var(--button-constraint-border-color-hover);
background-color: var(--button-constraint-background-color-hover);
}
}
}
.constraints-left {
grid-area: left;
.constraint-btn-rotated {
height: $s-60;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.constraints-center {
grid-area: center;
position: relative;
background-color: var(--constraint-center-area-background-color);
border-radius: $br-8;
.constraint-btn {
width: $s-60;
height: $s-24;
.resalted-area {
width: $s-32;
height: $s-3;
}
}
.constraint-btn-special {
position: absolute;
height: $s-60;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.horizontal-select, .constraints-right {
.vertical-select { grid-area: right;
width: $s-124; .constraint-btn-rotated {
padding: 0; height: $s-72;
width: $s-24;
.resalted-area {
height: $s-32;
width: $s-3;
}
}
}
.constraints-bottom {
grid-area: bottom;
}
.contraints-selects {
@include flexColumn;
}
.horizontal-select,
.vertical-select {
width: $s-124;
padding: 0;
}
.checkbox {
display: flex;
align-items: center;
margin-bottom: $s-8;
margin-top: $s-8;
padding-left: 0;
input {
margin: 0;
}
label {
@include titleTipography;
display: flex;
align-items: center;
gap: $s-2;
cursor: pointer;
color: var(--input-checkbox-text-foreground-color);
.check-mark {
@include flexCenter;
width: $s-16;
height: $s-16;
border-radius: $br-6;
background-color: var(--input-checkbox-inactive-background-color);
&.checked {
background-color: var(--input-checkbox-active-background-color);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
}
} }
&:hover {
.checkbox { border-color: var(--input-checkbox-border-color-hover);
display: flex; }
align-items: center; &:focus {
margin-bottom: $s-8; border-color: var(--input-checkbox-border-color-focus);
margin-top: $s-8;
padding-left: 0;
input {
margin: 0;
}
label {
@include titleTipography;
display: flex;
align-items: center;
gap: $s-2;
cursor: pointer;
color: var(--input-checkbox-text-foreground-color);
.check-mark {
@include flexCenter;
width: $s-16;
height: $s-16;
border-radius: $br-6;
background-color: var(--input-checkbox-inactive-background-color);
&.checked {
background-color: var(--input-checkbox-active-background-color);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
}
}
&:hover {
border-color: var(--input-checkbox-border-color-hover);
}
&:focus {
border-color: var(--input-checkbox-border-color-focus);
}
}
}
} }
} }
} }

View file

@ -15,7 +15,6 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.export] [app.main.ui.export]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -30,8 +29,7 @@
(mf/defc exports-menu (mf/defc exports-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "page-id" "file-id"]))]} {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "page-id" "file-id"]))]}
[{:keys [ids type values page-id file-id] :as props}] [{:keys [ids type values page-id file-id] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [exports (:exports values [])
exports (:exports values [])
has-exports? (or (= :multiple exports) (some? (seq exports))) has-exports? (or (= :multiple exports) (some? (seq exports)))
comp-state* (mf/use-state true) comp-state* (mf/use-state true)
@ -118,11 +116,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index event] (fn [index event]
(let [scale (if new-css-system (let [scale (d/parse-double event)]
(d/parse-double event)
(-> event
(dom/get-target-val)
(d/parse-double)))]
(st/emit! (dch/update-shapes ids (st/emit! (dch/update-shapes ids
(fn [shape] (fn [shape]
(assoc-in shape [:exports index :scale] scale))))))) (assoc-in shape [:exports index :scale] scale)))))))
@ -143,11 +137,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index event] (fn [index event]
(let [type (if new-css-system (let [type (keyword event)]
(keyword event)
(-> event
(dom/get-target-val)
(keyword)))]
(st/emit! (dch/update-shapes ids (st/emit! (dch/update-shapes ids
(fn [shape] (fn [shape]
(assoc-in shape [:exports index :type] type))))))) (assoc-in shape [:exports index :type] type)))))))
@ -179,125 +169,68 @@
{:value "svg" :label "SVG"} {:value "svg" :label "SVG"}
{:value "pdf" :label "PDF"}]] {:value "pdf" :label "PDF"}]]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-exports?
[:& title-bar {:collapsable? has-exports? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (tr (if (> (count ids) 1) "workspace.options.export-multiple" "workspace.options.export"))
:title (tr (if (> (count ids) 1) "workspace.options.export-multiple" "workspace.options.export")) :class (stl/css-case :title-spacing-export (not has-exports?))}
:class (stl/css-case :title-spacing-export (not has-exports?))} [:button {:class (stl/css :add-export)
[:button {:class (stl/css :add-export) :on-click add-export} i/add-refactor]]]
:on-click add-export} i/add-refactor]]] (when open?
(when open? [:div {:class (stl/css :element-set-content)}
[:div {:class (stl/css :element-set-content)}
(cond (cond
(= :multiple exports) (= :multiple exports)
[:div {:class (stl/css :multiple-exports)} [:div {:class (stl/css :multiple-exports)}
[:div {:class (stl/css :label)} (tr "settings.multiple")] [:div {:class (stl/css :label)} (tr "settings.multiple")]
[:div {:class (stl/css :actions)} [:div {:class (stl/css :actions)}
[:button {:class (stl/css :action-btn) [:button {:class (stl/css :action-btn)
:on-click on-remove-all} :on-click on-remove-all}
i/remove-refactor]]] i/remove-refactor]]]
(seq exports) (seq exports)
[:* [:*
(for [[index export] (d/enumerate exports)] (for [[index export] (d/enumerate exports)]
[:div {:class (stl/css :element-group) [:div {:class (stl/css :element-group)
:key index} :key index}
[:div {:class (stl/css :input-wrapper)} [:div {:class (stl/css :input-wrapper)}
[:div {:class (stl/css :format-select)} [: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 [:& select
{:default-value (d/name (:type export)) {:default-value (str (:scale export))
:options format-options :options size-options
:dropdown-class (stl/css :dropdown-upwards) :dropdown-class (stl/css :dropdown-upwards)
:on-change (partial on-type-change index)}]] :on-change (partial on-scale-change index)}]])
(when (scale-enabled? export) [:label {:class (stl/css :suffix-input)
[:div {:class (stl/css :size-select)} :for "suffix-export-input"}
[:& select [:input {:class (stl/css :type-input)
{:default-value (str (:scale export)) :id "suffix-export-input"
:options size-options :type "text"
:dropdown-class (stl/css :dropdown-upwards) :value (:suffix export)
:on-change (partial on-scale-change index)}]]) :placeholder (tr "workspace.options.export.suffix")
[:label {:class (stl/css :suffix-input) :data-value index
:for "suffix-export-input"} :on-change on-suffix-change
[:input {:class (stl/css :type-input) :on-key-down manage-key-down}]]]
: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}]]]
[:button {:class (stl/css :action-btn) [:button {:class (stl/css :action-btn)
:on-click (partial delete-export index)} :on-click (partial delete-export index)}
i/remove-refactor]])]) i/remove-refactor]])])
(when (or (= :multiple exports) (seq exports)) (when (or (= :multiple exports) (seq exports))
[:button [:button
{:on-click (when-not in-progress? on-download) {:on-click (when-not in-progress? on-download)
:class (stl/css-case :class (stl/css-case
:export-btn true :export-btn true
:btn-disabled in-progress?) :btn-disabled in-progress?)
:disabled in-progress?} :disabled in-progress?}
(if in-progress? (if in-progress?
(tr "workspace.options.exporting-object") (tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count shapes-with-exports))))])])] (tr "workspace.options.export-object" (c (count shapes-with-exports))))])])]))
[:div.element-set.exports-options
[:div.element-set-title
[:span (tr (if (> (count ids) 1) "workspace.options.export-multiple" "workspace.options.export"))]
(when (not (= :multiple exports))
[:div.add-page {:on-click add-export} i/close])]
(cond
(= :multiple exports)
[:div.element-set-options-group
[:div.element-set-label (tr "settings.multiple")]
[:div.element-set-actions
[:div.element-set-actions-button {:on-click on-remove-all}
i/minus]]]
(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 {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
: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")
:data-value index
:on-change on-suffix-change
:on-key-down manage-key-down}]
[:select.input-select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
: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]])])
(when (or (= :multiple exports) (seq exports))
[: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-with-exports))))])])))

View file

@ -8,12 +8,35 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
.title-spacing-export {
padding-left: $s-2; .title-spacing-export {
margin: 0; padding-left: $s-2;
} margin: 0;
.add-export { }
.add-export {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.element-set-content {
@include flexColumn;
margin: $s-4 0 $s-8 0;
}
.multiple-exports {
@include flexRow;
.label {
@extend .mixed-bar;
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary; @extend .button-tertiary;
height: $s-32; height: $s-32;
width: $s-28; width: $s-28;
@ -22,68 +45,49 @@
} }
} }
} }
.element-set-content { }
@include flexColumn;
margin: $s-4 0 $s-8 0; .element-group {
.multiple-exports { @include flexRow;
@include flexRow; .input-wrapper {
.label { @include flexRow;
@extend .mixed-bar; .format-select {
} width: $s-60;
.actions { padding: 0;
@include flexRow; .dropdown-upwards {
.action-btn { bottom: $s-36;
@extend .button-tertiary; width: $s-80;
height: $s-32; top: unset;
width: $s-28;
svg {
@extend .button-icon;
}
}
} }
} }
.element-group { .size-select {
@include flexRow; width: $s-60;
.input-wrapper { padding: 0;
@include flexRow; .dropdown-upwards {
.format-select { bottom: $s-36;
width: $s-60; top: unset;
padding: 0; width: $s-80;
.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 { .suffix-input {
@extend .button-secondary; @extend .input-element;
@include tabTitleTipography; min-width: $s-92;
height: $s-32; flex-grow: 1;
width: $s-252; }
}
.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

@ -13,7 +13,6 @@
[app.main.data.workspace.colors :as dc] [app.main.data.workspace.colors :as dc]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
@ -44,8 +43,7 @@
(mf/defc fill-menu (mf/defc fill-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]} {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]}
[{:keys [ids type values disable-remove?] :as props}] [{:keys [ids type values disable-remove?] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [label (case type
label (case type
:multiple (tr "workspace.options.selection-fill") :multiple (tr "workspace.options.selection-fill")
:group (tr "workspace.options.group-fill") :group (tr "workspace.options.group-fill")
(tr "workspace.options.fill")) (tr "workspace.options.fill"))
@ -137,83 +135,28 @@
(dom/set-attribute! checkbox "indeterminate" true) (dom/set-attribute! checkbox "indeterminate" true)
(dom/remove-attribute! checkbox "indeterminate"))))) (dom/remove-attribute! checkbox "indeterminate")))))
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-fills?
[:& title-bar {:collapsable? has-fills? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title label
:title label :class (stl/css-case :title-spacing-fill (not has-fills?))}
:class (stl/css-case :title-spacing-fill (not has-fills?))}
(when (and (not disable-remove?) (not (= :multiple fills))) (when (and (not disable-remove?) (not (= :multiple fills)))
[:button {:class (stl/css :add-fill) [:button {:class (stl/css :add-fill)
:on-click on-add} i/add-refactor])]] :on-click on-add} i/add-refactor])]]
(when open?
[:div {:class (stl/css :element-content)}
(cond
(= :multiple fills)
[:div {:class (stl/css :element-set-options-group)}
[:div {:class (stl/css :group-label)}
(tr "settings.multiple")]
[:button {:on-click on-remove-all
:class (stl/css :remove-btn)}
i/remove-refactor]]
(seq fills)
[:& h/sortable-container {}
(for [[index value] (d/enumerate (:fills values []))]
[:& color-row {:color {:color (:fill-color value)
:opacity (:fill-opacity value)
:id (:fill-color-ref-id value)
:file-id (:fill-color-ref-file value)
:gradient (:fill-color-gradient value)
:image (:fill-image value)}
:key index
:index index
:title (tr "workspace.options.fill")
:on-change (on-change index)
:on-reorder (on-reorder index)
:on-detach (on-detach index)
:on-remove (on-remove index)
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus (not @disable-drag)
:on-blur on-blur}])])
(when (or (= type :frame)
(and (= type :multiple) (some? (:hide-fill-on-export values))))
[:div {:class (stl/css :checkbox)}
[:label {:for "show-fill-on-export"
:class (stl/css-case :global/checked (not hide-fill-on-export?))}
[:span {:class (stl/css-case :check-mark true
:checked (not hide-fill-on-export?))}
(when (not hide-fill-on-export?)
i/status-tick-refactor)]
(tr "workspace.options.show-fill-on-export")
[:input {:type "checkbox"
:id "show-fill-on-export"
:ref checkbox-ref
:checked (not hide-fill-on-export?)
:on-change on-change-show-fill-on-export}]]])])]
;; OLD
[:div.element-set
[:div.element-set-title
[:span label]
(when (and (not disable-remove?) (not (= :multiple fills)))
[:div.add-page {:on-click on-add} i/close])]
[:div.element-set-content
(when open?
[:div {:class (stl/css :element-content)}
(cond (cond
(= :multiple fills) (= :multiple fills)
[:div.element-set-options-group [:div {:class (stl/css :element-set-options-group)}
[:div.element-set-label (tr "settings.multiple")] [:div {:class (stl/css :group-label)}
[:div.element-set-actions (tr "settings.multiple")]
[:div.element-set-actions-button {:on-click on-remove-all} [:button {:on-click on-remove-all
i/minus]]] :class (stl/css :remove-btn)}
i/remove-refactor]]
(seq fills) (seq fills)
[:& h/sortable-container {} [:& h/sortable-container {}
@ -238,12 +181,16 @@
(when (or (= type :frame) (when (or (= type :frame)
(and (= type :multiple) (some? (:hide-fill-on-export values)))) (and (= type :multiple) (some? (:hide-fill-on-export values))))
[:div.input-checkbox [:div {:class (stl/css :checkbox)}
[:input {:type "checkbox" [:label {:for "show-fill-on-export"
:id "show-fill-on-export" :class (stl/css-case :global/checked (not hide-fill-on-export?))}
:ref checkbox-ref [:span {:class (stl/css-case :check-mark true
:checked (not hide-fill-on-export?) :checked (not hide-fill-on-export?))}
:on-change on-change-show-fill-on-export}] (when (not hide-fill-on-export?)
i/status-tick-refactor)]
[:label {:for "show-fill-on-export"} (tr "workspace.options.show-fill-on-export")
(tr "workspace.options.show-fill-on-export")]])]]))) [:input {:type "checkbox"
:id "show-fill-on-export"
:ref checkbox-ref
:checked (not hide-fill-on-export?)
:on-change on-change-show-fill-on-export}]]])])]))

View file

@ -8,50 +8,58 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
margin: 0;
.title-spacing-fill { .element-title {
padding-left: $s-2; margin: 0;
margin: 0; }
}
.add-fill { .title-spacing-fill {
@extend .button-tertiary; padding-left: $s-2;
height: $s-32; margin: 0;
width: $s-28; }
svg {
@extend .button-icon; .add-fill {
} @extend .button-tertiary;
} height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
} }
.element-content { }
display: flex;
flex-direction: column; .element-content {
gap: $s-12; display: flex;
margin: $s-4 0 $s-8 0; flex-direction: column;
.element-set-options-group { gap: $s-12;
@include flexRow; margin: $s-4 0 $s-8 0;
.group-label { }
@extend .mixed-bar;
} .element-set-options-group {
.remove-btn { @include flexRow;
@extend .button-tertiary; }
height: $s-32;
width: $s-28; .group-label {
svg { @extend .mixed-bar;
@extend .button-icon; }
}
} .remove-btn {
} @extend .button-tertiary;
.checkbox { height: $s-32;
@extend .input-checkbox; width: $s-28;
padding-left: $s-8; svg {
span.checked { @extend .button-icon;
background-color: var(--input-border-color-active); }
svg { }
@extend .button-icon-small;
stroke: var(--input-details-color); .checkbox {
} @extend .input-checkbox;
} padding-left: $s-8;
span.checked {
background-color: var(--input-border-color-active);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
} }
} }
} }

View file

@ -15,11 +15,9 @@
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] [app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row input-row-v2]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l] [okulary.core :as l]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -35,8 +33,7 @@
(mf/defc grid-options (mf/defc grid-options
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [shape-id index grid frame-width frame-height default-grid-params]}] [{:keys [shape-id index grid frame-width frame-height default-grid-params]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [on-change (mf/use-fn (mf/deps shape-id index) #(st/emit! (dw/set-frame-grid shape-id index %)))
on-change (mf/use-fn (mf/deps shape-id index) #(st/emit! (dw/set-frame-grid shape-id index %)))
on-remove (mf/use-fn (mf/deps shape-id index) #(st/emit! (dw/remove-frame-grid shape-id index))) on-remove (mf/use-fn (mf/deps shape-id index) #(st/emit! (dw/remove-frame-grid shape-id index)))
on-save-default (mf/use-fn #(st/emit! (dw/set-default-grid (:type %) (:params %)))) on-save-default (mf/use-fn #(st/emit! (dw/set-default-grid (:type %) (:params %))))
@ -136,215 +133,87 @@
is-default (= (->> grid :params) is-default (= (->> grid :params)
(->> grid :type default-grid-params))] (->> grid :type default-grid-params))]
(if new-css-system [:div {:class (stl/css :grid-option)}
[:div {:class (stl/css :grid-option)} [:div {:class (stl/css :grid-title)}
[:div {:class (stl/css :grid-title)} [:div {:class (stl/css-case :option-row true
[:div {:class (stl/css-case :option-row true :hidden is-hidden?)}
:hidden is-hidden?)} [:button {:class (stl/css-case :show-options true
[:button {:class (stl/css-case :show-options true :selected open?)
:selected open?) :on-click toggle-advanced-options}
:on-click toggle-advanced-options} i/menu-refactor]
i/menu-refactor] [:div {:class (stl/css :type-select-wrapper)}
[:div {:class (stl/css :type-select-wrapper)}
[:& select
{:class (stl/css :grid-type-select)
:default-value type
:options [{:value :square :label (tr "workspace.options.grid.square")}
{:value :column :label (tr "workspace.options.grid.column")}
{:value :row :label (tr "workspace.options.grid.row")}]
:on-change handle-change-type}]]
(if (= type :square)
[:div {:class (stl/css :grid-size)
:title (tr "workspace.options.size")}
[:> numeric-input* {:min 0.01
:value (or (:size params) "")
:no-validate true
:className (stl/css :numeric-input)
:on-change (handle-change :params :size)}]]
[:div {:class (stl/css :editable-select-wrapper)}
[:& editable-select {:value (:size params)
:type "number"
:class (stl/css :column-select)
:input-class (stl/css :numeric-input)
:min 1
:options size-options
:placeholder "Auto"
:on-change handle-change-size}]])]
[:div {:class (stl/css :actions)}
[:button {:class (stl/css :action-btn)
:on-click handle-toggle-visibility}
(if display i/shown-refactor i/hide-refactor)]
[:button {:class (stl/css :action-btn)
:on-click on-remove}
i/remove-refactor]]]
(when (:display grid)
[:& advanced-options {:class (stl/css :grid-advanced-options)
:visible? open?
:on-close toggle-advanced-options}
;; square
(when (= :square type)
[:div {:class (stl/css :square-row)}
[:div {:class (stl/css :advanced-row)}
[:& color-row {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]
[:button {:class (stl/css-case :show-more-options true
:selected show-more-options?)
:on-click toggle-more-options}
i/menu-refactor]]
(when show-more-options?
[:div {:class (stl/css :second-row)}
[:button {:class (stl/css-case :btn-options true
:disabled is-default)
:disabled is-default
:on-click handle-use-default}
[:span (tr "workspace.options.grid.params.use-default")]]
[:button {:class (stl/css-case :btn-options true
:disabled is-default)
:disabled is-default
:on-click handle-set-as-default}
[:span (tr "workspace.options.grid.params.set-default")]]])])
(when (or (= :column type) (= :row type))
[:div {:class (stl/css :column-row)}
[:div {:class (stl/css :advanced-row)}
[:div {:class (stl/css :orientation-select-wrapper)}
[:& select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:default-value (:type params)
:class (stl/css :orientation-select)
:options [{:value :stretch :label (tr "workspace.options.grid.params.type.stretch")}
{:value :left :label (if (= type :row)
(tr "workspace.options.grid.params.type.top")
(tr "workspace.options.grid.params.type.left"))}
{:value :center :label (tr "workspace.options.grid.params.type.center")}
{:value :right :label (if (= type :row)
(tr "workspace.options.grid.params.type.bottom")
(tr "workspace.options.grid.params.type.right"))}]
:on-change (handle-change :params :type)}]]
[:div {:class (stl/css :color-wrapper)}
[:& color-row {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]]]
[:div {:class (stl/css :advanced-row)}
[:div {:class (stl/css :height)
:title (if (= :row type)
(tr "workspace.options.grid.params.height")
(tr "workspace.options.grid.params.width"))}
[:span {:class (stl/css :icon-text)}
(if (= :row type)
"H"
"W")]
[:> numeric-input* {:placeholder "Auto"
:on-change handle-change-item-length
:nillable true
:className (stl/css :numeric-input)
:value (or (:item-length params) "")}]]
[:div {:class (stl/css :gutter)
:title (tr "workspace.options.grid.params.gutter")}
[:span {:class (stl/css-case :icon true
:rotated (= type :row))} i/gap-horizontal-refactor]
[:> numeric-input* {:placeholder "0"
:on-change (handle-change :params :gutter)
:nillable true
:className (stl/css :numeric-input)
:value (or (:gutter params) 0)}]]
[:div {:class (stl/css :margin)
:title (tr "workspace.options.grid.params.margin")}
[:span {:class (stl/css-case :icon true
:rotated (= type :column))} i/grid-margin-refactor]
[:> numeric-input* {:placeholder "0"
:on-change (handle-change :params :margin)
:nillable true
:className (stl/css :numeric-input)
:value (or (:margin params) 0)}]]
[:button {:class (stl/css-case :show-more-options true
:selected show-more-options?)
:on-click toggle-more-options}
i/menu-refactor]
(when show-more-options?
[:div {:class (stl/css :more-options)}
[:button {:disabled is-default
:class (stl/css :option-btn)
:on-click handle-use-default} (tr "workspace.options.grid.params.use-default")]
[:button {:disabled is-default
:class (stl/css :option-btn)
:on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]])]])])]
[:div.grid-option
[:div.grid-option-main {:style {:display (when open? "none")}}
[:button.custom-button {:class (when open? "is-active")
:on-click toggle-advanced-options} i/actions]
[:& select [:& select
{:class "flex-grow" {:class (stl/css :grid-type-select)
:default-value type :default-value type
:options [{:value :square :label (tr "workspace.options.grid.square")} :options [{:value :square :label (tr "workspace.options.grid.square")}
{:value :column :label (tr "workspace.options.grid.column")} {:value :column :label (tr "workspace.options.grid.column")}
{:value :row :label (tr "workspace.options.grid.row")}] {:value :row :label (tr "workspace.options.grid.row")}]
:on-change handle-change-type}] :on-change handle-change-type}]]
(if (= type :square)
(if (= type :square) [:div {:class (stl/css :grid-size)
[:div.input-element.pixels {:title (tr "workspace.options.size")} :title (tr "workspace.options.size")}
[:> numeric-input* {:min 0.01 [:> numeric-input* {:min 0.01
:value (or (:size params) "") :value (or (:size params) "")
:no-validate true :no-validate true
:on-change (handle-change :params :size)}]] :className (stl/css :numeric-input)
:on-change (handle-change :params :size)}]]
[:div {:class (stl/css :editable-select-wrapper)}
[:& editable-select {:value (:size params) [:& editable-select {:value (:size params)
:type "number" :type "number"
:class "input-option" :class (stl/css :column-select)
:input-class (stl/css :numeric-input)
:min 1 :min 1
:options size-options :options size-options
:placeholder "Auto" :placeholder "Auto"
:on-change handle-change-size}]) :on-change handle-change-size}]])]
[:div.grid-option-main-actions [:div {:class (stl/css :actions)}
[:button.custom-button {:on-click handle-toggle-visibility} (if display i/eye i/eye-closed)] [:button {:class (stl/css :action-btn)
[:button.custom-button {:on-click on-remove} i/minus]]] :on-click handle-toggle-visibility}
(if display i/shown-refactor i/hide-refactor)]
[:button {:class (stl/css :action-btn)
:on-click on-remove}
i/remove-refactor]]]
[:& advanced-options {:visible? open? :on-close toggle-advanced-options} (when (:display grid)
[:button.custom-button {:on-click toggle-advanced-options} i/actions] [:& advanced-options {:class (stl/css :grid-advanced-options)
:visible? open?
:on-close toggle-advanced-options}
;; square
(when (= :square type) (when (= :square type)
[:& input-row {:label (tr "workspace.options.grid.params.size") [:div {:class (stl/css :square-row)}
:class "pixels" [:div {:class (stl/css :advanced-row)}
:min 0.01 [:& color-row {:color (:color params)
:value (:size params) :title (tr "workspace.options.grid.params.color")
:on-change (handle-change :params :size)}]) :disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]
[:button {:class (stl/css-case :show-more-options true
:selected show-more-options?)
:on-click toggle-more-options}
i/menu-refactor]]
(when show-more-options?
[:div {:class (stl/css :second-row)}
[:button {:class (stl/css-case :btn-options true
:disabled is-default)
:disabled is-default
:on-click handle-use-default}
[:span (tr "workspace.options.grid.params.use-default")]]
[:button {:class (stl/css-case :btn-options true
:disabled is-default)
:disabled is-default
:on-click handle-set-as-default}
[:span (tr "workspace.options.grid.params.set-default")]]])])
(when (= :row type) (when (or (= :column type) (= :row type))
[:& input-row {:label (tr "workspace.options.grid.params.rows") [:div {:class (stl/css :column-row)}
:type :editable-select [:div {:class (stl/css :advanced-row)}
:options size-options [:div {:class (stl/css :orientation-select-wrapper)}
:value (:size params) [:& select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:min 1 :default-value (:type params)
:placeholder "Auto" :class (stl/css :orientation-select)
:on-change handle-change-size}])
(when (= :column type)
[:& input-row {:label (tr "workspace.options.grid.params.columns")
:type :editable-select
:options size-options
:value (:size params)
:min 1
:placeholder "Auto"
:on-change handle-change-size}])
(when (#{:row :column} type)
[:& input-row {:label (tr "workspace.options.grid.params.type")
:type :select
:options [{:value :stretch :label (tr "workspace.options.grid.params.type.stretch")} :options [{:value :stretch :label (tr "workspace.options.grid.params.type.stretch")}
{:value :left :label (if (= type :row) {:value :left :label (if (= type :row)
(tr "workspace.options.grid.params.type.top") (tr "workspace.options.grid.params.type.top")
@ -353,56 +222,67 @@
{:value :right :label (if (= type :row) {:value :right :label (if (= type :row)
(tr "workspace.options.grid.params.type.bottom") (tr "workspace.options.grid.params.type.bottom")
(tr "workspace.options.grid.params.type.right"))}] (tr "workspace.options.grid.params.type.right"))}]
:value (:type params) :on-change (handle-change :params :type)}]]
:on-change (handle-change :params :type)}])
(when (#{:row :column} type) [:div {:class (stl/css :color-wrapper)}
[:& input-row-v2 [:& color-row {:color (:color params)
{:class "pixels" :title (tr "workspace.options.grid.params.color")
:label (if (= :row type) :disable-gradient true
(tr "workspace.options.grid.params.height") :disable-image true
(tr "workspace.options.grid.params.width"))} :on-change handle-change-color
[:> numeric-input* :on-detach handle-detach-color}]]]
{:placeholder "Auto"
:value (or (:item-length params) "")
:nillable true
:on-change handle-change-item-length}]])
(when (#{:row :column} type) [:div {:class (stl/css :advanced-row)}
[:* [:div {:class (stl/css :height)
[:& input-row {:label (tr "workspace.options.grid.params.gutter") :title (if (= :row type)
:class "pixels" (tr "workspace.options.grid.params.height")
:value (:gutter params) (tr "workspace.options.grid.params.width"))}
:min 0 [:span {:class (stl/css :icon-text)}
:nillable true (if (= :row type)
:default 0 "H"
:placeholder "0" "W")]
:on-change (handle-change :params :gutter)}] [:> numeric-input* {:placeholder "Auto"
[:& input-row {:label (tr "workspace.options.grid.params.margin") :on-change handle-change-item-length
:class "pixels" :nillable true
:min 0 :className (stl/css :numeric-input)
:nillable true :value (or (:item-length params) "")}]]
:default 0
:placeholder "0"
:value (:margin params)
:on-change (handle-change :params :margin)}]])
[:& color-row {:color (:color params) [:div {:class (stl/css :gutter)
:title (tr "workspace.options.grid.params.color") :title (tr "workspace.options.grid.params.gutter")}
:disable-gradient true [:span {:class (stl/css-case :icon true
:disable-image true :rotated (= type :row))} i/gap-horizontal-refactor]
:on-change handle-change-color [:> numeric-input* {:placeholder "0"
:on-detach handle-detach-color}] :on-change (handle-change :params :gutter)
[:div.row-flex :nillable true
[:button.btn-options {:disabled is-default :className (stl/css :numeric-input)
:on-click handle-use-default} (tr "workspace.options.grid.params.use-default")] :value (or (:gutter params) 0)}]]
[:button.btn-options {:disabled is-default
:on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]]]]))) [:div {:class (stl/css :margin)
:title (tr "workspace.options.grid.params.margin")}
[:span {:class (stl/css-case :icon true
:rotated (= type :column))} i/grid-margin-refactor]
[:> numeric-input* {:placeholder "0"
:on-change (handle-change :params :margin)
:nillable true
:className (stl/css :numeric-input)
:value (or (:margin params) 0)}]]
[:button {:class (stl/css-case :show-more-options true
:selected show-more-options?)
:on-click toggle-more-options}
i/menu-refactor]
(when show-more-options?
[:div {:class (stl/css :more-options)}
[:button {:disabled is-default
:class (stl/css :option-btn)
:on-click handle-use-default} (tr "workspace.options.grid.params.use-default")]
[:button {:disabled is-default
:class (stl/css :option-btn)
:on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]])]])])]))
(mf/defc frame-grid (mf/defc frame-grid
[{:keys [shape]}] [{:keys [shape]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [state* (mf/use-state true)
state* (mf/use-state true)
open? (deref state*) open? (deref state*)
frame-grids (:grids shape) frame-grids (:grids shape)
has-frame-grids? (or (= :multiple frame-grids) (some? (seq frame-grids))) has-frame-grids? (or (= :multiple frame-grids) (some? (seq frame-grids)))
@ -413,44 +293,26 @@
default-grid-params (mf/use-memo (mf/deps saved-grids) #(merge dw/default-grid-params saved-grids)) default-grid-params (mf/use-memo (mf/deps saved-grids) #(merge dw/default-grid-params saved-grids))
handle-create-grid (mf/use-fn (mf/deps id) #(st/emit! (dw/add-frame-grid id)))] handle-create-grid (mf/use-fn (mf/deps id) #(st/emit! (dw/add-frame-grid id)))]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:& title-bar {:collapsable? has-frame-grids?
[:& title-bar {:collapsable? has-frame-grids? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :class (stl/css-case :title-spacing-board-grid (not has-frame-grids?))
:class (stl/css-case :title-spacing-board-grid (not has-frame-grids?)) :title (tr "workspace.options.guides.title")}
:title (tr "workspace.options.guides.title")}
[:button {:on-click handle-create-grid [:button {:on-click handle-create-grid
:class (stl/css :add-grid)} :class (stl/css :add-grid)}
i/add-refactor]] i/add-refactor]]
(when (and open? (seq frame-grids)) (when (and open? (seq frame-grids))
[:div {:class (stl/css :element-set-content)} [:div {:class (stl/css :element-set-content)}
(for [[index grid] (map-indexed vector frame-grids)] (for [[index grid] (map-indexed vector frame-grids)]
[:& grid-options {:key (str id "-" index) [:& grid-options {:key (str id "-" index)
:shape-id id :shape-id id
:grid grid :grid grid
:index index :index index
:frame-width (:width shape) :frame-width (:width shape)
:frame-height (:height shape) :frame-height (:height shape)
:default-grid-params default-grid-params}])])] :default-grid-params default-grid-params}])])]))
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.options.grid.grid-title")]
[:div.add-page {:on-click handle-create-grid} i/close]]
(when (seq frame-grids)
[:div.element-set-content
(for [[index grid] (map-indexed vector frame-grids)]
[:& grid-options {:key (str id "-" index)
:shape-id id
:grid grid
:index index
:frame-width (:width shape)
:frame-height (:height shape)
:default-grid-params default-grid-params}])])])))

View file

@ -8,241 +8,250 @@
.element-set { .element-set {
margin: 0; margin: 0;
.title-spacing-board-grid { }
padding-left: $s-2;
margin: 0; .title-spacing-board-grid {
padding-left: $s-2;
margin: 0;
}
.add-grid {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
} }
.add-grid { }
@extend .button-tertiary;
.element-set-content {
@include flexColumn;
margin: $s-4 0 $s-8 0;
}
.grid-title {
@include flexRow;
}
.option-row {
display: flex;
align-items: center;
gap: $s-1;
border-radius: $br-8;
background-color: var(--input-details-color);
.show-options {
@extend .button-secondary;
height: $s-32; height: $s-32;
width: $s-28; width: $s-28;
border-radius: $br-8 0 0 $br-8;
box-sizing: border-box;
border: $s-1 solid var(--input-background-color);
svg { svg {
@extend .button-icon; @extend .button-icon;
} }
&.selected {
@extend .button-icon-selected;
}
} }
.element-set-content { .type-select-wrapper {
@include flexColumn; width: $s-96;
margin: $s-4 0 $s-8 0; padding: 0;
.grid-option { border-radius: 0;
.grid-title { height: $s-32;
@include flexRow; .grid-type-select {
.option-row { border-radius: 0;
display: flex; height: 100%;
align-items: center; box-sizing: border-box;
gap: $s-1; border: $s-1 solid var(--input-background-color);
border-radius: $br-8; &:hover {
background-color: var(--input-details-color); border: $s-1 solid var(--input-background-color-hover);
.show-options { }
@extend .button-secondary; }
height: $s-32; }
width: $s-28; .grid-size {
border-radius: $br-8 0 0 $br-8; @extend .asset-element;
box-sizing: border-box; width: $s-60;
border: $s-1 solid var(--input-background-color); margin: 0;
svg { padding: 0;
@extend .button-icon; padding-left: $s-8;
} border-radius: 0 $br-8 $br-8 0;
&.selected { .numeric-input {
@extend .button-icon-selected; @extend .input-base;
} }
} }
.type-select-wrapper { .editable-select-wrapper {
width: $s-96; @extend .asset-element;
padding: 0; width: $s-60;
border-radius: 0; margin: 0;
height: $s-32; padding: 0;
.grid-type-select { position: relative;
border-radius: 0; border-radius: 0 $br-8 $br-8 0;
height: 100%; .column-select {
box-sizing: border-box; height: $s-32;
border: $s-1 solid var(--input-background-color); border-radius: 0 $br-8 $br-8 0;
&:hover { box-sizing: border-box;
border: $s-1 solid var(--input-background-color-hover); border: $s-1 solid var(--input-background-color);
} .numeric-input {
} @extend .input-base;
} margin: 0;
.grid-size { padding: 0;
@extend .asset-element; }
width: $s-60; span {
margin: 0; @include flexCenter;
padding: 0; svg {
padding-left: $s-8; @extend .button-icon;
border-radius: 0 $br-8 $br-8 0;
.numeric-input {
@extend .input-base;
}
}
.editable-select-wrapper {
@extend .asset-element;
width: $s-60;
margin: 0;
padding: 0;
position: relative;
border-radius: 0 $br-8 $br-8 0;
.column-select {
height: $s-32;
border-radius: 0 $br-8 $br-8 0;
box-sizing: border-box;
border: $s-1 solid var(--input-background-color);
.numeric-input {
@extend .input-base;
margin: 0;
padding: 0;
}
span {
@include flexCenter;
svg {
@extend .button-icon;
}
}
}
}
&.hidden {
.show-options {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
}
.type-select-wrapper,
.editable-select-wrapper {
@include hiddenElement;
.column-select,
.grid-type-select {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
}
.column-select {
@include hiddenElement;
border-radius: 0 $br-8 $br-8 0;
.numeric-input {
@include hiddenElement;
}
}
}
.grid-size {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
.icon {
stroke: var(--input-foreground-color-disabled);
}
.numeric-input {
color: var(--input-foreground-color-disabled);
}
}
.actions {
.hidden-btn,
.lock-btn {
background-color: transparent;
svg {
stroke: var(--input-foreground-color-disabled);
}
}
}
}
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
} }
} }
} }
.grid-advanced-options { }
@include flexColumn;
margin-top: $s-4;
.column-row,
.square-row {
@include flexColumn;
position: relative;
.advanced-row {
position: relative;
display: flex;
gap: $s-4;
.orientation-select-wrapper {
width: $s-92;
padding: 0;
}
.color-wrapper {
width: $s-156;
}
.show-more-options {
@extend .button-tertiary;
height: $s-32;
width: $s-32;
svg {
@extend .button-icon;
}
&.selected {
@extend .button-icon-selected;
}
}
.height {
@extend .input-element;
width: $s-108;
.icon-text {
padding-top: $s-1;
}
}
.gutter,
.margin {
@extend .input-element;
width: $s-108;
.icon {
&.rotated svg {
transform: rotate(90deg);
}
}
}
.more-options {
@include menuShadow;
@include flexColumn;
position: absolute;
top: calc($s-2 + $s-28);
right: 0;
width: $s-156;
max-height: $s-300;
padding: $s-2;
margin: 0 0 $s-40 0;
margin-top: $s-4;
border-radius: $br-8;
z-index: $z-index-3;
overflow-y: auto;
background-color: var(--menu-background-color);
.option-btn {
@include buttonStyle;
display: flex;
align-items: center;
height: $s-32;
padding: 0 $s-8;
border-radius: $br-6;
color: var(--menu-foreground-color);
&:hover { &.hidden {
background-color: var(--menu-background-color-hover); .show-options {
color: var(--menu-foreground-color-hover); @include hiddenElement;
} border: $s-1 solid var(--input-border-color-disabled);
} }
} .type-select-wrapper,
.editable-select-wrapper {
@include hiddenElement;
.column-select,
.grid-type-select {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
}
.column-select {
@include hiddenElement;
border-radius: 0 $br-8 $br-8 0;
.numeric-input {
@include hiddenElement;
} }
.second-row { }
@extend .dropdown-wrapper; }
left: unset; .grid-size {
right: 0; @include hiddenElement;
width: $s-108; border: $s-1 solid var(--input-border-color-disabled);
.btn-options { .icon {
@include buttonStyle; stroke: var(--input-foreground-color-disabled);
@extend .dropdown-element-base; }
width: 100%; .numeric-input {
} color: var(--input-foreground-color-disabled);
}
}
.actions {
.hidden-btn,
.lock-btn {
background-color: transparent;
svg {
stroke: var(--input-foreground-color-disabled);
} }
} }
} }
} }
} }
.actions {
@include flexRow;
}
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.grid-advanced-options {
@include flexColumn;
margin-top: $s-4;
}
.column-row,
.square-row {
@include flexColumn;
position: relative;
}
.advanced-row {
position: relative;
display: flex;
gap: $s-4;
.orientation-select-wrapper {
width: $s-92;
padding: 0;
}
.color-wrapper {
width: $s-156;
}
.show-more-options {
@extend .button-tertiary;
height: $s-32;
width: $s-32;
svg {
@extend .button-icon;
}
&.selected {
@extend .button-icon-selected;
}
}
.height {
@extend .input-element;
width: $s-108;
.icon-text {
padding-top: $s-1;
}
}
.gutter,
.margin {
@extend .input-element;
width: $s-108;
.icon {
&.rotated svg {
transform: rotate(90deg);
}
}
}
.more-options {
@include menuShadow;
@include flexColumn;
position: absolute;
top: calc($s-2 + $s-28);
right: 0;
width: $s-156;
max-height: $s-300;
padding: $s-2;
margin: 0 0 $s-40 0;
margin-top: $s-4;
border-radius: $br-8;
z-index: $z-index-3;
overflow-y: auto;
background-color: var(--menu-background-color);
.option-btn {
@include buttonStyle;
display: flex;
align-items: center;
height: $s-32;
padding: 0 $s-8;
border-radius: $br-6;
color: var(--menu-foreground-color);
&:hover {
background-color: var(--menu-background-color-hover);
color: var(--menu-foreground-color-hover);
}
}
}
}
.second-row {
@extend .dropdown-wrapper;
left: unset;
right: 0;
width: $s-108;
.btn-options {
@include buttonStyle;
@extend .dropdown-element-base;
width: 100%;
}
}

View file

@ -18,10 +18,8 @@
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.menus.layout-container :as lyc]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -38,9 +36,7 @@
(mf/defc set-self-alignment (mf/defc set-self-alignment
[{:keys [is-col? alignment set-alignment] :as props}] [{:keys [is-col? alignment set-alignment] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [alignment (or alignment :auto)
dir-v [:auto :start :center :end :stretch #_:baseline]
alignment (or alignment :auto)
type (if is-col? "col" "row") type (if is-col? "col" "row")
handle-set-alignment handle-set-alignment
@ -49,8 +45,7 @@
(fn [value] (fn [value]
(set-alignment (-> value keyword))))] (set-alignment (-> value keyword))))]
(if new-css-system [:div {:class (stl/css :self-align-menu)}
[:div {:class (stl/css :self-align-menu)}
[:& radio-buttons {:selected (d/name alignment) [:& radio-buttons {:selected (d/name alignment)
:on-change handle-set-alignment :on-change handle-set-alignment
:name (dm/str "flex-align-items-" type)} :name (dm/str "flex-align-items-" type)}
@ -72,27 +67,14 @@
[:& radio-button {:value "stretch" [:& radio-button {:value "stretch"
:icon (if is-col? i/align-self-row-strech i/align-self-column-strech) :icon (if is-col? i/align-self-row-strech i/align-self-column-strech)
:title "Align self stretch" :title "Align self stretch"
:id (dm/str "align-self-stretch-" type)}]]] :id (dm/str "align-self-stretch-" type)}]]]))
[:div.align-self-style
(for [align dir-v]
[:button.align-self.tooltip.tooltip-bottom
{:class (dom/classnames :active (= alignment align)
:tooltip-bottom-left (not= align :start)
:tooltip-bottom (= align :start))
:alt (dm/str "Align self " (d/name align)) ;; TODO fix this tooltip
:on-click #(set-alignment align)
:key (str "align-self" align)}
(lyc/get-layout-flex-icon :align-self align is-col?)])])))
(mf/defc options (mf/defc options
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [shape cell cells] :as props}] [{:keys [shape cell cells] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [state* (mf/use-state {:open true})
state* (mf/use-state {:open true})
open? (:open @state*) open? (:open @state*)
cells (hooks/use-equal-memo cells) cells (hooks/use-equal-memo cells)
@ -181,208 +163,104 @@
(dwge/clear-selection (:id shape)))))] (dwge/clear-selection (:id shape)))))]
(if new-css-system [:div {:class (stl/css :grid-cell-menu)}
[:div {:class (stl/css :grid-cell-menu)} [:div {:class (stl/css :grid-cell-menu-title)}
[:div {:class (stl/css :grid-cell-menu-title)} [:& title-bar {:collapsable? true
[:& title-bar {:collapsable? true :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed #(swap! state* update :open not)
:on-collapsed #(swap! state* update :open not) :title "Grid cell"}]]
:title "Grid cell"}]]
(when open? (when open?
[:div {:class (stl/css :grid-cell-menu-container)} [:div {:class (stl/css :grid-cell-menu-container)}
[:div {:class (stl/css :cell-mode :row)} [:div {:class (stl/css :cell-mode :row)}
[:& radio-buttons {:selected (d/name cell-mode) [:& radio-buttons {:selected (d/name cell-mode)
:on-change set-cell-mode :on-change set-cell-mode
:name "cell-mode" :name "cell-mode"
:wide true} :wide true}
[:& radio-button {:value "auto" :id :auto}] [:& radio-button {:value "auto" :id :auto}]
[:& radio-button {:value "manual" :id :manual}] [:& radio-button {:value "manual" :id :manual}]
[:& radio-button {:value "area" :id :area}]]] [:& radio-button {:value "area"
:id :area
(when (= :area cell-mode) :disabled (not valid-area-cells?)}]]]
[:div {:class (stl/css :row)}
[:input
{:class (stl/css :area-input)
:key (dm/str "name-" (:id cell))
:id "grid-area-name"
:type "text"
:aria-label "grid-area-name"
:placeholder "Area name"
:default-value area-name
:auto-complete "off"
:on-change on-area-name-change}]])
(when (and (not multiple?) (= :auto cell-mode))
[:div {:class (stl/css :row)}
[:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/flex-vertical-refactor]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:title "Column"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :column)
:value column}]]]
[:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/flex-horizontal-refactor]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:title "Row"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :row)
:value row}]]]])
(when (and (not multiple?) (or (= :manual cell-mode) (= :area cell-mode)))
[:div {:class (stl/css :row)}
[:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/layout-rows]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :start :column)
:value column}]]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :end :column)
:value column-end}]]]
[:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/layout-columns]
[:div {:class (stl/css :coord-input :double)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :start :row)
:value row}]]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :end :row)
:value row-end}]]]])
(when (= :area cell-mode)
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& set-self-alignment {:is-col? false [:input
:alignment align-self {:class (stl/css :area-input)
:set-alignment set-alignment}] :key (dm/str "name-" (:id cell))
[:& set-self-alignment {:is-col? true :id "grid-area-name"
:alignment justify-self :type "text"
:set-alignment set-justify-self}]] :aria-label "grid-area-name"
:placeholder "Area name"
:default-value area-name
:auto-complete "off"
:on-change on-area-name-change}]])
(when (and (not multiple?) (= :auto cell-mode))
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:button [:div {:class (stl/css :grid-coord-group)}
{:class (stl/css :edit-grid-btn) [:span {:class (stl/css :icon)} i/flex-vertical-refactor]
:alt (tr "workspace.layout_grid.editor.options.edit-grid") [:div {:class (stl/css :coord-input)}
:on-click toggle-edit-mode} [:> numeric-input*
(tr "workspace.layout_grid.editor.options.edit-grid")]]])] {:placeholder "--"
:title "Column"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :column)
:value column}]]]
[:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/flex-horizontal-refactor]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:title "Row"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :row)
:value row}]]]])
[:div.element-set (when (and (not multiple?) (or (= :manual cell-mode) (= :area cell-mode)))
[:div.element-set-title [:div {:class (stl/css :row)}
[:span "Grid Cell"]] [:div {:class (stl/css :grid-coord-group)}
[:span {:class (stl/css :icon)} i/layout-rows]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :start :column)
:value column}]]
[:div {:class (stl/css :coord-input)}
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :end :column)
:value column-end}]]]
[:div.element-set-content.layout-grid-item-menu [:div {:class (stl/css :grid-coord-group)}
[:div.layout-row [:span {:class (stl/css :icon)} i/layout-columns]
[:div.row-title.sizing "Position"] [:div {:class (stl/css :coord-input :double)}
[:div.position-wrapper [:> numeric-input*
[:button.position-btn {:placeholder "--"
{:on-click #(set-cell-mode :auto) :on-pointer-down #(dom/select-target %)
:class (dom/classnames :active (= :auto cell-mode))} "Auto"] :on-change (partial on-grid-coordinates :start :row)
(when-not multiple? :value row}]]
[:button.position-btn [:div {:class (stl/css :coord-input)}
{:on-click #(set-cell-mode :manual) [:> numeric-input*
:class (dom/classnames :active (= :manual cell-mode))} "Manual"]) {:placeholder "--"
[:button.position-btn :on-pointer-down #(dom/select-target %)
{:on-click #(set-cell-mode :area) :on-change (partial on-grid-coordinates :end :row)
:disabled (not valid-area-cells?) :value row-end}]]]])
:class (dom/classnames :active (= :area cell-mode))} "Area"]]]
[:div.manage-grid-columns [:div {:class (stl/css :row)}
(when (and (not multiple?) (= :auto cell-mode)) [:& set-self-alignment {:is-col? false
[:div.grid-auto :alignment align-self
[:div.grid-columns-auto :set-alignment set-alignment}]
[:span.icon i/layout-rows] [:& set-self-alignment {:is-col? true
[:div.input-wrapper :alignment justify-self
[:> numeric-input* :set-alignment set-justify-self}]]
{:placeholder "--"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :column)
:value column}]]]
[:div.grid-rows-auto
[:span.icon i/layout-columns]
[:div.input-wrapper
[:> numeric-input*
{:placeholder "--"
:on-click #(dom/select-target %)
:on-change (partial on-grid-coordinates :all :row)
:value row}]]]])
(when (= :area cell-mode) [:div {:class (stl/css :row)}
[:div.input-wrapper [:button
[:input.input-text {:class (stl/css :edit-grid-btn)
{:key (dm/str "name-" (:id cell)) :alt (tr "workspace.layout_grid.editor.options.edit-grid")
:id "grid-area-name" :on-click toggle-edit-mode}
:type "text" (tr "workspace.layout_grid.editor.options.edit-grid")]]])]))
:aria-label "grid-area-name"
:placeholder "--"
:default-value area-name
:auto-complete "off"
:on-change on-area-name-change}]])
(when (and (not multiple?) (or (= :manual cell-mode) (= :area cell-mode)))
[:div.grid-manual
[:div.grid-columns-auto
[:span.icon i/layout-rows]
[:div.input-wrapper
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :start :column)
:value column}]
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :end :column)
:value column-end}]]]
[:div.grid-rows-auto
[:span.icon i/layout-columns]
[:div.input-wrapper
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :start :row)
:value row}]
[:> numeric-input*
{:placeholder "--"
:on-pointer-down #(dom/select-target %)
:on-change (partial on-grid-coordinates :end :row)
:value row-end}]]]])]
[:div.layout-row
[:div.row-title "Align"]
[:div.btn-wrapper
[:& set-self-alignment {:is-col? false
:alignment align-self
:set-alignment set-alignment}]]]
[:div.layout-row
[:div.row-title "Justify"]
[:div.btn-wrapper
[:& set-self-alignment {:is-col? true
:alignment justify-self
:set-alignment set-justify-self}]]]
[:div.layout-row.single-button
[:div.btn-wrapper
[:div.edit-mode
[:button.tooltip.tooltip-bottom-left
{:alt "Grid edit mode"
:on-click toggle-edit-mode
:style {:padding 0}}
"Edit grid"
i/grid-layout-mode]]]]]])))

View file

@ -6,53 +6,51 @@
@import "refactor/common-refactor.scss"; @import "refactor/common-refactor.scss";
.grid-cell-menu { .grid-cell-menu-container {
.grid-cell-menu-container { @include flexColumn;
@include flexColumn; margin-top: $s-8;
margin-top: $s-8; gap: $s-16;
gap: $s-16; }
}
.grid-cell-menu-title { .grid-cell-menu-title {
font-size: $fs-11; font-size: $fs-11;
} }
.row { .row {
@include flexRow; @include flexRow;
} }
.cell-mode :global(label) { .cell-mode :global(label) {
padding: 0 $s-12; padding: 0 $s-12;
} }
.edit-grid-btn { .edit-grid-btn {
@extend .button-secondary; @extend .button-secondary;
@include tabTitleTipography; @include tabTitleTipography;
width: 100%; width: 100%;
padding: $s-8; padding: $s-8;
} }
.area-input { .area-input {
@extend .input-element; @extend .input-element;
width: 100%; width: 100%;
padding: $s-8; padding: $s-8;
}
} }
.grid-coord-group { .grid-coord-group {
@include flexRow; @include flexRow;
border-radius: $br-8; border-radius: $br-8;
padding-left: $s-4; padding-left: $s-4;
background-color: var(--input-background-color); background-color: var(--input-background-color);
}
.icon svg {
@extend .button-icon; .icon svg {
stroke: var(--icon-foreground); @extend .button-icon;
} stroke: var(--icon-foreground);
.coord-input { }
@extend .input-element;
border-radius: 0 $br-8 $br-8 0; .coord-input {
border-left: 1px solid var(--panel-background-color); @extend .input-element;
} border-radius: 0 $br-8 $br-8 0;
border-left: 1px solid var(--panel-background-color);
} }

View file

@ -14,7 +14,6 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -33,9 +32,7 @@
(mf/defc layer-menu (mf/defc layer-menu
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [ids (unchecked-get props "ids")
ids (unchecked-get props "ids")
type (unchecked-get props "type")
values (unchecked-get props "values") values (unchecked-get props "values")
hidden? (:hidden values) hidden? (:hidden values)
@ -148,90 +145,46 @@
preview-complete?)) preview-complete?))
(swap! state* assoc :selected-blend-mode current-blend-mode))) (swap! state* assoc :selected-blend-mode current-blend-mode)))
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css-case :element-set-content true
[:div {:class (stl/css-case :element-set-content true :hidden hidden?)}
:hidden hidden?)} [:div {:class (stl/css :select)}
[:div {:class (stl/css :select)} [:& select
[:& select {:default-value selected-blend-mode
{:default-value selected-blend-mode :options options
:options options :on-change handle-change-blend-mode
:on-change handle-change-blend-mode :is-open? option-highlighted?
:is-open? option-highlighted? :class (stl/css-case :hidden-select hidden?)
:class (stl/css-case :hidden-select hidden?) :on-pointer-enter-option handle-blend-mode-enter
:on-pointer-enter-option handle-blend-mode-enter :on-pointer-leave-option handle-blend-mode-leave}]]
:on-pointer-leave-option handle-blend-mode-leave}]] [:div {:class (stl/css :input)
[:div {:class (stl/css :input) :title (tr "workspace.options.opacity")}
:title (tr "workspace.options.opacity")} [:span {:class (stl/css :icon)} "%"]
[:span {:class (stl/css :icon)} "%"] [:> numeric-input*
[:> numeric-input* {:value (opacity->string current-opacity)
{:value (opacity->string current-opacity) :placeholder (tr "settings.multiple")
:placeholder (tr "settings.multiple") :on-change handle-opacity-change
:on-change handle-opacity-change :min 0
:min 0 :max 100
:max 100 :className (stl/css :numeric-input)}]]
:className (stl/css :numeric-input)}]]
[:div {:class (stl/css :actions)} [:div {:class (stl/css :actions)}
(cond (cond
(or (= :multiple hidden?) (not hidden?)) (or (= :multiple hidden?) (not hidden?))
[:button {:on-click handle-set-hidden [:button {:on-click handle-set-hidden
:class (stl/css :hidden-btn)} i/shown-refactor] :class (stl/css :hidden-btn)} i/shown-refactor]
:else :else
[:button {:on-click handle-set-visible [:button {:on-click handle-set-visible
:class (stl/css :hidden-btn)} i/hide-refactor]) :class (stl/css :hidden-btn)} i/hide-refactor])
(cond (cond
(or (= :multiple blocked?) (not blocked?)) (or (= :multiple blocked?) (not blocked?))
[:button {:on-click handle-set-blocked [:button {:on-click handle-set-blocked
:class (stl/css :lock-btn)} i/unlock-refactor] :class (stl/css :lock-btn)} i/unlock-refactor]
:else :else
[:button {:on-click handle-set-unblocked [:button {:on-click handle-set-unblocked
:class (stl/css-case :lock-btn true :class (stl/css-case :lock-btn true
:locked blocked?)} i/lock-refactor])]]] :locked blocked?)} i/lock-refactor])]]]))
[:div.element-set
[:div.element-set-title
[:span
(case type
:multiple (tr "workspace.options.layer-options.title.multiple")
:group (tr "workspace.options.layer-options.title.group")
(tr "workspace.options.layer-options.title"))]]
[:div.element-set-content
[:div.row-flex
[:& select
{:class "flex-grow no-check"
:default-value selected-blend-mode
:options options
:on-change handle-change-blend-mode
:is-open? option-highlighted?
:on-pointer-enter-option handle-blend-mode-enter
:on-pointer-leave-option handle-blend-mode-leave}]
[:div.input-element {:title (tr "workspace.options.opacity")
:class "percentail"}
[:> numeric-input*
{:value (opacity->string current-opacity)
:placeholder (tr "settings.multiple")
:on-change handle-opacity-change
:min 0
:max 100}]]
[:div.element-set-actions.layer-actions
(cond
(or (= :multiple hidden?) (not hidden?))
[:div.element-set-actions-button {:on-click handle-set-hidden} i/eye]
:else
[:div.element-set-actions-button {:on-click handle-set-visible} i/eye-closed])
(cond
(or (= :multiple blocked?) (not blocked?))
[:div.element-set-actions-button {:on-click handle-set-blocked} i/unlock]
:else
[:div.element-set-actions-button {:on-click handle-set-unblocked} i/lock])]]]])))

View file

@ -8,48 +8,48 @@
.element-set { .element-set {
margin-bottom: $s-8; margin-bottom: $s-8;
.element-set-content { }
.element-set-content {
display: flex;
height: $s-32;
gap: $s-4;
.select {
width: $s-124;
padding: 0;
}
.input {
@extend .input-element;
width: $s-60;
}
.actions {
display: flex; display: flex;
height: $s-32;
gap: $s-4; gap: $s-4;
.select { .hidden-btn,
width: $s-124; .lock-btn {
padding: 0; @extend .button-tertiary;
border-radius: $br-8;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
}
&.hidden {
.hidden-select {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
} }
.input { .input {
@extend .input-element; @include hiddenElement;
width: $s-60; border: $s-1 solid var(--input-border-color-disabled);
} .icon {
.actions { stroke: var(--input-foreground-color-disabled);
display: flex;
gap: $s-4;
.hidden-btn,
.lock-btn {
@extend .button-tertiary;
border-radius: $br-8;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
} }
} .numeric-input {
color: var(--input-foreground-color-disabled);
&.hidden {
.hidden-select {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
}
.input {
@include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled);
.icon {
stroke: var(--input-foreground-color-disabled);
}
.numeric-input {
color: var(--input-foreground-color-disabled);
}
} }
} }
} }

View file

@ -174,7 +174,7 @@
.grid-layout-menu-title { .grid-layout-menu-title {
flex: 1; flex: 1;
font-size: $fs-11; font-size: $fs-11;
color: $df-primary; color: var(--title-foreground-color-hover);
} }
.edit-mode-btn { .edit-mode-btn {
@ -246,9 +246,6 @@
border-right: $s-1 solid var(--panel-background-color); border-right: $s-1 solid var(--panel-background-color);
} }
.track-info-unit {
}
.track-info-unit-selector { .track-info-unit-selector {
border-radius: 0 $br-8 $br-8 0; border-radius: 0 $br-8 $br-8 0;
width: $s-96; width: $s-96;

View file

@ -17,9 +17,8 @@
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon get-layout-flex-icon-refactor]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -40,8 +39,7 @@
(mf/defc margin-section (mf/defc margin-section
[{:keys [values change-margin-style on-margin-change] :as props}] [{:keys [values change-margin-style on-margin-change] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [margin-type (or (:layout-item-margin-type values) :simple)
margin-type (or (:layout-item-margin-type values) :simple)
m1 (when (and (not (= :multiple (:layout-item-margin values))) m1 (when (and (not (= :multiple (:layout-item-margin values)))
(= (dm/get-in values [:layout-item-margin :m1]) (= (dm/get-in values [:layout-item-margin :m1])
(dm/get-in values [:layout-item-margin :m3]))) (dm/get-in values [:layout-item-margin :m3])))
@ -63,158 +61,99 @@
;;on destroy component ;;on destroy component
(select-margins false false false false)))) (select-margins false false false false))))
(if new-css-system [:div {:class (stl/css :margin-row)}
[:div {:class (stl/css :margin-row)} [:div {:class (stl/css :inputs-wrapper)}
[:div {:class (stl/css :inputs-wrapper)} (cond
(cond (= margin-type :simple)
(= margin-type :simple) [:div {:class (stl/css :margin-simple)}
[:div {:class (stl/css :margin-simple)} [:div {:class (stl/css :vertical-margin)
[:div {:class (stl/css :vertical-margin) :title "Vertical margin"}
:title "Vertical margin"} [:span {:class (stl/css :icon)}
[:span {:class (stl/css :icon)} i/margin-top-bottom-refactor]
i/margin-top-bottom-refactor] [:> numeric-input* {:className (stl/css :numeric-input)
[:> numeric-input* {:className (stl/css :numeric-input) :placeholder "--"
:placeholder "--" :nillable true
:nillable true :value m1
:value m1 :on-focus (fn [event]
:on-focus (fn [event] (select-margins true false true false)
(select-margins true false true false) (dom/select-target event))
(dom/select-target event)) :on-change (partial on-margin-change :simple :m1)
:on-change (partial on-margin-change :simple :m1) :on-blur #(select-margins false false false false)}]]
:on-blur #(select-margins false false false false)}]]
[:div {:class (stl/css :horizontal-margin) [:div {:class (stl/css :horizontal-margin)
:title "Horizontal margin"} :title "Horizontal margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-left-right-refactor] i/margin-left-right-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :on-focus (fn [event]
(select-margins false true false true) (select-margins false true false true)
(dom/select-target event)) (dom/select-target event))
:on-change (partial on-margin-change :simple :m2) :on-change (partial on-margin-change :simple :m2)
:on-blur #(select-margins false false false false) :on-blur #(select-margins false false false false)
:nillable true :nillable true
:value m2}]]] :value m2}]]]
(= margin-type :multiple) (= margin-type :multiple)
[:div {:class (stl/css :margin-multiple)} [:div {:class (stl/css :margin-multiple)}
[:div {:class (stl/css :top-margin) [:div {:class (stl/css :top-margin)
:title "Top margin"} :title "Top margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-top-refactor] i/margin-top-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :on-focus (fn [event]
(select-margin :m1) (select-margin :m1)
(dom/select-target event)) (dom/select-target event))
:on-change (partial on-margin-change :multiple :m1) :on-change (partial on-margin-change :multiple :m1)
:on-blur #(select-margins false false false false) :on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m1 (:layout-item-margin values))}]] :value (:m1 (:layout-item-margin values))}]]
[:div {:class (stl/css :right-margin) [:div {:class (stl/css :right-margin)
:title "Right margin"} :title "Right margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-right-refactor] i/margin-right-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :on-focus (fn [event]
(select-margin :m2) (select-margin :m2)
(dom/select-target event)) (dom/select-target event))
:on-change (partial on-margin-change :multiple :m2) :on-change (partial on-margin-change :multiple :m2)
:on-blur #(select-margins false false false false) :on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m2 (:layout-item-margin values))}]] :value (:m2 (:layout-item-margin values))}]]
[:div {:class (stl/css :bottom-margin) [:div {:class (stl/css :bottom-margin)
:title "Bottom margin"} :title "Bottom margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-bottom-refactor] i/margin-bottom-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :on-focus (fn [event]
(select-margin :m3) (select-margin :m3)
(dom/select-target event)) (dom/select-target event))
:on-change (partial on-margin-change :multiple :m3) :on-change (partial on-margin-change :multiple :m3)
:on-blur #(select-margins false false false false) :on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m3 (:layout-item-margin values))}]] :value (:m3 (:layout-item-margin values))}]]
[:div {:class (stl/css :left-margin) [:div {:class (stl/css :left-margin)
:title "Left margin"} :title "Left margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-left-refactor] i/margin-left-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :on-focus (fn [event]
(select-margin :m4) (select-margin :m4)
(dom/select-target event)) (dom/select-target event))
:on-change (partial on-margin-change :multiple :m4) :on-change (partial on-margin-change :multiple :m4)
:on-blur #(select-margins false false false false) :on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m4 (:layout-item-margin values))}]]])] :value (:m4 (:layout-item-margin values))}]]])]
[:button {:class (stl/css-case :margin-mode true [:button {:class (stl/css-case :margin-mode true
:selected (= margin-type :multiple)) :selected (= margin-type :multiple))
:title "Margin - multiple" :title "Margin - multiple"
:on-click #(change-margin-style (if (= margin-type :multiple) :simple :multiple))} :on-click #(change-margin-style (if (= margin-type :multiple) :simple :multiple))}
i/margin-refactor]] i/margin-refactor]]))
[:div.margin-row
(cond
(= margin-type :simple)
[:div.margin-item-group
[:div.margin-item.tooltip.tooltip-bottom-left
{:alt "Vertical margin"}
[:span.icon i/auto-margin-both-sides]
[:> numeric-input*
{:placeholder "--"
:on-focus (fn [event]
(select-margins true false true false)
(dom/select-target event))
:on-change (partial on-margin-change :simple :m1)
:on-blur #(select-margins false false false false)
:nillable true
:value m1}]]
[:div.margin-item.tooltip.tooltip-bottom-left
{:alt "Horizontal margin"}
[:span.icon.rotated i/auto-margin-both-sides]
[:> numeric-input*
{:placeholder "--"
:on-focus (fn [event]
(select-margins false true false true)
(dom/select-target event))
:on-change (partial on-margin-change :simple :m2)
:on-blur #(select-margins false false false false)
:nillable true
:value m2}]]]
(= margin-type :multiple)
[:div.wrapper
(for [num [:m1 :m2 :m3 :m4]]
[:div.tooltip.tooltip-bottom
{:key (dm/str "margin-" (d/name num))
:alt (case num
:m1 "Top"
:m2 "Right"
:m3 "Bottom"
:m4 "Left")}
[:div.input-element.auto
[:> numeric-input*
{:placeholder "--"
:on-focus (fn [event]
(select-margin num)
(dom/select-target event))
:on-change (partial on-margin-change :multiple num)
:on-blur #(select-margins false false false false)
:nillable true
:value (num (:layout-item-margin values))}]]])])
[:div.margin-item-icons
[:div.margin-item-icon.tooltip.tooltip-bottom-left
{:class (dom/classnames :selected (= margin-type :multiple))
:alt "Margin - multiple"
:on-click #(change-margin-style (if (= margin-type :multiple) :simple :multiple))}
i/auto-margin]]])))
(mf/defc element-behaviour-horizontal (mf/defc element-behaviour-horizontal
[{:keys [auto? fill? layout-item-sizing on-change] :as props}] [{:keys [auto? fill? layout-item-sizing on-change] :as props}]
@ -270,112 +209,46 @@
:id "behaviour-v-auto"}])]]) :id "behaviour-v-auto"}])]])
(mf/defc element-behaviour (mf/defc element-behaviour
[{:keys [auto? fill? layout-item-h-sizing layout-item-v-sizing on-change-behaviour-h-refactor on-change-behaviour-v-refactor on-change] :as props}] [{:keys [auto?
(let [new-css-system (mf/use-ctx ctx/new-css-system)] fill?
layout-item-h-sizing
(if new-css-system layout-item-v-sizing
[:div {:class (stl/css-case :behaviour-menu true on-change-behaviour-h-refactor
:wrap (and fill? auto?))} on-change-behaviour-v-refactor] :as props}]
[:& element-behaviour-horizontal {:auto? auto? [:div {:class (stl/css-case :behaviour-menu true
:fill? fill? :wrap (and fill? auto?))}
:layout-item-sizing layout-item-h-sizing [:& element-behaviour-horizontal {:auto? auto?
:on-change on-change-behaviour-h-refactor}] :fill? fill?
[:& element-behaviour-vertical {:auto? auto? :layout-item-sizing layout-item-h-sizing
:fill? fill? :on-change on-change-behaviour-h-refactor}]
:layout-item-sizing layout-item-v-sizing [:& element-behaviour-vertical {:auto? auto?
:on-change on-change-behaviour-v-refactor}]] :fill? fill?
:layout-item-sizing layout-item-v-sizing
[:div.btn-wrapper :on-change on-change-behaviour-v-refactor}]])
{:class (when (and fill? auto?) "wrap")}
[:div.layout-behavior.horizontal
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fix width"
:class (dom/classnames :active (= layout-item-h-sizing :fix))
:data-direction :h
:data-value :fix
:on-click on-change}
i/auto-fix-layout]
(when fill?
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Width 100%"
:class (dom/classnames :active (= layout-item-h-sizing :fill))
:data-direction :h
:data-value :fill
:on-click on-change}
i/auto-fill])
(when auto?
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fit content"
:class (dom/classnames :active (= layout-item-h-sizing :auto))
:data-direction :h
:data-value :auto
:on-click on-change}
i/auto-hug])]
[:div.layout-behavior
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fix height"
:class (dom/classnames :active (= layout-item-v-sizing :fix))
:data-direction :v
:data-value :fix
:on-click on-change}
i/auto-fix-layout]
(when fill?
[:button.behavior-btn.tooltip.tooltip-bottom-left
{:alt "Height 100%"
:class (dom/classnames :active (= layout-item-v-sizing :fill))
:data-direction :v
:data-value :fill
:on-click on-change}
i/auto-fill])
(when auto?
[:button.behavior-btn.tooltip.tooltip-bottom-left
{:alt "Fit content"
:class (dom/classnames :active (= layout-item-v-sizing :auto))
:data-direction :v
:data-value :auto
:on-click on-change}
i/auto-hug])]])))
(mf/defc align-self-row (mf/defc align-self-row
[{:keys [is-col? align-self on-change] :as props}] [{:keys [is-col? align-self on-change] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) [:& radio-buttons {:selected (d/name align-self)
dir-v [:start :center :end #_:stretch #_:baseline]] :on-change on-change
(if new-css-system :name "flex-align-self"}
[:& radio-buttons {:selected (d/name align-self) [:& radio-button {:value "start"
:on-change on-change :icon (get-layout-flex-icon :align-self :start is-col?)
:name "flex-align-self"} :title "Align self start"
[:& radio-button {:value "start" :id "align-self-start"}]
:icon (get-layout-flex-icon-refactor :align-self :start is-col?) [:& radio-button {:value "center"
:title "Align self start" :icon (get-layout-flex-icon :align-self :center is-col?)
:id "align-self-start"}] :title "Align self center"
[:& radio-button {:value "center" :id "align-self-center"}]
:icon (get-layout-flex-icon-refactor :align-self :center is-col?) [:& radio-button {:value "end"
:title "Align self center" :icon (get-layout-flex-icon :align-self :end is-col?)
:id "align-self-center"}] :title "Align self end"
[:& radio-button {:value "end" :id "align-self-end"}]])
:icon (get-layout-flex-icon-refactor :align-self :end is-col?)
:title "Align self end"
:id "align-self-end"}]]
[:div.align-self-style
(for [align dir-v]
[:button.align-self.tooltip.tooltip-bottom
{:class (dom/classnames :active (= align-self align)
:tooltip-bottom-left (not= align :start)
:tooltip-bottom (= align :start))
:alt (dm/str "Align self " (d/name align))
:data-value align
:on-click on-change
:key (str "align-self" align)}
(get-layout-flex-icon :align-self align is-col?)])])))
(mf/defc layout-item-menu (mf/defc layout-item-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "is-layout-child?" "is-grid-parent?" "is-flex-parent?"]))]} {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "is-layout-child?" "is-grid-parent?" "is-flex-parent?"]))]}
[{:keys [ids values is-layout-child? is-layout-container? is-grid-parent? is-flex-parent?] :as props}] [{:keys [ids values is-layout-child? is-layout-container? is-grid-parent? is-flex-parent?] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
selection-parents (mf/deref selection-parents-ref) selection-parents (mf/deref selection-parents-ref)
is-absolute? (:layout-item-absolute values) is-absolute? (:layout-item-absolute values)
@ -408,17 +281,6 @@
"Layout element") "Layout element")
set-align-self set-align-self
(mf/use-fn
(mf/deps ids align-self)
(fn [event]
(let [value (-> (dom/get-current-target event)
(dom/get-data "value")
(d/read-string))]
(if (= align-self value)
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil}))
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))))
set-align-self-refactor
(mf/use-fn (mf/use-fn
(mf/deps ids align-self) (mf/deps ids align-self)
(fn [value] (fn [value]
@ -464,7 +326,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(let [value (if new-css-system (keyword value) value)] (let [value (keyword value)]
(st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value})))))
@ -472,7 +334,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(let [value (if new-css-system (keyword value) value)] (let [value (keyword value)]
(st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value})))))
;; Size and position ;; Size and position
@ -485,7 +347,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(let [value (if new-css-system (keyword value) value)] (let [value (keyword value)]
(when (= value :static) (when (= value :static)
(st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil})))
(st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)})))))
@ -498,19 +360,18 @@
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout-child ids {:layout-item-z-index value}))))] (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index value}))))]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-content?
[:& title-bar {:collapsable? has-content? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title title
:title title :class (stl/css-case :title-spacing-layout-element true
:class (stl/css-case :title-spacing-layout-element true :title-spacing-empty (not has-content?))}]]
:title-spacing-empty (not has-content?))}]] (when open?
(when open? [:div {:class (stl/css :flex-element-menu)}
[:div {:class (stl/css :flex-element-menu)} (when (or is-layout-child? is-absolute?)
(when (or is-layout-child? is-absolute?) [:div {:class (stl/css :row)}
[:div {:class (stl/css :row)}
[:div {:class (stl/css :position-options)} [:div {:class (stl/css :position-options)}
[:& radio-buttons {:selected (if is-absolute? "absolute" "static") [:& radio-buttons {:selected (if is-absolute? "absolute" "static")
:on-change on-change-position :on-change on-change-position
@ -535,187 +396,93 @@
:nillable true :nillable true
:value (:layout-item-z-index values)}]])]) :value (:layout-item-z-index values)}]])])
[:div {:class (stl/css :row)}
[:& element-behaviour {:fill? is-layout-child?
:auto? is-layout-container?
:layout-item-v-sizing (or (:layout-item-v-sizing values) :fix)
:layout-item-h-sizing (or (:layout-item-h-sizing values) :fix)
:on-change-behaviour-h-refactor on-change-behaviour-h
:on-change-behaviour-v-refactor on-change-behaviour-v
:on-change on-change-behaviour}]]
(when (and is-layout-child? is-flex-parent?)
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& element-behaviour {:fill? is-layout-child? [:& align-self-row {:is-col? is-col?
:auto? is-layout-container? :align-self align-self
:layout-item-v-sizing (or (:layout-item-v-sizing values) :fix) :on-changer set-align-self}]])
:layout-item-h-sizing (or (:layout-item-h-sizing values) :fix)
:on-change-behaviour-h-refactor on-change-behaviour-h
:on-change-behaviour-v-refactor on-change-behaviour-v
:on-change on-change-behaviour}]]
(when (and is-layout-child? is-flex-parent?) (when is-layout-child?
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& align-self-row {:is-col? is-col?
:align-self align-self
:on-changer set-align-self-refactor}]])
(when is-layout-child?
[:div {:class (stl/css :row)}
[:& margin-section {:values values
:change-margin-style change-margin-style
:on-margin-change on-margin-change}]])
(when (or (= (:layout-item-h-sizing values) :fill)
(= (:layout-item-v-sizing values) :fill))
[:div {:class (stl/css :row)}
[:div {:class (stl/css :advanced-options)}
(when (= (:layout-item-h-sizing values) :fill)
[:div {:class (stl/css :horizontal-fill)}
[:div {:class (stl/css :layout-item-min-w)
:title (tr "workspace.options.layout-item.layout-item-min-w")}
[:span {:class (stl/css :icon-text)}
"MIN W"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-min-w)
:value (get values :layout-item-min-w)
:nillable true}]]
[:div {:class (stl/css :layout-item-max-w)
:title (tr "workspace.options.layout-item.layout-item-max-w")}
[:span {:class (stl/css :icon-text)}
"MAX W"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-max-w)
:value (get values :layout-item-max-w)
:nillable true}]]])
(when (= (:layout-item-v-sizing values) :fill)
[:div {:class (stl/css :vertical-fill)}
[:div {:class (stl/css :layout-item-min-h)
:title (tr "workspace.options.layout-item.layout-item-min-h")}
[:span {:class (stl/css :icon-text)}
"MIN H"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-min-h)
:value (get values :layout-item-min-h)
:nillable true}]]
[:div {:class (stl/css :layout-item-max-h)
:title (tr "workspace.options.layout-item.layout-item-max-h")}
[:span {:class (stl/css :icon-text)}
"MAX H"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-max-h)
:value (get values :layout-item-max-h)
:nillable true}]]])]])])]
[:div.element-set
[:div.element-set-title
[:span (cond
(and is-layout-container? (not is-layout-child?))
"Flex board"
is-flex-parent?
"Flex element"
is-grid-parent?
"Grid element"
:else
"Layout element")]]
[:div.element-set-content.layout-item-menu
(when (or is-layout-child? is-absolute?)
[:div.layout-row
[:div.row-title.sizing "Position"]
[:div.btn-wrapper
[:div.absolute
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Static"
:class (dom/classnames :active (not (:layout-item-absolute values)))
:on-click #(on-change-position :static)}
"Static"]
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Absolute"
:class (dom/classnames :active (and (:layout-item-absolute values) (not= :multiple (:layout-item-absolute values))))
:on-click #(on-change-position :absolute)}
"Absolute"]]
[:div.tooltip.tooltip-bottom-left.z-index {:alt "z-index"}
i/layers
[:> numeric-input*
{:placeholder "--"
:on-focus #(dom/select-target %)
:on-change #(on-change-z-index %)
:nillable true
:value (:layout-item-z-index values)}]]]])
[:*
[:div.layout-row
[:div.row-title.sizing "Sizing"]
[:& element-behaviour {:fill? is-layout-child?
:auto? is-layout-container?
:layout-item-v-sizing (or (:layout-item-v-sizing values) :fix)
:layout-item-h-sizing (or (:layout-item-h-sizing values) :fix)
:on-change-behaviour-h-refactor on-change-behaviour-h
:on-change-behaviour-v-refactor on-change-behaviour-v
:on-change on-change-behaviour}]]
(when (and is-layout-child? is-flex-parent?)
[:div.layout-row
[:div.row-title "Align"]
[:div.btn-wrapper
[:& align-self-row {:is-col? is-col?
:align-self align-self
:on-change set-align-self}]]])
(when is-layout-child?
[:& margin-section {:values values [:& margin-section {:values values
:change-margin-style change-margin-style :change-margin-style change-margin-style
:on-margin-change on-margin-change}]) :on-margin-change on-margin-change}]])
[:div.advanced-ops-body (when (or (= (:layout-item-h-sizing values) :fill)
[:div.input-wrapper (= (:layout-item-v-sizing values) :fill))
(for [item (cond-> [] [:div {:class (stl/css :row)}
(= (:layout-item-h-sizing values) :fill) [:div {:class (stl/css :advanced-options)}
(conj :layout-item-min-w :layout-item-max-w) (when (= (:layout-item-h-sizing values) :fill)
[:div {:class (stl/css :horizontal-fill)}
[:div {:class (stl/css :layout-item-min-w)
:title (tr "workspace.options.layout-item.layout-item-min-w")}
(= (:layout-item-v-sizing values) :fill) [:span {:class (stl/css :icon-text)}
(conj :layout-item-min-h :layout-item-max-h))] "MIN W"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-min-w)
:value (get values :layout-item-min-w)
:nillable true}]]
[:div.tooltip.tooltip-bottom [:div {:class (stl/css :layout-item-max-w)
{:key (d/name item) :title (tr "workspace.options.layout-item.layout-item-max-w")}
:alt (tr (dm/str "workspace.options.layout-item.title." (d/name item))) [:span {:class (stl/css :icon-text)}
:class (dom/classnames "maxH" (= item :layout-item-max-h) "MAX W"]
"minH" (= item :layout-item-min-h) [:> numeric-input*
"maxW" (= item :layout-item-max-w) {:className (stl/css :numeric-input)
"minW" (= item :layout-item-min-w))} :no-validate true
[:div.input-element :min 0
{:alt (tr (dm/str "workspace.options.layout-item." (d/name item)))} :data-wrap true
[:> numeric-input* :placeholder "--"
{:no-validate true :on-focus #(dom/select-target %)
:min 0 :on-change (partial on-size-change :layout-item-max-w)
:data-wrap true :value (get values :layout-item-max-w)
:placeholder "--" :nillable true}]]])
:on-focus #(dom/select-target %) (when (= (:layout-item-v-sizing values) :fill)
:on-change (partial on-size-change item) [:div {:class (stl/css :vertical-fill)}
:value (get values item) [:div {:class (stl/css :layout-item-min-h)
:nillable true}]]])]]]]]))) :title (tr "workspace.options.layout-item.layout-item-min-h")}
[:span {:class (stl/css :icon-text)}
"MIN H"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-min-h)
:value (get values :layout-item-min-h)
:nillable true}]]
[:div {:class (stl/css :layout-item-max-h)
:title (tr "workspace.options.layout-item.layout-item-max-h")}
[:span {:class (stl/css :icon-text)}
"MAX H"]
[:> numeric-input*
{:className (stl/css :numeric-input)
:no-validate true
:min 0
:data-wrap true
:placeholder "--"
:on-focus #(dom/select-target %)
:on-change (partial on-size-change :layout-item-max-h)
:value (get values :layout-item-max-h)
:nillable true}]]])]])])]))

View file

@ -8,125 +8,132 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
.title-spacing-layout-element {
margin: 0 0 $s-4 0; .title-spacing-layout-element {
} margin: 0 0 $s-4 0;
.title-spacing-empty { }
padding-left: $s-2;
} .title-spacing-empty {
padding-left: $s-2;
}
.flex-element-menu {
@include flexColumn;
gap: $s-12;
}
.behaviour-menu {
display: flex;
gap: $s-4;
}
.horizontal-behaviour {
&.one-element {
width: $s-28;
} }
.flex-element-menu { &.two-element {
@include flexColumn; width: $s-60;
gap: $s-12; }
&.three-element {
width: $s-92;
}
}
.behaviour-menu { .vertical-behaviour {
display: flex; .rotated {
gap: $s-4; transform: rotate(90deg);
.horizontal-behaviour { }
&.one-element { &.one-element {
width: $s-28; width: $s-28;
} }
&.two-element { &.two-element {
width: $s-60; width: $s-60;
} }
&.three-element { &.three-element {
width: $s-92; width: $s-92;
} }
} }
.vertical-behaviour {
.rotated {
transform: rotate(90deg);
}
&.one-element {
width: $s-28;
}
&.two-element {
width: $s-60;
}
&.three-element {
width: $s-92;
}
}
}
.z-index-wrapper { .z-index-wrapper {
@extend .input-element; @extend .input-element;
width: $s-60; width: $s-60;
} }
.row { .row {
display: flex; display: flex;
gap: $s-4; gap: $s-4;
} }
.position-options { .position-options {
width: $s-188; width: $s-188;
} }
.margin-row { .margin-row {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: $s-4; gap: $s-4;
.margin-mode { }
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-tertiary-background-color-active);
color: var(--button-tertiary-foreground-color-active);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.inputs-wrapper {
.margin-simple {
display: flex;
gap: $s-4;
.vertical-margin,
.horizontal-margin {
@extend .input-element;
width: $s-108;
}
}
.margin-multiple {
display: grid;
grid-template-columns: 1fr 1fr;
gap: $s-4;
.top-margin,
.bottom-margin,
.left-margin,
.right-margin {
@extend .input-element;
width: $s-108;
}
}
}
}
.advanced-options { .margin-mode {
@include flexColumn; @extend .button-tertiary;
.horizontal-fill, height: $s-32;
.vertical-fill { width: $s-28;
display: flex; svg {
gap: $s-4; @extend .button-icon;
.layout-item-min-w, }
.layout-item-min-h, &.selected {
.layout-item-max-w, background-color: var(--button-tertiary-background-color-active);
.layout-item-max-h { color: var(--button-tertiary-foreground-color-active);
@extend .input-element; svg {
width: $s-108; stroke: var(--button-tertiary-foreground-color-active);
.icon-text {
justify-content: flex-start;
width: $s-80;
padding-top: $s-2;
}
}
}
} }
} }
} }
.margin-simple {
display: flex;
gap: $s-4;
.vertical-margin,
.horizontal-margin {
@extend .input-element;
width: $s-108;
}
}
.margin-multiple {
display: grid;
grid-template-columns: 1fr 1fr;
gap: $s-4;
}
.top-margin,
.bottom-margin,
.left-margin,
.right-margin {
@extend .input-element;
width: $s-108;
}
.advanced-options {
@include flexColumn;
}
.horizontal-fill,
.vertical-fill {
display: flex;
gap: $s-4;
}
.layout-item-min-w,
.layout-item-min-h,
.layout-item-max-w,
.layout-item-max-h {
@extend .input-element;
width: $s-108;
.icon-text {
justify-content: flex-start;
width: $s-80;
padding-top: $s-2;
}
}

View file

@ -21,7 +21,6 @@
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -75,8 +74,7 @@
{::mf/wrap-props false {::mf/wrap-props false
::mf/wrap [mf/memo]} ::mf/wrap [mf/memo]}
[{:keys [ids ids-with-children values type all-types shape]}] [{:keys [ids ids-with-children values type all-types shape]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [options (if (= type :multiple)
options (if (= type :multiple)
(reduce #(union %1 %2) (map #(get type->options %) all-types)) (reduce #(union %1 %2) (map #(get type->options %) all-types))
(get type->options type)) (get type->options type))
@ -193,16 +191,7 @@
:else :else
:vert)) :vert))
on-orientation-clicked on-orientation-change
(mf/use-fn
(mf/deps ids)
(fn [event]
(let [orientation (-> (dom/get-current-target event)
(dom/get-data "value")
(keyword))]
(st/emit! (udw/change-orientation ids orientation)))))
on-orientation-change-refactor
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [orientation] (fn [orientation]
@ -348,30 +337,29 @@
;; restore focus to the newly created numeric-input ;; restore focus to the newly created numeric-input
(let [radius-input (mf/ref-val radius-input-ref)] (let [radius-input (mf/ref-val radius-input-ref)]
(dom/focus! radius-input))))) (dom/focus! radius-input)))))
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} (when (and (options :presets)
(when (and (options :presets) (or (nil? all-types) (= (count all-types) 1)))
(or (nil? all-types) (= (count all-types) 1))) [:div {:class (stl/css :presets)}
[:div {:class (stl/css :presets)} [:div {:class (stl/css-case :presets-wrapper true
[:div {:class (stl/css-case :presets-wrapper true :opened show-presets-dropdown?)
:opened show-presets-dropdown?) :on-click open-presets}
:on-click open-presets} [:span {:class (stl/css :select-name)} (tr "workspace.options.size-presets")]
[:span {:class (stl/css :select-name)}(tr "workspace.options.size-presets")] [:span {:class (stl/css :collapsed-icon)} i/arrow-refactor]
[:span {:class (stl/css :collapsed-icon)} i/arrow-refactor]
[:& dropdown {:show show-presets-dropdown? [:& dropdown {:show show-presets-dropdown?
:on-close close-presets} :on-close close-presets}
[:ul {:class (stl/css :custom-select-dropdown)} [:ul {:class (stl/css :custom-select-dropdown)}
(for [size-preset size-presets] (for [size-preset size-presets]
(if-not (:width size-preset) (if-not (:width size-preset)
[:li {:key (:name size-preset)
:class (stl/css-case :dropdown-element true
:disabled true)}
[:span {:class (stl/css :preset-name)} (:name size-preset)]]
(let [preset-match (and (= (:width size-preset) (d/parse-integer (:width values) 0))
(= (:height size-preset) (d/parse-integer (:height values) 0)))]
[:li {:key (:name size-preset) [:li {:key (:name size-preset)
:class (stl/css-case :dropdown-element true
:disabled true)}
[:span {:class (stl/css :preset-name)} (:name size-preset)]]
(let [preset-match (and (= (:width size-preset) (d/parse-integer (:width values) 0))
(= (:height size-preset) (d/parse-integer (:height values) 0)))]
[:li {:key (:name size-preset)
:class (stl/css-case :dropdown-element true :class (stl/css-case :dropdown-element true
:match preset-match) :match preset-match)
:data-width (:width size-preset) :data-width (:width size-preset)
@ -383,366 +371,189 @@
(when preset-match (when preset-match
[:span {:class (stl/css :check-icon)} i/tick-refactor])])))]]] [:span {:class (stl/css :check-icon)} i/tick-refactor])])))]]]
[:& radio-buttons {:selected (or (d/name orientation) "") [:& radio-buttons {:selected (or (d/name orientation) "")
:on-change on-orientation-change-refactor :on-change on-orientation-change
:name "frame-otientation"} :name "frame-otientation"}
[:& radio-button {:icon i/size-vertical-refactor [:& radio-button {:icon i/size-vertical-refactor
:value "vert" :value "vert"
:id "size-vertical"}] :id "size-vertical"}]
[:& radio-button {:icon i/size-horizontal-refactor [:& radio-button {:icon i/size-horizontal-refactor
:value "horiz" :value "horiz"
:id "size-horizontal"}]]]) :id "size-horizontal"}]]])
(when (options :size) (when (options :size)
[:div {:class (stl/css :size)} [:div {:class (stl/css :size)}
[:div {:class (stl/css-case :width true [:div {:class (stl/css-case :width true
:disabled disabled-width-sizing?) :disabled disabled-width-sizing?)
:title (tr "workspace.options.width")} :title (tr "workspace.options.width")}
[:span {:class (stl/css :icon-text)} "W"] [:span {:class (stl/css :icon-text)} "W"]
[:> numeric-input* {:min 0.01 [:> numeric-input* {:min 0.01
:no-validate true :no-validate true
:placeholder "--" :placeholder "--"
:on-change on-width-change :on-change on-width-change
:disabled disabled-width-sizing? :disabled disabled-width-sizing?
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (:width values)}]] :value (:width values)}]]
[:div {:class (stl/css-case :height true [:div {:class (stl/css-case :height true
:disabled disabled-height-sizing?) :disabled disabled-height-sizing?)
:title (tr "workspace.options.height")} :title (tr "workspace.options.height")}
[:span {:class (stl/css :icon-text)} "H"] [:span {:class (stl/css :icon-text)} "H"]
[:> numeric-input* {:min 0.01 [:> numeric-input* {:min 0.01
:no-validate true :no-validate true
:placeholder "--" :placeholder "--"
:on-change on-height-change :on-change on-height-change
:disabled disabled-height-sizing? :disabled disabled-height-sizing?
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (:height values)}]] :value (:height values)}]]
[:button {:class (stl/css-case [:button {:class (stl/css-case
:lock-size-btn true :lock-size-btn true
:selected (true? proportion-lock) :selected (true? proportion-lock)
:disabled (= proportion-lock :multiple)) :disabled (= proportion-lock :multiple))
:on-click on-proportion-lock-change} :on-click on-proportion-lock-change}
(if proportion-lock (if proportion-lock
i/lock-refactor i/lock-refactor
i/unlock-refactor)]]) i/unlock-refactor)]])
(when (options :position) (when (options :position)
[:div {:class (stl/css :position)} [:div {:class (stl/css :position)}
[:div {:class (stl/css-case :x-position true [:div {:class (stl/css-case :x-position true
:disabled disabled-position-x?) :disabled disabled-position-x?)
:title (tr "workspace.options.x")} :title (tr "workspace.options.x")}
[:span {:class (stl/css :icon-text)} "X"] [:span {:class (stl/css :icon-text)} "X"]
[:> numeric-input* {:no-validate true [:> numeric-input* {:no-validate true
:placeholder "--" :placeholder "--"
:on-change on-pos-x-change :on-change on-pos-x-change
:disabled disabled-position-x? :disabled disabled-position-x?
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (:x values)}]] :value (:x values)}]]
[:div {:class (stl/css-case :y-position true [:div {:class (stl/css-case :y-position true
:disabled disabled-position-y?) :disabled disabled-position-y?)
:title (tr "workspace.options.y")} :title (tr "workspace.options.y")}
[:span {:class (stl/css :icon-text)} "Y"] [:span {:class (stl/css :icon-text)} "Y"]
[:> numeric-input* {:no-validate true [:> numeric-input* {:no-validate true
:placeholder "--" :placeholder "--"
:disabled disabled-position-y? :disabled disabled-position-y?
:on-change on-pos-y-change :on-change on-pos-y-change
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (:y values)}]]]) :value (:y values)}]]])
(when (or (options :rotation) (options :radius)) (when (or (options :rotation) (options :radius))
[:div {:class (stl/css :rotation-radius)} [:div {:class (stl/css :rotation-radius)}
(when (options :rotation) (when (options :rotation)
[:div {:class (stl/css :rotation) [:div {:class (stl/css :rotation)
:title (tr "workspace.options.rotation")} :title (tr "workspace.options.rotation")}
[:span {:class (stl/css :icon)} i/rotation-refactor] [:span {:class (stl/css :icon)} i/rotation-refactor]
[:> numeric-input* [:> numeric-input*
{:no-validate true {:no-validate true
:min 0 :min 0
:max 359 :max 359
:data-wrap true :data-wrap true
:placeholder "--" :placeholder "--"
:on-change on-rotation-change :on-change on-rotation-change
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (:rotation values)}]]) :value (:rotation values)}]])
(when (options :radius)
[:div {:class (stl/css :radius)}
[:div {:class (stl/css :radius-inputs)}
(cond
(= radius-mode :radius-1)
[:div {:class (stl/css :radius-1)
:title (tr "workspace.options.radius")}
[:span {:class (stl/css :icon)} i/corner-radius-refactor]
[:> numeric-input*
{:placeholder "Mixed"
:ref radius-input-ref
:min 0
:on-change on-radius-1-change
:className (stl/css :numeric-input)
:value (:rx values)}]]
@radius-multi?
[:div {:class (stl/css :radius-1)
:title (tr "workspace.options.radius")}
[:span {:class (stl/css :icon)} i/corner-radius-refactor]
[:input.input-text
{:type "number"
:placeholder "Mixed"
:min 0
:on-change on-radius-multi-change
:className (stl/css :numeric-input)
:value (if all-equal? (:rx values) nil)}]]
(= radius-mode :radius-4)
[:div {:class (stl/css :radius-4)}
[:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-top-left")}
[:> numeric-input*
{:placeholder "--"
:min 0
:on-change on-radius-r1-change
:className (stl/css :numeric-input)
:value (:r1 values)}]]
[:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-top-right")}
[:> numeric-input*
{:placeholder "--"
:min 0
:on-change on-radius-r2-change
:className (stl/css :numeric-input)
:value (:r2 values)}]]
[:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-bottom-left")}
[:> numeric-input*
{:placeholder "--"
:min 0
:on-change on-radius-r4-change
:className (stl/css :numeric-input)
:value (:r4 values)}]]
[:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-bottom-right")}
[:> numeric-input*
{:placeholder "--"
:min 0
:on-change on-radius-r3-change
:className (stl/css :numeric-input)
:value (:r3 values)}]]
])]
[:button {:class (stl/css-case :radius-mode true
:selected (= radius-mode :radius-4))
:title (if(= radius-mode :radius-4)
(tr "workspace.options.radius.all-corners")
(tr "workspace.options.radius.single-corners"))
:on-click toggle-radius-mode}
i/corner-radius-refactor]])])
(when (or (options :clip-content) (options :show-in-viewer))
[:div {:class (stl/css :clip-show)}
(when (options :clip-content)
[:div {:class (stl/css :clip-content)}
[:input {:type "checkbox"
:id "clip-content"
:ref clip-content-ref
:class (stl/css :clip-content-input)
:checked (not (:show-content values))
:on-change on-change-clip-content}]
[:label {:for "clip-content"
:title (tr "workspace.options.clip-content")
:class (stl/css-case :clip-content-label true
:selected (not (:show-content values)))}
[:span {:class (stl/css :icon)}
i/clip-content-refactor]
]])
(when (options :show-in-viewer)
[:div {:class (stl/css :clip-content)}
[:input {:type "checkbox"
:id "show-in-viewer"
:ref show-in-viewer-ref
:class (stl/css :clip-content-input)
:checked (not (:hide-in-viewer values))
:on-change on-change-show-in-viewer}]
[:label {:for "show-in-viewer"
:title (tr "workspace.options.show-in-viewer")
:class (stl/css-case :clip-content-label true
:selected (not (:hide-in-viewer values)))}
[:span {:class (stl/css :icon)}
i/play-refactor]]])])]
[:*
[:div.element-set
[:div.element-set-content
;; FRAME PRESETS
(when (and (options :presets)
(or (nil? all-types) (= (count all-types) 1))) ;; Don't show presets if multi selected
[:div.row-flex ;; some frames and some non frames
[:div.presets.custom-select.flex-grow {:class (when show-presets-dropdown? "opened")
:on-click open-presets}
[:span (tr "workspace.options.size-presets")]
[:span.dropdown-button i/arrow-down]
[:& dropdown {:show show-presets-dropdown?
:on-close close-presets}
[:ul.custom-select-dropdown
(for [size-preset size-presets]
(if-not (:width size-preset)
[:li.dropdown-label {:key (:name size-preset)}
[:span (:name size-preset)]]
[:li {:key (:name size-preset)
:data-width (:width size-preset)
:data-height (:height size-preset)
:on-click on-preset-selected}
(:name size-preset)
[:span (:width size-preset) " x " (:height size-preset)]]))]]]
[:span.orientation-icon {:data-value :vert
:on-click on-orientation-clicked} i/size-vert]
[:span.orientation-icon {:data-value :horiz
:on-click on-orientation-clicked} i/size-horiz]])
;; WIDTH & HEIGHT
(when (options :size)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.size")]
[:div.input-element.width {:title (tr "workspace.options.width")}
[:> numeric-input* {:min 0.01
:no-validate true
:placeholder "--"
:on-change on-width-change
:disabled disabled-width-sizing?
:value (:width values)}]]
[:div.input-element.height {:title (tr "workspace.options.height")}
[:> numeric-input* {:min 0.01
:no-validate true
:placeholder "--"
:on-change on-height-change
:disabled disabled-height-sizing?
:value (:height values)}]]
[:div.lock-size {:class (dom/classnames
:selected (true? proportion-lock)
:disabled (= proportion-lock :multiple))
:on-click on-proportion-lock-change}
(if proportion-lock
i/lock
i/unlock)]])
;; POSITION
(when (options :position)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.position")]
[:div.input-element.Xaxis {:title (tr "workspace.options.x")}
[:> numeric-input* {:no-validate true
:placeholder "--"
:on-change on-pos-x-change
:disabled disabled-position-x?
:value (:x values)}]]
[:div.input-element.Yaxis {:title (tr "workspace.options.y")}
[:> numeric-input* {:no-validate true
:placeholder "--"
:disabled disabled-position-y?
:on-change on-pos-y-change
:value (:y values)}]]])
;; ROTATION
(when (options :rotation)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.rotation")]
[:div.input-element.degrees {:title (tr "workspace.options.rotation")}
[:> numeric-input*
{:no-validate true
:min 0
:max 359
:data-wrap true
:placeholder "--"
:on-change on-rotation-change
:value (:rotation values)}]]])
;; RADIUS
(when (options :radius)
[:div.row-flex
[:div.radius-options
[:div.radius-icon.tooltip.tooltip-bottom
{:class (dom/classnames
:selected (or (= radius-mode :radius-1) @radius-multi?))
:alt (tr "workspace.options.radius.all-corners")
:on-click on-switch-to-radius-1}
i/radius-1]
[:div.radius-icon.tooltip.tooltip-bottom
{:class (dom/classnames
:selected (and (= radius-mode :radius-4) (not @radius-multi?)))
:alt (tr "workspace.options.radius.single-corners")
:on-click on-switch-to-radius-4}
i/radius-4]]
(when (options :radius)
[:div {:class (stl/css :radius)}
[:div {:class (stl/css :radius-inputs)}
(cond (cond
(= radius-mode :radius-1) (= radius-mode :radius-1)
[:div.input-element.mini {:title (tr "workspace.options.radius")} [:div {:class (stl/css :radius-1)
:title (tr "workspace.options.radius")}
[:span {:class (stl/css :icon)} i/corner-radius-refactor]
[:> numeric-input* [:> numeric-input*
{:placeholder "--" {:placeholder "Mixed"
:ref radius-input-ref :ref radius-input-ref
:min 0 :min 0
:on-change on-radius-1-change :on-change on-radius-1-change
:className (stl/css :numeric-input)
:value (:rx values)}]] :value (:rx values)}]]
@radius-multi? @radius-multi?
[:div.input-element.mini {:title (tr "workspace.options.radius")} [:div {:class (stl/css :radius-1)
:title (tr "workspace.options.radius")}
[:span {:class (stl/css :icon)} i/corner-radius-refactor]
[:input.input-text [:input.input-text
{:type "number" {:type "number"
:placeholder "--" :placeholder "Mixed"
:min 0 :min 0
:on-change on-radius-multi-change :on-change on-radius-multi-change
:value ""}]] :className (stl/css :numeric-input)
:value (if all-equal? (:rx values) nil)}]]
(= radius-mode :radius-4) (= radius-mode :radius-4)
[:* [:div {:class (stl/css :radius-4)}
[:div.input-element.mini {:title (tr "workspace.options.radius-top-left")} [:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-top-left")}
[:> numeric-input* [:> numeric-input*
{:placeholder "--" {:placeholder "--"
:min 0 :min 0
:on-change on-radius-r1-change :on-change on-radius-r1-change
:className (stl/css :numeric-input)
:value (:r1 values)}]] :value (:r1 values)}]]
[:div.input-element.mini {:title (tr "workspace.options.radius-top-right")} [:div {:class (stl/css :small-input)
:title (tr "workspace.options.radius-top-right")}
[:> numeric-input* [:> numeric-input*
{:placeholder "--" {:placeholder "--"
:min 0 :min 0
:on-change on-radius-r2-change :on-change on-radius-r2-change
:className (stl/css :numeric-input)
:value (:r2 values)}]] :value (:r2 values)}]]
[:div.input-element.mini {:title (tr "workspace.options.radius-bottom-right")} [:div {:class (stl/css :small-input)
[:> numeric-input* :title (tr "workspace.options.radius-bottom-left")}
{:placeholder "--"
:min 0
:on-change on-radius-r3-change
:value (:r3 values)}]]
[:div.input-element.mini {:title (tr "workspace.options.radius-bottom-left")}
[:> numeric-input* [:> numeric-input*
{:placeholder "--" {:placeholder "--"
:min 0 :min 0
:on-change on-radius-r4-change :on-change on-radius-r4-change
:value (:r4 values)}]]])]) :className (stl/css :numeric-input)
(when (options :clip-content) :value (:r4 values)}]]
[:div.input-checkbox
[:input {:type "checkbox"
:id "clip-content"
:ref clip-content-ref
:checked (not (:show-content values))
:on-change on-change-clip-content}]
[:label {:for "clip-content"} [:div {:class (stl/css :small-input)
(tr "workspace.options.clip-content")]]) :title (tr "workspace.options.radius-bottom-right")}
(when (options :show-in-viewer) [:> numeric-input*
[:div.input-checkbox {:placeholder "--"
[:input {:type "checkbox" :min 0
:id "show-in-viewer" :on-change on-radius-r3-change
:ref show-in-viewer-ref :className (stl/css :numeric-input)
:checked (not (:hide-in-viewer values)) :value (:r3 values)}]]])]
:on-change on-change-show-in-viewer}] [:button {:class (stl/css-case :radius-mode true
:selected (= radius-mode :radius-4))
:title (if (= radius-mode :radius-4)
(tr "workspace.options.radius.all-corners")
(tr "workspace.options.radius.single-corners"))
:on-click toggle-radius-mode}
i/corner-radius-refactor]])])
(when (or (options :clip-content) (options :show-in-viewer))
[:div {:class (stl/css :clip-show)}
(when (options :clip-content)
[:div {:class (stl/css :clip-content)}
[:input {:type "checkbox"
:id "clip-content"
:ref clip-content-ref
:class (stl/css :clip-content-input)
:checked (not (:show-content values))
:on-change on-change-clip-content}]
[:label {:for "show-in-viewer"} [:label {:for "clip-content"
(tr "workspace.options.show-in-viewer")]])]]]))) :title (tr "workspace.options.clip-content")
:class (stl/css-case :clip-content-label true
:selected (not (:show-content values)))}
[:span {:class (stl/css :icon)}
i/clip-content-refactor]]])
(when (options :show-in-viewer)
[:div {:class (stl/css :clip-content)}
[:input {:type "checkbox"
:id "show-in-viewer"
:ref show-in-viewer-ref
:class (stl/css :clip-content-input)
:checked (not (:hide-in-viewer values))
:on-change on-change-show-in-viewer}]
[:label {:for "show-in-viewer"
:title (tr "workspace.options.show-in-viewer")
:class (stl/css-case :clip-content-label true
:selected (not (:hide-in-viewer values)))}
[:span {:class (stl/css :icon)}
i/play-refactor]]])])]))

View file

@ -9,216 +9,235 @@
.element-set { .element-set {
@include flexColumn; @include flexColumn;
margin-bottom: $s-8; margin-bottom: $s-8;
.presets { }
display: flex;
align-items: flex-start;
gap: $s-4;
.presets-wrapper {
@extend .asset-element;
position: relative;
display: flex;
height: $s-32;
width: $s-188;
padding: $s-8;
border-radius: $br-8;
.select-name {
@include titleTipography;
display: flex;
justify-content: flex-start;
align-items: center;
flex-grow: 1;
cursor: pointer;
}
.collapsed-icon {
@include flexCenter;
cursor: pointer;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
transform: rotate(90deg);
}
}
.custom-select-dropdown {
@extend .dropdown-wrapper;
margin-top: $s-2;
width: $s-252;
.dropdown-element {
@extend .dropdown-element-base;
.name-wrapper {
display: flex;
gap: $s-8;
flex-grow: 1;
.preset-name {
color: var(--menu-foreground-color-rest);
}
.preset-size {
color: var(--menu-foreground-color-rest);
}
}
.check-icon { .presets {
@include flexCenter; display: flex;
svg { align-items: flex-start;
@extend .button-icon-small; gap: $s-4;
stroke: var(--icon-foreground); }
}
}
&.disabled { .presets-wrapper {
pointer-events: none; @extend .asset-element;
cursor: default; position: relative;
.preset-name { display: flex;
color: var(--menu-foreground-color); height: $s-32;
} width: $s-188;
} padding: $s-8;
border-radius: $br-8;
&.match { .collapsed-icon {
.name-wrapper .preset-name { @include flexCenter;
color: var(--menu-foreground-color-hover); cursor: pointer;
} svg {
.check-icon svg { @extend .button-icon-small;
stroke: var(--menu-foreground-color-hover); stroke: var(--icon-foreground);
} transform: rotate(90deg);
}
&:hover {
background-color: var(--menu-background-color-hover);
.name-wrapper .preset-name {
color: var(--menu-foreground-color-hover);
}
.check-icon svg {
stroke: var(--menu-foreground-color-hover);
}
}
}
}
&:hover {
.collapsed-icon svg {
stroke: var(--input-foreground-color-active);
}
}
} }
} }
.size {
@include flexRow; &:hover {
.height, .collapsed-icon svg {
.width { stroke: var(--input-foreground-color-active);
@extend .input-element; }
width: $s-108; }
.icon-text { }
padding-top: $s-1;
.select-name {
@include titleTipography;
display: flex;
justify-content: flex-start;
align-items: center;
flex-grow: 1;
cursor: pointer;
}
.custom-select-dropdown {
@extend .dropdown-wrapper;
margin-top: $s-2;
width: $s-252;
.dropdown-element {
@extend .dropdown-element-base;
.name-wrapper {
display: flex;
gap: $s-8;
flex-grow: 1;
.preset-name {
color: var(--menu-foreground-color-rest);
} }
&.disabled { .preset-size {
@extend .disabled-input; color: var(--menu-foreground-color-rest);
} }
} }
.lock-size-btn {
@extend .button-tertiary; .check-icon {
border-radius: $br-8; @include flexCenter;
height: $s-32;
width: $s-28;
svg { svg {
@extend .button-icon; @extend .button-icon-small;
stroke: var(--icon-foreground); stroke: var(--icon-foreground);
} }
&.selected { }
@extend .button-icon-selected;
&.disabled {
pointer-events: none;
cursor: default;
.preset-name {
color: var(--menu-foreground-color);
} }
} }
}
.position { &.match {
@include flexRow; .name-wrapper .preset-name {
.x-position, color: var(--menu-foreground-color-hover);
.y-position {
@extend .input-element;
width: $s-108;
.icon-text {
padding-top: $s-1;
} }
&.disabled { .check-icon svg {
@extend .disabled-input; stroke: var(--menu-foreground-color-hover);
} }
} }
}
.rotation-radius { &:hover {
display: flex; background-color: var(--menu-background-color-hover);
align-items: flex-start; .name-wrapper .preset-name {
justify-content: flex-start; color: var(--menu-foreground-color-hover);
gap: $s-4;
.rotation {
@extend .input-element;
width: $s-108;
.icon-text {
padding-top: $s-1;
} }
} .check-icon svg {
.radius { stroke: var(--menu-foreground-color-hover);
display: flex; }
align-items: flex-start; }
justify-content: flex-start; }
gap: $s-4; }
.radius-inputs {
display: flex; .size {
.radius-1 { @include flexRow;
@extend .input-element; }
width: $s-108;
} .height,
.radius-4 { .width {
display: grid; @extend .input-element;
grid-template-columns: 1fr 1fr; width: $s-108;
gap: $s-4; .icon-text {
.small-input { padding-top: $s-1;
@extend .input-element; }
width: $s-52; &.disabled {
} @extend .disabled-input;
} }
} }
.radius-mode {
@extend .button-tertiary; .lock-size-btn {
height: $s-32; @extend .button-tertiary;
width: $s-28; border-radius: $br-8;
border-radius: $br-8; height: $s-32;
svg { width: $s-28;
@extend .button-icon; svg {
stroke: var(--icon-foreground); @extend .button-icon;
} stroke: var(--icon-foreground);
&.selected { }
background-color: var(--button-tertiary-background-color-hover); &.selected {
svg { @extend .button-icon-selected;
stroke: var(--button-tertiary-foreground-color-active); }
} }
}
} .position {
} @include flexRow;
} }
.clip-show {
display: flex; .x-position,
align-items: flex-start; .y-position {
justify-content: flex-start; @extend .input-element;
gap: $s-4; width: $s-108;
.clip-content, .icon-text {
.show-in-viewer { padding-top: $s-1;
.clip-content-input { }
display: none; &.disabled {
} @extend .disabled-input;
.clip-content-label { }
@extend .button-tertiary; }
height: $s-32;
width: $s-28; .rotation-radius {
border-radius: $br-8; display: flex;
.icon { align-items: flex-start;
@include flexCenter; justify-content: flex-start;
svg { gap: $s-4;
@extend .button-icon; }
stroke: var(--icon-foreground);
} .rotation {
} @extend .input-element;
&.selected { width: $s-108;
background-color: var(--button-tertiary-background-color-hover); .icon-text {
svg { padding-top: $s-1;
stroke: var(--button-tertiary-foreground-color-active); }
} }
} .radius {
display: flex;
align-items: flex-start;
justify-content: flex-start;
gap: $s-4;
}
.radius-inputs {
display: flex;
}
.radius-1 {
@extend .input-element;
width: $s-108;
}
.radius-4 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: $s-4;
.small-input {
@extend .input-element;
width: $s-52;
}
}
.radius-mode {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
border-radius: $br-8;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
&.selected {
background-color: var(--button-tertiary-background-color-hover);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.clip-show {
display: flex;
align-items: flex-start;
justify-content: flex-start;
gap: $s-4;
}
.clip-content,
.show-in-viewer {
.clip-content-input {
display: none;
}
.clip-content-label {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
border-radius: $br-8;
.icon {
@include flexCenter;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
&.selected {
background-color: var(--button-tertiary-background-color-hover);
svg {
stroke: var(--button-tertiary-foreground-color-active);
} }
} }
} }

View file

@ -19,7 +19,6 @@
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] [app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
@ -51,8 +50,7 @@
(mf/defc shadow-entry (mf/defc shadow-entry
[{:keys [ids index value on-reorder disable-drag? on-blur open-state-ref]}] [{:keys [ids index value on-reorder disable-drag? on-blur open-state-ref]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [basic-offset-x-ref (mf/use-ref nil)
basic-offset-x-ref (mf/use-ref nil)
basic-offset-y-ref (mf/use-ref nil) basic-offset-y-ref (mf/use-ref nil)
basic-blur-ref (mf/use-ref nil) basic-blur-ref (mf/use-ref nil)
@ -61,9 +59,7 @@
adv-blur-ref (mf/use-ref nil) adv-blur-ref (mf/use-ref nil)
adv-spread-ref (mf/use-ref nil) adv-spread-ref (mf/use-ref nil)
shadow-style (if new-css-system shadow-style (:style value)
(:style value)
(dm/str (:style value)))
shadow-id (:id value) shadow-id (:id value)
@ -143,9 +139,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids index) (mf/deps ids index)
(fn [event] (fn [event]
(let [value (if new-css-system (let [value (keyword event)]
(keyword event)
(-> event dom/get-target-val d/read-string))]
(st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))) (st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value))))))
type-options [{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")} type-options [{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")}
@ -155,187 +149,91 @@
manage-on-close #(st/emit! (dwu/commit-undo-transaction :color-row))] manage-on-close #(st/emit! (dwu/commit-undo-transaction :color-row))]
[:div.shadow-option {:class (stl/css-case new-css-system [:div {:class (stl/css-case :global/shadow-option true
:global/shadow-option true :shadow-element true
:shadow-element true :dnd-over-top (= (:over dprops) :top)
:dnd-over-top (= (:over dprops) :top) :dnd-over-bot (= (:over dprops) :bot))
:dnd-over-bot (= (:over dprops) :bot)) :ref dref}
:ref dref} [:*
(if new-css-system [:div {:class (stl/css :basic-options)}
[:* [:div {:class (stl/css-case :shadow-info true
[:div {:class (stl/css :basic-options)} :hidden hidden?)}
[:div {:class (stl/css-case :shadow-info true [:button {:class (stl/css-case :more-options true
:hidden hidden?)} :selected open-shadow)
[:button {:class (stl/css-case :more-options true :on-click on-toggle-open-shadow}
:selected open-shadow) i/menu-refactor]
:on-click on-toggle-open-shadow} [:div {:class (stl/css :type-select)}
i/menu-refactor] [:& select
[:div {:class (stl/css :type-select)} {:class (stl/css :shadow-type-select)
[:& select :default-value (d/name shadow-style)
{:class (stl/css :shadow-type-select) :options type-options
:default-value (d/name shadow-style) :on-change on-type-change}]]]
:options type-options [:div {:class (stl/css :actions)}
:on-change on-type-change}]]] [:button {:class (stl/css :action-btn)
[:div {:class (stl/css :actions)} :on-click toggle-visibility}
[:button {:class (stl/css :action-btn) (if hidden?
:on-click toggle-visibility} i/hide-refactor
(if hidden? i/shown-refactor)]
i/hide-refactor [:button {:class (stl/css :action-btn)
i/shown-refactor)] :on-click on-remove-shadow}
[:button {:class (stl/css :action-btn) i/remove-refactor]]]
:on-click on-remove-shadow} (when open-shadow
i/remove-refactor]]] [:& advanced-options {:class (stl/css :shadow-advanced-options)
(when open-shadow :visible? open-shadow
[:& advanced-options {:class (stl/css :shadow-advanced-options)
:visible? open-shadow
:on-close on-toggle-open-shadow}
[:div {:class (stl/css :first-row)}
[:div {:class (stl/css :offset-x-input)
:title (tr "workspace.options.shadow-options.offsetx")}
[:span {:class (stl/css :input-label)}
"X"]
[:> numeric-input* {:className (stl/css :numeric-input)
:ref adv-offset-x-ref
:no-validate true
:placeholder "--"
:on-change (update-attr index :offset-x basic-offset-x-ref)
:on-blur on-blur
:value (:offset-x value)}]]
[:div {:class (stl/css :blur-input)
:title (tr "workspace.options.shadow-options.blur")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.blur")]
[:> numeric-input* {:ref adv-blur-ref
:className (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :blur basic-blur-ref)
:on-blur on-blur
:min 0
:value (:blur value)}]]
[:div {:class (stl/css :spread-input)
:title (tr "workspace.options.shadow-options.spread")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.spread")]
[:> numeric-input* {:ref adv-spread-ref
:className (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :spread)
:on-blur on-blur
:value (:spread value)}]]]
[:div {:class (stl/css :second-row)}
[:div {:class (stl/css :offset-y-input)
:title (tr "workspace.options.shadow-options.offsety")}
[:span {:class (stl/css :input-label)}
"Y"]
[:> numeric-input* {:ref adv-offset-y-ref
:className (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :offset-y basic-offset-y-ref)
:on-blur on-blur
:value (:offset-y value)}]]
[:& color-row {:color (if (string? (:color value))
;; Support for old format colors
{:color (:color value) :opacity (:opacity value)}
(:color value))
:title (tr "workspace.options.shadow-options.color")
:disable-gradient true
:disable-image true
:on-change update-color
:on-detach detach-color
:on-open manage-on-open
:on-close manage-on-close}]]])]
[:*
[:div.shadow-option-main {:style {:display (when open-shadow "none")}}
[:div.element-set-actions-button
{:on-click on-toggle-open-shadow}
i/actions]
[:select.input-select
{:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:default-value shadow-style
:on-change on-type-change}
[:option {:value ":drop-shadow"
:selected (when (= shadow-style ":drop-shadow") "selected")}
(tr "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"
:selected (when (= shadow-style ":inner-shadow") "selected")}
(tr "workspace.options.shadow-options.inner-shadow")]]
[:div.shadow-option-main-actions
[:div.element-set-actions-button {:on-click toggle-visibility}
(if hidden? i/eye-closed i/eye)]
[:div.element-set-actions-button
{:data-index index
:on-click on-remove-shadow}
i/minus]]]
[:& advanced-options {:visible? open-shadow
:on-close on-toggle-open-shadow} :on-close on-toggle-open-shadow}
[:div.color-data
[:div.element-set-actions-button
{:on-click on-toggle-open-shadow}
i/actions]
[:select.input-select
{:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:default-value shadow-style
:on-change on-type-change}
[:option {:value ":drop-shadow"
:selected (when (= shadow-style ":drop-shadow") "selected")}
(tr "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"
:selected (when (= shadow-style ":inner-shadow") "selected")}
(tr "workspace.options.shadow-options.inner-shadow")]]]
[:div.row-grid-2 [:div {:class (stl/css :first-row)}
[:div.input-element {:title (tr "workspace.options.shadow-options.offsetx")} [:div {:class (stl/css :offset-x-input)
[:> numeric-input* {:ref adv-offset-x-ref :title (tr "workspace.options.shadow-options.offsetx")}
[:span {:class (stl/css :input-label)}
"X"]
[:> numeric-input* {:className (stl/css :numeric-input)
:ref adv-offset-x-ref
:no-validate true :no-validate true
:placeholder "--" :placeholder "--"
:on-change (update-attr index :offset-x basic-offset-x-ref) :on-change (update-attr index :offset-x basic-offset-x-ref)
:on-blur on-blur :on-blur on-blur
:value (:offset-x value)}] :value (:offset-x value)}]]
[:span.after (tr "workspace.options.shadow-options.offsetx")]]
[:div.input-element {:title (tr "workspace.options.shadow-options.offsety")} [:div {:class (stl/css :blur-input)
[:> numeric-input* {:ref adv-offset-y-ref :title (tr "workspace.options.shadow-options.blur")}
:no-validate true [:span {:class (stl/css :input-label)}
:placeholder "--" (tr "workspace.options.shadow-options.blur")]
:on-change (update-attr index :offset-y basic-offset-y-ref)
:on-blur on-blur
:value (:offset-y value)}]
[:span.after (tr "workspace.options.shadow-options.offsety")]]]
[:div.row-grid-2
[:div.input-element {:title (tr "workspace.options.shadow-options.blur")}
[:> numeric-input* {:ref adv-blur-ref [:> numeric-input* {:ref adv-blur-ref
:className (stl/css :numeric-input)
:no-validate true :no-validate true
:placeholder "--" :placeholder "--"
:on-change (update-attr index :blur basic-blur-ref) :on-change (update-attr index :blur basic-blur-ref)
:on-blur on-blur :on-blur on-blur
:min 0 :min 0
:value (:blur value)}] :value (:blur value)}]]
[:span.after (tr "workspace.options.shadow-options.blur")]]
[:div.input-element {:title (tr "workspace.options.shadow-options.spread")} [:div {:class (stl/css :spread-input)
:title (tr "workspace.options.shadow-options.spread")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.spread")]
[:> numeric-input* {:ref adv-spread-ref [:> numeric-input* {:ref adv-spread-ref
:className (stl/css :numeric-input)
:no-validate true :no-validate true
:placeholder "--" :placeholder "--"
:on-change (update-attr index :spread) :on-change (update-attr index :spread)
:on-blur on-blur :on-blur on-blur
:value (:spread value)}] :value (:spread value)}]]]
[:span.after (tr "workspace.options.shadow-options.spread")]]]
[:div.color-row-wrap [:div {:class (stl/css :second-row)}
[:div {:class (stl/css :offset-y-input)
:title (tr "workspace.options.shadow-options.offsety")}
[:span {:class (stl/css :input-label)}
"Y"]
[:> numeric-input* {:ref adv-offset-y-ref
:className (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :offset-y basic-offset-y-ref)
:on-blur on-blur
:value (:offset-y value)}]]
[:& color-row {:color (if (string? (:color value)) [:& color-row {:color (if (string? (:color value))
;; Support for old format colors ;; Support for old format colors
{:color (:color value) :opacity (:opacity value)} {:color (:color value) :opacity (:opacity value)}
(:color value)) (:color value))
:title (tr "workspace.options.shadow-options.color") :title (tr "workspace.options.shadow-options.color")
@ -344,13 +242,12 @@
:on-change update-color :on-change update-color
:on-detach detach-color :on-detach detach-color
:on-open manage-on-open :on-open manage-on-open
:on-close manage-on-close}]]]])])) :on-close manage-on-close}]]])]]))
(mf/defc shadow-menu (mf/defc shadow-menu
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [ids (unchecked-get props "ids")
ids (unchecked-get props "ids")
type (unchecked-get props "type") type (unchecked-get props "type")
values (unchecked-get props "values") values (unchecked-get props "values")
@ -389,70 +286,35 @@
(mf/deps ids) (mf/deps ids)
#(st/emit! (dc/add-shadow ids (create-shadow))))] #(st/emit! (dc/add-shadow ids (create-shadow))))]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-shadows?
[:& title-bar {:collapsable? has-shadows? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (case type
:title (case type :multiple (tr "workspace.options.shadow-options.title.multiple")
:multiple (tr "workspace.options.shadow-options.title.multiple") :group (tr "workspace.options.shadow-options.title.group")
:group (tr "workspace.options.shadow-options.title.group") (tr "workspace.options.shadow-options.title"))
(tr "workspace.options.shadow-options.title")) :class (stl/css-case :title-spacing-shadow (not has-shadows?))}
:class (stl/css-case :title-spacing-shadow (not has-shadows?))}
(when-not (= :multiple shadows) (when-not (= :multiple shadows)
[:button {:class (stl/css :add-shadow) [:button {:class (stl/css :add-shadow)
:on-click on-add-shadow} i/add-refactor])]] :on-click on-add-shadow} i/add-refactor])]]
(when open?
(cond
(= :multiple shadows)
[:div {:class (stl/css :element-set-content)}
[:div {:class (stl/css :multiple-shadows)}
[:div {:class (stl/css :label)} (tr "settings.multiple")]
[:div {:class (stl/css :actions)}
[:button {:class (stl/css :action-btn)
:on-click on-remove-all}
i/remove-refactor]]]]
(seq shadows)
[:& h/sortable-container {}
[:div {:class (stl/css :element-set-content)}
(for [[index value] (d/enumerate shadows)]
[:& shadow-entry
{:key (dm/str "shadow-" index)
:ids ids
:value value
:on-reorder handle-reorder
:disable-drag? disable-drag?
:on-blur on-blur
:index index
:open-state-ref open-state-ref}])]]))]
[:div.element-set.shadow-options
[:div.element-set-title
[:span
(case type
:multiple (tr "workspace.options.shadow-options.title.multiple")
:group (tr "workspace.options.shadow-options.title.group")
(tr "workspace.options.shadow-options.title"))]
(when-not (= :multiple shadows)
[:div.add-page {:on-click on-add-shadow} i/close])]
(when open?
(cond (cond
(= :multiple shadows) (= :multiple shadows)
[:div.element-set-content [:div {:class (stl/css :element-set-content)}
[:div.element-set-options-group [:div {:class (stl/css :multiple-shadows)}
[:div.element-set-label (tr "settings.multiple")] [:div {:class (stl/css :label)} (tr "settings.multiple")]
[:div.element-set-actions [:div {:class (stl/css :actions)}
[:div.element-set-actions-button {:on-click on-remove-all} [:button {:class (stl/css :action-btn)
i/minus]]]] :on-click on-remove-all}
i/remove-refactor]]]]
(seq shadows) (seq shadows)
[:& h/sortable-container {} [:& h/sortable-container {}
[:div.element-set-content [:div {:class (stl/css :element-set-content)}
(for [[index value] (d/enumerate shadows)] (for [[index value] (d/enumerate shadows)]
[:& shadow-entry [:& shadow-entry
{:key (dm/str "shadow-" index) {:key (dm/str "shadow-" index)
@ -462,4 +324,4 @@
:disable-drag? disable-drag? :disable-drag? disable-drag?
:on-blur on-blur :on-blur on-blur
:index index :index index
:open-state-ref open-state-ref}])]])]))) :open-state-ref open-state-ref}])]]))]))

View file

@ -8,129 +8,127 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
.title-spacing-shadow {
margin: 0; .title-spacing-shadow {
padding-left: $s-2; margin: 0;
padding-left: $s-2;
}
.add-shadow {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.element-set-content {
margin-top: $s-4;
@include flexColumn;
}
.multiple-shadows {
@include flexRow;
}
.label {
@extend .mixed-bar;
}
.actions {
@include flexRow;
}
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.shadow-element {
@include flexColumn;
}
.basic-options {
@include flexRow;
}
.shadow-info {
display: flex;
align-items: center;
gap: $s-1;
width: $s-188;
.more-options {
@extend .button-secondary;
height: $s-32;
width: $s-28;
border-radius: $br-8 0 0 $br-8;
svg {
@extend .button-icon;
} }
.add-shadow { &.selected {
@extend .button-tertiary; background-color: var(--button-radio-background-color-active);
height: $s-32;
width: $s-28;
svg { svg {
@extend .button-icon; stroke: var(--button-radio-foreground-color-active);
} }
} }
} }
.element-set-content { .type-select {
margin-top: $s-4; padding: 0;
@include flexColumn; border-radius: 0 $br-8 $br-8 0;
.multiple-shadows { flex-grow: 1;
@include flexRow; .shadow-type-select {
.label { flex-grow: 1;
@extend .mixed-bar; border-radius: 0 $br-8 $br-8 0;
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
} }
.shadow-element { }
@include flexColumn;
.basic-options {
@include flexRow;
.shadow-info {
display: flex;
align-items: center;
gap: $s-1;
width: $s-188;
.more-options {
@extend .button-secondary;
height: $s-32;
width: $s-28;
border-radius: $br-8 0 0 $br-8;
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-radio-background-color-active);
svg {
stroke: var(--button-radio-foreground-color-active);
}
}
}
.type-select {
padding: 0;
border-radius: 0 $br-8 $br-8 0;
flex-grow: 1;
.shadow-type-select {
flex-grow: 1;
border-radius: 0 $br-8 $br-8 0;
}
}
&.hidden { &.hidden {
.more-options { .more-options {
@include hiddenElement; @include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled); border: $s-1 solid var(--input-border-color-disabled);
} }
.type-select { .type-select {
@include hiddenElement; @include hiddenElement;
.shadow-type-select { .shadow-type-select {
@include hiddenElement; @include hiddenElement;
border: $s-1 solid var(--input-border-color-disabled); border: $s-1 solid var(--input-border-color-disabled);
}
}
}
}
.actions {
@include flexRow;
.action-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
}
.shadow-advanced-options {
@include flexColumn;
.first-row,
.second-row {
@include flexRow;
.offset-x-input,
.blur-input,
.spread-input,
.offset-y-input {
@extend .input-element;
width: $s-60;
min-width: $s-60;
align-items: baseline;
input {
width: $s-32;
}
}
.blur-input,
.spread-input {
width: $s-92;
.input-label {
width: $s-44;
}
}
.spread-input {
gap: $s-8;
}
}
} }
} }
} }
} }
.shadow-advanced-options {
@include flexColumn;
}
.first-row,
.second-row {
@include flexRow;
.offset-x-input,
.blur-input,
.spread-input,
.offset-y-input {
@extend .input-element;
width: $s-60;
min-width: $s-60;
align-items: baseline;
input {
width: $s-32;
}
}
.blur-input,
.spread-input {
width: $s-92;
.input-label {
width: $s-44;
}
}
.spread-input {
gap: $s-8;
}
}

View file

@ -13,7 +13,6 @@
[app.main.data.workspace.colors :as dc] [app.main.data.workspace.colors :as dc]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.stroke-row :refer [stroke-row]] [app.main.ui.workspace.sidebar.options.rows.stroke-row :refer [stroke-row]]
@ -38,8 +37,7 @@
(mf/defc stroke-menu (mf/defc stroke-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "show-caps"]))]} {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "show-caps"]))]}
[{:keys [ids type values show-caps disable-stroke-style] :as props}] [{:keys [ids type values show-caps disable-stroke-style] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [label (case type
label (case type
:multiple (tr "workspace.options.selection-stroke") :multiple (tr "workspace.options.selection-stroke")
:group (tr "workspace.options.group-stroke") :group (tr "workspace.options.group-stroke")
(tr "workspace.options.stroke")) (tr "workspace.options.stroke"))
@ -53,27 +51,15 @@
strokes (:strokes values) strokes (:strokes values)
has-strokes? (or (= :multiple strokes) (some? (seq strokes))) has-strokes? (or (= :multiple strokes) (some? (seq strokes)))
handle-change-stroke-color
(mf/use-fn
(mf/deps ids)
(fn [index]
(fn [color]
(st/emit! (dc/change-stroke ids color index)))))
on-color-change-refactor on-color-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index color] (fn [index color]
(st/emit! (dc/change-stroke ids color index)))) (st/emit! (dc/change-stroke ids color index))))
handle-remove
(mf/use-fn
(mf/deps ids)
(fn [index]
(fn []
(st/emit! (dc/remove-stroke ids index)))))
on-remove-refactor on-remove
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index] (fn [index]
@ -85,16 +71,7 @@
(fn [_] (fn [_]
(st/emit! (dc/remove-all-strokes ids)))) (st/emit! (dc/remove-all-strokes ids))))
handle-detach on-color-detach
(mf/use-fn
(mf/deps ids)
(fn [index]
(fn [color]
(let [color (-> color
(assoc :id nil :file-id nil))]
(st/emit! (dc/change-stroke ids color index))))))
on-color-detach-refactor
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index color] (fn [index color]
@ -110,42 +87,19 @@
(st/emit! (dc/reorder-strokes ids index new-index))))) (st/emit! (dc/reorder-strokes ids index new-index)))))
on-stroke-style-change on-stroke-style-change
(fn [index]
(fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/read-string))]
(st/emit! (dc/change-stroke ids {:stroke-style value} index)))))
on-stroke-style-change-refactor
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [index value] (fn [index value]
(st/emit! (dc/change-stroke ids {:stroke-style value} index)))) (st/emit! (dc/change-stroke ids {:stroke-style value} index))))
on-stroke-alignment-change on-stroke-alignment-change
(fn [index]
(fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/read-string))]
(when-not (str/empty? value)
(st/emit! (dc/change-stroke ids {:stroke-alignment value} index))))))
on-stroke-alignment-change-refactor
(fn [index value] (fn [index value]
(when-not (str/empty? value) (when-not (str/empty? value)
(st/emit! (dc/change-stroke ids {:stroke-alignment value} index)))) (st/emit! (dc/change-stroke ids {:stroke-alignment value} index))))
on-stroke-width-change
(fn [index]
(fn [value]
(when-not (str/empty? value)
(st/emit! (dc/change-stroke ids {:stroke-width value} index)))))
on-stroke-width-change-refactor on-stroke-width-change
(fn [index value] (fn [index value]
(when-not (str/empty? value) (when-not (str/empty? value)
(st/emit! (dc/change-stroke ids {:stroke-width value} index)))) (st/emit! (dc/change-stroke ids {:stroke-width value} index))))
@ -207,70 +161,27 @@
on-blur (fn [_] on-blur (fn [_]
(reset! disable-drag false))] (reset! disable-drag false))]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? has-strokes?
[:& title-bar {:collapsable? has-strokes? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title label
:title label :class (stl/css-case :title-spacing-stroke (not has-strokes?))}
:class (stl/css-case :title-spacing-stroke (not has-strokes?))}
[:button {:class (stl/css :add-stroke) [:button {:class (stl/css :add-stroke)
:on-click on-add-stroke} i/add-refactor]]] :on-click on-add-stroke} i/add-refactor]]]
(when open? (when open?
[:div {:class (stl/css-case :element-content true [:div {:class (stl/css-case :element-content true
:empty-content (not has-strokes?))} :empty-content (not has-strokes?))}
(cond
(= :multiple strokes)
[:div {:class (stl/css :element-set-options-group)}
[:div {:class (stl/css :group-label)}
(tr "settings.multiple")]
[:button {:on-click handle-remove-all
:class (stl/css :remove-btn)}
i/remove-refactor]]
(seq strokes)
[:& h/sortable-container {}
(for [[index value] (d/enumerate (:strokes values []))]
[:& stroke-row {:key (dm/str "stroke-" index)
:stroke value
:title (tr "workspace.options.stroke-color")
:index index
:show-caps show-caps
:on-color-change on-color-change-refactor
:on-color-detach on-color-detach-refactor
:on-stroke-width-change on-stroke-width-change-refactor
:on-stroke-style-change on-stroke-style-change-refactor
:on-stroke-alignment-change on-stroke-alignment-change-refactor
:open-caps-select open-caps-select
:close-caps-select close-caps-select
:on-stroke-cap-start-change on-stroke-cap-start-change
:on-stroke-cap-end-change on-stroke-cap-end-change
:on-stroke-cap-switch on-stroke-cap-switch
:on-remove on-remove-refactor
:on-reorder (handle-reorder index)
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus (not @disable-drag)
:on-blur on-blur
:disable-stroke-style disable-stroke-style}])])])]
[:div.element-set
[:div.element-set-title
[:span label]
[:div.add-page {:on-click on-add-stroke} i/close]]
[:div.element-set-content
(cond (cond
(= :multiple strokes) (= :multiple strokes)
[:div.element-set-options-group [:div {:class (stl/css :element-set-options-group)}
[:div.element-set-label (tr "settings.multiple")] [:div {:class (stl/css :group-label)}
[:div.element-set-actions (tr "settings.multiple")]
[:div.element-set-actions-button {:on-click handle-remove-all} [:button {:on-click handle-remove-all
i/minus]]] :class (stl/css :remove-btn)}
i/remove-refactor]]
(seq strokes) (seq strokes)
[:& h/sortable-container {} [:& h/sortable-container {}
(for [[index value] (d/enumerate (:strokes values []))] (for [[index value] (d/enumerate (:strokes values []))]
@ -279,8 +190,8 @@
:title (tr "workspace.options.stroke-color") :title (tr "workspace.options.stroke-color")
:index index :index index
:show-caps show-caps :show-caps show-caps
:on-color-change handle-change-stroke-color :on-color-change on-color-change
:on-color-detach handle-detach :on-color-detach on-color-detach
:on-stroke-width-change on-stroke-width-change :on-stroke-width-change on-stroke-width-change
:on-stroke-style-change on-stroke-style-change :on-stroke-style-change on-stroke-style-change
:on-stroke-alignment-change on-stroke-alignment-change :on-stroke-alignment-change on-stroke-alignment-change
@ -289,10 +200,10 @@
:on-stroke-cap-start-change on-stroke-cap-start-change :on-stroke-cap-start-change on-stroke-cap-start-change
:on-stroke-cap-end-change on-stroke-cap-end-change :on-stroke-cap-end-change on-stroke-cap-end-change
:on-stroke-cap-switch on-stroke-cap-switch :on-stroke-cap-switch on-stroke-cap-switch
:on-remove handle-remove :on-remove on-remove
:on-reorder (handle-reorder index) :on-reorder (handle-reorder index)
:disable-drag disable-drag :disable-drag disable-drag
:on-focus on-focus :on-focus on-focus
:select-on-focus (not @disable-drag) :select-on-focus (not @disable-drag)
:on-blur on-blur :on-blur on-blur
:disable-stroke-style disable-stroke-style}])])]]))) :disable-stroke-style disable-stroke-style}])])])]))

View file

@ -8,43 +8,48 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
margin: 0;
.title-spacing-stroke {
padding-left: $s-2;
margin: 0;
}
.add-stroke {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
.element-content { .element-title {
display: flex; margin: 0;
flex-direction: column; }
gap: $s-12;
margin: $s-4 0 $s-8 0; .title-spacing-stroke {
.element-set-options-group { padding-left: $s-2;
@include flexRow; margin: 0;
.group-label { }
@extend .mixed-bar; .add-stroke {
} @extend .button-tertiary;
.remove-btn { height: $s-32;
@extend .button-tertiary; width: $s-28;
height: $s-32; svg {
width: $s-28; @extend .button-icon;
svg { }
@extend .button-icon; }
}
} .element-content {
} display: flex;
&.empty-content { flex-direction: column;
margin: 0; gap: $s-12;
} margin: $s-4 0 $s-8 0;
&.empty-content {
margin: 0;
}
}
.element-set-options-group {
@include flexRow;
}
.group-label {
@extend .mixed-bar;
}
.remove-btn {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
} }
} }

View file

@ -11,16 +11,13 @@
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc attribute-value [{:keys [attr value on-change on-delete] :as props}] (mf/defc attribute-value [{:keys [attr value on-change on-delete] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [handle-change
handle-change
(mf/use-fn (mf/use-fn
(mf/deps attr on-change) (mf/deps attr on-change)
(fn [event] (fn [event]
@ -33,56 +30,31 @@
(on-delete attr))) (on-delete attr)))
label (->> attr last d/name)] label (->> attr last d/name)]
(if new-css-system [:*
[:* (if (string? value)
(if (string? value) [:div {:class (stl/css :attr-content)}
[:div {:class (stl/css :attr-content)} [:span {:class (stl/css :attr-name)} label]
[:span {:class (stl/css :attr-name)} label] [:div {:class (stl/css :attr-input)}
[:div {:class (stl/css :attr-input)} [:input {:value value
[:input {:value value :class "input-text"
:class "input-text" :on-change handle-change}]]
:on-change handle-change}]] [:div {:class (stl/css :attr-actions)}
[:div {:class (stl/css :attr-actions)} [:button {:class (stl/css :attr-action-btn)
[:button {:class (stl/css :attr-action-btn) :on-click handle-delete}
:on-click handle-delete} i/remove-refactor]]]
i/remove-refactor]]] [:div {:class (stl/css :attr-nested-content)}
[:div {:class (stl/css :attr-nested-content)} [:div {:class (stl/css :attr-title)}
[:div {:class (stl/css :attr-title)} (str (d/name (last attr)))]
(str (d/name (last attr)))] (for [[key value] value]
(for [[key value] value] [:div {:class (stl/css :attr-row) :key key}
[:div {:class (stl/css :attr-row) :key key} [:& attribute-value {:key key
[:& attribute-value {:key key :attr (conj attr key)
:attr (conj attr key) :value value
:value value :on-change on-change
:on-change on-change :on-delete on-delete}]])])]))
:on-delete on-delete}]])])]
[:div.element-set-content
(if (string? value)
[:div.row-flex.row-flex-removable
[:& input-row {:label label
:type :text
:class "large"
:value (str value)
:on-change handle-change}]
[:div.element-set-actions
[:div.element-set-actions-button {:on-click handle-delete}
i/minus]]]
[:*
[:div.element-set-title
{:style {:border-bottom "1px solid #444" :margin-bottom "0.5rem"}}
[:span (str (d/name (last attr)))]]
(for [[key value] value]
[:& attribute-value {:key key
:attr (conj attr key)
:value value
:on-change on-change
:on-delete on-delete}])])])))
(mf/defc svg-attrs-menu [{:keys [ids values]}] (mf/defc svg-attrs-menu [{:keys [ids values]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [state* (mf/use-state true)
state* (mf/use-state true)
open? (deref state*) open? (deref state*)
attrs (:svg-attrs values) attrs (:svg-attrs values)
has-attributes? (or (= :multiple attrs) (some? (seq attrs))) has-attributes? (or (= :multiple attrs) (some? (seq attrs)))
@ -112,30 +84,18 @@
(st/emit! (dch/update-shapes ids update-fn)))))] (st/emit! (dch/update-shapes ids update-fn)))))]
(when-not (empty? attrs) (when-not (empty? attrs)
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-set-title)}
[:div {:class (stl/css :element-set-title)} [:& title-bar {:collapsable? has-attributes?
[:& title-bar {:collapsable? has-attributes? :collapsed? (not open?)
:collapsed? (not open?) :on-collapsed toggle-content
:on-collapsed toggle-content :title (tr "workspace.sidebar.options.svg-attrs.title")
:title (tr "workspace.sidebar.options.svg-attrs.title") :class (stl/css-case :title-spacing-svg-attrs (not has-attributes?))}]]
:class (stl/css-case :title-spacing-svg-attrs (not has-attributes?))}]] (when open?
(when open? [:div {:class (stl/css :element-set-content)}
[:div {:class (stl/css :element-set-content)}
(for [[attr-key attr-value] attrs] (for [[attr-key attr-value] attrs]
[:& attribute-value {:key attr-key [:& attribute-value {:key attr-key
:attr [attr-key] :attr [attr-key]
:value attr-value :value attr-value
:on-change handle-change :on-change handle-change
:on-delete handle-delete}])])] :on-delete handle-delete}])])])))
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.sidebar.options.svg-attrs.title")]]
(for [[attr-key attr-value] attrs]
[:& attribute-value {:key attr-key
:attr [attr-key]
:value attr-value
:on-change handle-change
:on-delete handle-delete}])]))))

View file

@ -8,41 +8,49 @@
.element-set { .element-set {
margin: 0; margin: 0;
.title-spacing-svg-attrs { }
padding-left: $s-2;
margin: 0; .title-spacing-svg-attrs {
} padding-left: $s-2;
.element-set-content { margin: 0;
@include flexColumn; }
margin: $s-4 0 0 0;
.attr-content { .element-set-content {
display: flex; @include flexColumn;
gap: $s-4; margin: $s-4 0 0 0;
.attr-name { }
@include titleTipography;
@include twoLineTextEllipsis; .attr-content {
width: $s-88; display: flex;
margin: auto $s-4; gap: $s-4;
margin-right: 0; }
display: inline-block;
} .attr-name {
.attr-input { @include titleTipography;
@extend .input-element; @include twoLineTextEllipsis;
width: $s-124; width: $s-88;
} margin: auto $s-4;
.attr-actions { margin-right: 0;
display: flex; display: inline-block;
gap: $s-4; color: var(--title-foreground-color);
.attr-action-btn { }
@extend .button-tertiary;
width: $s-28; .attr-input {
height: $s-32; @extend .input-element;
svg { width: $s-124;
@extend .button-icon; }
}
} .attr-actions {
} display: flex;
} gap: $s-4;
}
.attr-action-btn {
@extend .button-tertiary;
width: $s-28;
height: $s-32;
svg {
@extend .button-icon;
} }
} }

View file

@ -30,181 +30,101 @@
(mf/defc text-align-options (mf/defc text-align-options
[{:keys [values on-change on-blur] :as props}] [{:keys [values on-change on-blur] :as props}]
(let [{:keys [text-align]} values (let [{:keys [text-align]} values
new-css-system (mf/use-ctx ctx/new-css-system)
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-blur)
(fn [value] (fn [value]
(let [new-align (if new-css-system (on-change {:text-align value})
value (when (some? on-blur) (on-blur))))]
(-> (dom/get-current-target value)
(dom/get-data "value")))]
(on-change {:text-align new-align})
(when (some? on-blur) (on-blur)))))]
;; --- Align ;; --- Align
(if new-css-system [:div {:class (stl/css :align-options)}
[:div {:class (stl/css :align-options)} [:& radio-buttons {:selected text-align
[:& radio-buttons {:selected text-align :on-change handle-change
:on-change handle-change :name "align-text-options"}
:name "align-text-options"} [:& radio-button {:value "left"
[:& radio-button {:value "left" :id "text-align-left"
:id "text-align-left" :title (tr "workspace.options.text-options.text-align-left" (sc/get-tooltip :text-align-left))
:title (tr "workspace.options.text-options.text-align-left" (sc/get-tooltip :text-align-left)) :icon i/text-align-left-refactor}]
:icon i/text-align-left-refactor}] [:& radio-button {:value "center"
[:& radio-button {:value "center" :id "text-align-center"
:id "text-align-center" :title (tr "workspace.options.text-options.text-align-center" (sc/get-tooltip :text-align-center))
:title (tr "workspace.options.text-options.text-align-center" (sc/get-tooltip :text-align-center)) :icon i/text-align-center-refactor}]
:icon i/text-align-center-refactor}] [:& radio-button {:value "right"
[:& radio-button {:value "right" :id "text-align-right"
:id "text-align-right" :title (tr "workspace.options.text-options.text-align-right" (sc/get-tooltip :text-align-right))
:title (tr "workspace.options.text-options.text-align-right" (sc/get-tooltip :text-align-right)) :icon i/text-align-right-refactor}]
:icon i/text-align-right-refactor}] [:& radio-button {:value "justify"
[:& radio-button {:value "justify" :id "text-align-justify"
:id "text-align-justify" :title (tr "workspace.options.text-options.text-align-justify" (sc/get-tooltip :text-align-justify))
:title (tr "workspace.options.text-options.text-align-justify" (sc/get-tooltip :text-align-justify)) :icon i/text-justify-refactor}]]]))
:icon i/text-justify-refactor}]]]
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.text-align-left" (sc/get-tooltip :text-align-left))
:class (dom/classnames :current (= "left" text-align))
:data-value "left"
:on-click handle-change}
i/text-align-left]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.text-align-center" (sc/get-tooltip :text-align-center))
:class (dom/classnames :current (= "center" text-align))
:data-value "center"
:on-click handle-change}
i/text-align-center]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.text-align-right" (sc/get-tooltip :text-align-right))
:class (dom/classnames :current (= "right" text-align))
:data-value "right"
:on-click handle-change}
i/text-align-right]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.text-align-justify" (sc/get-tooltip :text-align-justify))
:class (dom/classnames :current (= "justify" text-align))
:data-value "justify"
:on-click handle-change}
i/text-align-justify]])))
(mf/defc text-direction-options (mf/defc text-direction-options
[{:keys [values on-change on-blur] :as props}] [{:keys [values on-change on-blur] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [direction (:text-direction values)
direction (:text-direction values)
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps direction) (mf/deps direction)
(fn [value] (fn [value]
(let [val (if new-css-system (let [dir (if (= value direction)
value
(-> (dom/get-current-target value)
(dom/get-data "value")))
dir (if (= val direction)
"none" "none"
val)] value)]
(on-change {:text-direction dir}) (on-change {:text-direction dir})
(when (some? on-blur) (on-blur)))))] (when (some? on-blur) (on-blur)))))]
(if new-css-system [:div {:class (stl/css :text-direction-options)}
[:div {:class (stl/css :text-direction-options)} [:& radio-buttons {:selected direction
[:& radio-buttons {:selected direction :on-change handle-change
:on-change handle-change :name "text-direction-options"}
:name "text-direction-options"} [:& radio-button {:value "ltr"
[:& radio-button {:value "ltr" :type "checkbox"
:type "checkbox" :id "ltr-text-direction"
:id "ltr-text-direction" :title (tr "workspace.options.text-options.direction-ltr")
:title (tr "workspace.options.text-options.direction-ltr") :icon i/text-ltr-refactor}]
:icon i/text-ltr-refactor}] [:& radio-button {:value "rtl"
[:& radio-button {:value "rtl" :type "checkbox"
:type "checkbox" :id "rtl-text-direction"
:id "rtl-text-direction" :title (tr "workspace.options.text-options.direction-rtl")
:title (tr "workspace.options.text-options.direction-rtl") :icon i/text-rtl-refactor}]]]))
:icon i/text-rtl-refactor}]]]
;; --- Align
[:div.align-icons
[:span.tooltip.tooltip-bottom-left
{:alt (tr "workspace.options.text-options.direction-ltr")
:class (dom/classnames :current (= "ltr" direction))
:data-value "ltr"
:on-click handle-change}
i/text-direction-ltr]
[:span.tooltip.tooltip-bottom-left
{:alt (tr "workspace.options.text-options.direction-rtl")
:class (dom/classnames :current (= "rtl" direction))
:data-value "rtl"
:on-click handle-change}
i/text-direction-rtl]])))
(mf/defc vertical-align (mf/defc vertical-align
[{:keys [values on-change on-blur] :as props}] [{:keys [values on-change on-blur] :as props}]
(let [{:keys [vertical-align]} values (let [{:keys [vertical-align]} values
new-css-system (mf/use-ctx ctx/new-css-system)
vertical-align (or vertical-align "top") vertical-align (or vertical-align "top")
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-blur)
(fn [value] (fn [value]
(let [new-align (if new-css-system (on-change {:vertical-align value})
value (when (some? on-blur) (on-blur))))]
(-> (dom/get-current-target value)
(dom/get-data "value")))]
(on-change {:vertical-align new-align})
(when (some? on-blur) (on-blur)))))]
(if new-css-system [:div {:class (stl/css :vertical-align-options)}
[:div {:class (stl/css :vertical-align-options)} [:& radio-buttons {:selected vertical-align
[:& radio-buttons {:selected vertical-align :on-change handle-change
:on-change handle-change :name "vertical-align-text-options"}
:name "vertical-align-text-options"} [:& radio-button {:value "top"
[:& radio-button {:value "top" :id "vertical-text-align-top"
:id "vertical-text-align-top" :title (tr "workspace.options.text-options.align-top")
:title (tr "workspace.options.text-options.align-top") :icon i/text-top-refactor}]
:icon i/text-top-refactor}] [:& radio-button {:value "center"
[:& radio-button {:value "center" :id "vertical-text-align-center"
:id "vertical-text-align-center" :title (tr "workspace.options.text-options.align-middle")
:title (tr "workspace.options.text-options.align-middle") :icon i/text-middle-refactor}]
:icon i/text-middle-refactor}] [:& radio-button {:value "bottom"
[:& radio-button {:value "bottom" :id "vertical-text-align-bottom"
:id "vertical-text-align-bottom" :title (tr "workspace.options.text-options.align-bottom")
:title (tr "workspace.options.text-options.align-bottom") :icon i/text-bottom-refactor}]]]))
:icon i/text-bottom-refactor}]]]
[:div.align-icons
[:span.tooltip.tooltip-bottom-left
{:alt (tr "workspace.options.text-options.align-top")
:class (dom/classnames :current (= "top" vertical-align))
:data-value "top"
:on-click handle-change}
i/align-top]
[:span.tooltip.tooltip-bottom-left
{:alt (tr "workspace.options.text-options.align-middle")
:class (dom/classnames :current (= "center" vertical-align))
:data-value "center"
:on-click handle-change}
i/align-middle]
[:span.tooltip.tooltip-bottom-left
{:alt (tr "workspace.options.text-options.align-bottom")
:class (dom/classnames :current (= "bottom" vertical-align))
:data-value "bottom"
:on-click handle-change}
i/align-bottom]])))
(mf/defc grow-options (mf/defc grow-options
[{:keys [ids values on-blur] :as props}] [{:keys [ids values on-blur] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [grow-type (:grow-type values)
grow-type (:grow-type values)
handle-change-grow handle-change-grow
(mf/use-fn (mf/use-fn
(mf/deps ids new-css-system) (mf/deps ids on-blur)
(fn [value] (fn [value]
(let [uid (js/Symbol) (let [uid (js/Symbol)
grow-type (if new-css-system grow-type (keyword value)]
(keyword value)
(-> (dom/get-current-target value)
(dom/get-data "value")
(keyword)))]
(st/emit! (st/emit!
(dwu/start-undo-transaction uid) (dwu/start-undo-transaction uid)
(dch/update-shapes ids #(assoc % :grow-type grow-type))) (dch/update-shapes ids #(assoc % :grow-type grow-type)))
@ -212,105 +132,55 @@
(ts/schedule #(st/emit! (dwu/commit-undo-transaction uid)))) (ts/schedule #(st/emit! (dwu/commit-undo-transaction uid))))
(when (some? on-blur) (on-blur))))] (when (some? on-blur) (on-blur))))]
(if new-css-system [:div {:class (stl/css :grow-options)}
[:div {:class (stl/css :grow-options)} [:& radio-buttons {:selected (d/name grow-type)
[:& radio-buttons {:selected (d/name grow-type) :on-change handle-change-grow
:on-change handle-change-grow :name "grow-text-options"}
:name "grow-text-options"} [:& radio-button {:value "fixed"
[:& radio-button {:value "fixed" :id "text-fixed-grow"
:id "text-fixed-grow" :title (tr "workspace.options.text-options.grow-fixed")
:title (tr "workspace.options.text-options.grow-fixed") :icon i/text-fixed-refactor}]
:icon i/text-fixed-refactor}] [:& radio-button {:value "auto-width"
[:& radio-button {:value "auto-width" :id "text-auto-width-grow"
:id "text-auto-width-grow" :title (tr "workspace.options.text-options.grow-auto-width")
:title (tr "workspace.options.text-options.grow-auto-width") :icon i/text-auto-width-refactor}]
:icon i/text-auto-width-refactor}] [:& radio-button {:value "auto-height"
[:& radio-button {:value "auto-height" :id "text-auto-height-grow"
:id "text-auto-height-grow" :title (tr "workspace.options.text-options.grow-auto-height")
:title (tr "workspace.options.text-options.grow-auto-height") :icon i/text-auto-height-refactor}]]]))
:icon i/text-auto-height-refactor}]]]
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.grow-fixed")
:class (dom/classnames :current (= :fixed grow-type))
:data-value "fixed"
:on-click handle-change-grow}
i/auto-fix]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.grow-auto-width")
:data-value "auto-width"
:class (dom/classnames :current (= :auto-width grow-type))
:on-click handle-change-grow}
i/auto-width]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.grow-auto-height")
:class (dom/classnames :current (= :auto-height grow-type))
:data-value "auto-height"
:on-click handle-change-grow}
i/auto-height]])))
(mf/defc text-decoration-options (mf/defc text-decoration-options
[{:keys [values on-change on-blur] :as props}] [{:keys [values on-change on-blur] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [text-decoration (or (:text-decoration values) "none")
text-decoration (or (:text-decoration values) "none")
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps text-decoration) (mf/deps text-decoration)
(fn [value] (fn [value]
(let [val (if new-css-system (let [decoration (if (= value text-decoration)
value
(-> (dom/get-current-target value)
(dom/get-data "value")))
decoration (if (= val text-decoration)
"none" "none"
val)] value)]
(on-change {:text-decoration decoration}) (on-change {:text-decoration decoration})
(when (some? on-blur) (on-blur)))))] (when (some? on-blur) (on-blur)))))]
(if new-css-system [:div {:class (stl/css :text-decoration-options)}
[:div {:class (stl/css :text-decoration-options)} [:& radio-buttons {:selected text-decoration
[:& radio-buttons {:selected text-decoration :on-change handle-change
:on-change handle-change :name "text-decoration-options"}
:name "text-decoration-options"} [:& radio-button {:value "underline"
[:& radio-button {:value "underline" :type "checkbox"
:type "checkbox" :id "underline-text-decoration"
:id "underline-text-decoration" :title (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline))
:title (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline)) :icon i/text-underlined-refactor}]
:icon i/text-underlined-refactor}] [:& radio-button {:value "line-through"
[:& radio-button {:value "line-through" :type "checkbox"
:type "checkbox" :id "line-through-text-decoration"
:id "line-through-text-decoration" :title (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through))
:title (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through)) :icon i/text-stroked-refactor}]]]))
:icon i/text-stroked-refactor}]]]
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.none")
:class (dom/classnames :current (= "none" text-decoration))
:data-value "none"
:on-click handle-change}
i/minus]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline))
:class (dom/classnames :current (= "underline" text-decoration))
:data-value "underline"
:on-click handle-change}
i/underline]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through))
:class (dom/classnames :current (= "line-through" text-decoration))
:data-value "line-through"
:on-click handle-change}
i/strikethrough]])))
(mf/defc text-menu (mf/defc text-menu
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [ids type values] :as props}] [{:keys [ids type values] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [file-id (mf/use-ctx ctx/current-file-id)
file-id (mf/use-ctx ctx/current-file-id)
typographies (mf/deref refs/workspace-file-typography) typographies (mf/deref refs/workspace-file-typography)
shared-libs (mf/deref refs/workspace-libraries) shared-libs (mf/deref refs/workspace-libraries)
label (case type label (case type
@ -411,87 +281,48 @@
(let [node (dom/get-element-by-class "public-DraftEditor-content")] (let [node (dom/get-element-by-class "public-DraftEditor-content")]
(dom/focus! node))))))}] (dom/focus! node))))))}]
(if new-css-system [:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)}
[:div {:class (stl/css :element-title)} [:& title-bar {:collapsable? true
[:& title-bar {:collapsable? true :collapsed? (not main-menu-open?)
:collapsed? (not main-menu-open?) :on-collapsed toggle-main-menu
:on-collapsed toggle-main-menu :title label
:title label :class (stl/css :title-spacing-text)}
:class (stl/css :title-spacing-text)} (when (and (not typography) (not multiple?))
(when (and (not typography) (not multiple?)) [:button {:class (stl/css :add-typography)
[:button {:class (stl/css :add-typography) :on-click on-convert-to-typography}
:on-click on-convert-to-typography} i/add-refactor])]]
i/add-refactor])]]
(when main-menu-open? (when main-menu-open?
[:div {:class (stl/css :element-content)} [:div {:class (stl/css :element-content)}
(cond (cond
typography typography
[:& typography-entry {:typography typography [:& typography-entry {:typography typography
:local? (= typography-file file-id) :local? (= typography-file file-id)
:file (get shared-libs typography-file) :file (get shared-libs typography-file)
:on-detach handle-detach-typography :on-detach handle-detach-typography
:on-change handle-change-typography}] :on-change handle-change-typography}]
(= typography-id :multiple) (= typography-id :multiple)
[:div {:class (stl/css :multiple-typography)} [:div {:class (stl/css :multiple-typography)}
[:span {:class (stl/css :multiple-text)} (tr "workspace.libraries.text.multiple-typography")] [:span {:class (stl/css :multiple-text)} (tr "workspace.libraries.text.multiple-typography")]
[:div {:class (stl/css :multiple-typography-button) [:div {:class (stl/css :multiple-typography-button)
:on-click handle-detach-typography :on-click handle-detach-typography
:title (tr "workspace.libraries.text.multiple-typography-tooltip")} :title (tr "workspace.libraries.text.multiple-typography-tooltip")}
i/detach-refactor]] i/detach-refactor]]
:else :else
[:> text-options opts]) [:> text-options opts])
[:div {:class (stl/css :text-align-options)} [:div {:class (stl/css :text-align-options)}
[:> text-align-options opts]
[:> grow-options opts]
[:button {:class (stl/css :more-options)
:on-click toggle-more-options}
i/menu-refactor]]
(when more-options-open?
[:div {:class (stl/css :text-decoration-options)}
[:> vertical-align opts]
[:> text-decoration-options opts]
[:> text-direction-options opts]])])]
[:div.element-set
[:div.element-set-title
[:span label]
(when (and (not typography) (not multiple?))
[:div.add-page {:on-click on-convert-to-typography} i/close])]
(cond
typography
[:& typography-entry {:typography typography
:local? (= typography-file file-id)
:file (get shared-libs typography-file)
:on-detach handle-detach-typography
:on-change handle-change-typography}]
(= typography-id :multiple)
[:div.multiple-typography
[:div.multiple-typography-text (tr "workspace.libraries.text.multiple-typography")]
[:div.multiple-typography-button {:on-click handle-detach-typography
:title (tr "workspace.libraries.text.multiple-typography-tooltip")} i/unchain]]
:else
[:> text-options opts])
[:div.element-set-content
[:div.row-flex
[:> text-align-options opts] [:> text-align-options opts]
[:> vertical-align opts]]
[:div.row-flex
[:> text-decoration-options opts]
[:> text-direction-options opts]]
[:div.row-flex
[:> grow-options opts] [:> grow-options opts]
[:div.align-icons]]]]))) [:button {:class (stl/css :more-options)
:on-click toggle-more-options}
i/menu-refactor]]
(when more-options-open?
[:div {:class (stl/css :text-decoration-options)}
[:> vertical-align opts]
[:> text-decoration-options opts]
[:> text-direction-options opts]])])]))

View file

@ -8,58 +8,68 @@
.element-set { .element-set {
margin: 0; margin: 0;
.element-title { }
margin: 0;
.add-typography { .element-title {
@extend .button-tertiary; margin: 0;
height: $s-32; }
width: $s-28;
svg { .add-typography {
@extend .button-icon; @extend .button-tertiary;
} height: $s-32;
} width: $s-28;
} svg {
.element-content { @extend .button-icon;
@include flexColumn;
margin-top: $s-4;
.multiple-typography {
@extend .mixed-bar;
.multiple-text {
@include titleTipography;
flex-grow: 1;
color: var(--input-foreground-color-active);
}
.multiple-typography-button {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
.text-align-options {
display: flex;
gap: $s-4;
.align-options,
.text-direction-options,
.vertical-align-options,
.grow-options,
.text-decoration-options {
height: $s-32;
}
.more-options {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
}
.text-decoration-options {
display: flex;
gap: $s-4;
}
} }
} }
.element-content {
@include flexColumn;
margin-top: $s-4;
}
.multiple-typography {
@extend .mixed-bar;
}
.multiple-text {
@include titleTipography;
flex-grow: 1;
color: var(--input-foreground-color-active);
}
.multiple-typography-button {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.text-align-options {
display: flex;
gap: $s-4;
}
.align-options,
.text-direction-options,
.vertical-align-options,
.grow-options,
.text-decoration-options {
height: $s-32;
}
.more-options {
@extend .button-tertiary;
height: $s-32;
width: $s-28;
svg {
@extend .button-icon;
}
}
.text-decoration-options {
display: flex;
gap: $s-4;
}

View file

@ -25,7 +25,6 @@
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
@ -61,8 +60,7 @@
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [font current? on-click style]}] [{:keys [font current? on-click style]}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
on-click (mf/use-fn (mf/deps font) #(on-click font)) on-click (mf/use-fn (mf/deps font) #(on-click font))]
new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/use-effect (mf/use-effect
(mf/deps current?) (mf/deps current?)
@ -72,22 +70,14 @@
(when-not (dom/is-in-viewport? element) (when-not (dom/is-in-viewport? element)
(dom/scroll-into-view! element)))))) (dom/scroll-into-view! element))))))
(if new-css-system [:div {:class (stl/css :font-wrapper)
[:div {:class (stl/css :font-wrapper) :style style
:style style :ref item-ref
:ref item-ref :on-click on-click}
:on-click on-click} [:div {:class (stl/css-case :font-item true
[:div {:class (stl/css-case :font-item true :selected current?)}
:selected current?)} [:span {:class (stl/css :label)} (:name font)]
[:span {:class (stl/css :label)} (:name font)] [:span {:class (stl/css :icon)} (when current? i/tick-refactor)]]]))
[:span {:class (stl/css :icon)} (when current? i/tick-refactor)]]]
[:div.font-item {:ref item-ref
:style style
:class (when current? "selected")
:on-click on-click}
[:span.icon (when current? i/tick)]
[:span.label (:name font)]])))
(declare row-renderer) (declare row-renderer)
@ -104,8 +94,7 @@
(mf/defc font-selector (mf/defc font-selector
[{:keys [on-select on-close current-font show-recent] :as props}] [{:keys [on-select on-close current-font show-recent] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [selected (mf/use-state current-font)
selected (mf/use-state current-font)
state (mf/use-state {:term "" :backends #{}}) state (mf/use-state {:term "" :backends #{}})
flist (mf/use-ref) flist (mf/use-ref)
@ -143,12 +132,8 @@
on-filter-change on-filter-change
(mf/use-fn (mf/use-fn
(mf/deps new-css-system)
(fn [event] (fn [event]
(let [value (if new-css-system (swap! state assoc :term event)))
event
(dom/get-target-val event))]
(swap! state assoc :term value))))
on-select-and-close on-select-and-close
(mf/use-fn (mf/use-fn
@ -184,72 +169,35 @@
#(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})] #(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})]
(.scrollToPosition ^js inst offset))))) (.scrollToPosition ^js inst offset)))))
[:div {:class (stl/css :font-selector)}
[:div {:class (stl/css :font-selector-dropdown)}
[:div {:class (stl/css :header)}
[:& search-bar {:on-change on-filter-change
:value (:term @state)
:placeholder (tr "workspace.options.search-font")}]
(when (and recent-fonts show-recent)
[*
[:p {:class (stl/css :title)} (tr "workspace.options.recent-fonts")]
(for [[idx font] (d/enumerate recent-fonts)]
[:& font-item {:key (dm/str "font-" idx)
:font font
:style {}
:on-click on-select-and-close
:current? (= (:id font) (:id @selected))}])])]
(if new-css-system [:div {:class (stl/css :fonts-list)}
[:div {:class (stl/css :font-selector)} [:> rvt/AutoSizer {}
[:div {:class (stl/css :font-selector-dropdown)} (fn [props]
[:div {:class (stl/css :header)} (let [width (unchecked-get props "width")
[:& search-bar {:on-change on-filter-change height (unchecked-get props "height")
:value (:term @state) render #(row-renderer fonts @selected on-select-and-close %)]
:placeholder (tr "workspace.options.search-font")}] (mf/html
(when (and recent-fonts show-recent) [:> rvt/List #js {:height height
[* :ref flist
[:p {:class (stl/css :title)} (tr "workspace.options.recent-fonts")] :width width
(for [[idx font] (d/enumerate recent-fonts)] :rowCount (count fonts)
[:& font-item {:key (dm/str "font-" idx) :rowHeight 36
:font font :rowRenderer render}])))]]]]))
:style {}
:on-click on-select-and-close
:current? (= (:id font) (:id @selected))}])])]
[:div {:class (stl/css :fonts-list)}
[:> rvt/AutoSizer {}
(fn [props]
(let [width (unchecked-get props "width")
height (unchecked-get props "height")
render #(row-renderer fonts @selected on-select-and-close %)]
(mf/html
[:> rvt/List #js {:height height
:ref flist
:width width
:rowCount (count fonts)
:rowHeight 36
:rowRenderer render}])))]]]]
[:div.font-selector
[:div.font-selector-dropdown
[:header
[:input {:placeholder (tr "workspace.options.search-font")
:value (:term @state)
:ref input
:spell-check false
:on-change on-filter-change}]
(when (and recent-fonts show-recent)
[:*
[:hr]
[:p.title (tr "workspace.options.recent-fonts")]
(for [[idx font] (d/enumerate recent-fonts)]
[:& font-item {:key (dm/str "font-" idx)
:font font
:style {}
:on-click on-select-and-close
:current? (= (:id font) (:id @selected))}])])]
[:hr]
[:div.fonts-list
[:> rvt/AutoSizer {}
(fn [props]
(let [width (unchecked-get props "width")
height (unchecked-get props "height")
render #(row-renderer fonts @selected on-select-and-close %)]
(mf/html
[:> rvt/List #js {:height height
:ref flist
:width width
:rowCount (count fonts)
:rowHeight 32
:rowRenderer render}])))]]]])))
(defn row-renderer (defn row-renderer
[fonts selected on-select props] [fonts selected on-select props]
@ -272,7 +220,6 @@
font-id (or font-id (:font-id txt/default-text-attrs)) font-id (or font-id (:font-id txt/default-text-attrs))
font-size (or font-size (:font-size txt/default-text-attrs)) font-size (or font-size (:font-size txt/default-text-attrs))
font-variant-id (or font-variant-id (:font-variant-id txt/default-text-attrs)) font-variant-id (or font-variant-id (:font-variant-id txt/default-text-attrs))
new-css-system (mf/use-ctx ctx/new-css-system)
fonts (mf/deref fonts/fontsdb) fonts (mf/deref fonts/fontsdb)
font (get fonts font-id) font (get fonts font-id)
@ -304,17 +251,14 @@
on-font-variant-change on-font-variant-change
(mf/use-fn (mf/use-fn
(mf/deps font on-change) (mf/deps font on-change)
(fn [event] (fn [new-variant-id]
(let [new-variant-id (if new-css-system (let [variant (d/seek #(= new-variant-id (:id %)) (:variants font))]
event
(dom/get-target-val event))
variant (d/seek #(= new-variant-id (:id %)) (:variants font))]
(on-change {:font-id (:id font) (on-change {:font-id (:id font)
:font-family (:family font) :font-family (:family font)
:font-variant-id new-variant-id :font-variant-id new-variant-id
:font-weight (:weight variant) :font-weight (:weight variant)
:font-style (:style variant)}) :font-style (:style variant)})
(dom/blur! (dom/get-target event))))) (dom/blur! (dom/get-target new-variant-id)))))
on-font-select on-font-select
(mf/use-fn (mf/use-fn
@ -335,114 +279,65 @@
(when (mf/ref-val last-font) (when (mf/ref-val last-font)
(st/emit! (fts/add-recent-font (mf/ref-val last-font))))))] (st/emit! (fts/add-recent-font (mf/ref-val last-font))))))]
(if new-css-system [:*
[:* (when @open-selector?
(when @open-selector? [:& font-selector
[:& font-selector {:current-font font
{:current-font font :on-close on-font-selector-close
:on-close on-font-selector-close :on-select on-font-select
:on-select on-font-select :show-recent show-recent}])
:show-recent show-recent}])
[:div {:class (stl/css :font-option) [:div {:class (stl/css :font-option)
:on-click #(reset! open-selector? true)} :on-click #(reset! open-selector? true)}
(cond (cond
(= :multiple font-id) (= :multiple font-id)
"--" "--"
(some? font) (some? font)
[:* [:*
[:span {:class (stl/css :name)} [:span {:class (stl/css :name)}
(:name font)] (:name font)]
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/arrow-refactor]] i/arrow-refactor]]
:else :else
(tr "dashboard.fonts.deleted-placeholder"))] (tr "dashboard.fonts.deleted-placeholder"))]
[:div {:class (stl/css :font-modifiers)} [:div {:class (stl/css :font-modifiers)}
[:div {:class (stl/css :font-size-options)} [:div {:class (stl/css :font-size-options)}
(let [size-options [8 9 10 11 12 14 16 18 24 36 48 72] (let [size-options [8 9 10 11 12 14 16 18 24 36 48 72]
size-options (if (= font-size :multiple) (into [""] size-options) size-options)] size-options (if (= font-size :multiple) (into [""] size-options) size-options)]
[:& editable-select [:& editable-select
{:value (attr->string font-size) {:value (attr->string font-size)
:class (stl/css :font-size-select) :class (stl/css :font-size-select)
:input-class (stl/css :numeric-input) :input-class (stl/css :numeric-input)
:options size-options :options size-options
:type "number" :type "number"
:placeholder "--" :placeholder "--"
:min 3 :min 3
:max 1000 :max 1000
:on-change on-font-size-change :on-change on-font-size-change
:on-blur on-blur}])] :on-blur on-blur}])]
[:div {:class (stl/css :font-variant-options)} [:div {:class (stl/css :font-variant-options)}
(let [basic-variant-options (->> (:variants font) (let [basic-variant-options (->> (:variants font)
(map (fn [variant] (map (fn [variant]
{:value (:id variant) {:value (:id variant)
:key (pr-str variant) :key (pr-str variant)
:label (:name variant)}) )) :label (:name variant)})))
variant-options (if (= font-size :multiple) variant-options (if (= font-size :multiple)
(conj basic-variant-options (conj basic-variant-options
{:value :multiple {:value :multiple
:key :multiple-variants :key :multiple-variants
:label "--"} ) :label "--"})
basic-variant-options)] basic-variant-options)]
;; TODO Add disabled mode ;; TODO Add disabled mode
[:& select [:& select
{:class (stl/css :font-variant-select) {:class (stl/css :font-variant-select)
:default-value (attr->string font-variant-id) :default-value (attr->string font-variant-id)
:options variant-options :options variant-options
:on-change on-font-variant-change :on-change on-font-variant-change
:on-blur on-blur}])]]] :on-blur on-blur}])]]]))
[:*
(when @open-selector?
[:& font-selector
{:current-font font
:on-close on-font-selector-close
:on-select on-font-select
:show-recent show-recent}])
[:div.row-flex
[:div.input-select.font-option
{:on-click #(reset! open-selector? true)}
(cond
(= :multiple font-id)
"--"
(some? font)
(:name font)
:else
(tr "dashboard.fonts.deleted-placeholder"))]]
[:div.row-flex
(let [size-options [8 9 10 11 12 14 16 18 24 36 48 72]
size-options (if (= font-size :multiple) (into [""] size-options) size-options)]
[:& editable-select
{:value (attr->string font-size)
:class "input-option size-option"
:options size-options
:type "number"
:placeholder "--"
:min 3
:max 1000
:on-change on-font-size-change
:on-blur on-blur}])
[:select.input-select.variant-option
{:disabled (= font-id :multiple)
:data-mousetrap-dont-stop true
:value (attr->string font-variant-id)
:on-change on-font-variant-change
:on-blur on-blur}
(when (or (= font-id :multiple) (= font-variant-id :multiple))
[:option {:value ""} "--"])
(for [variant (:variants font)]
[:option {:value (:id variant)
:key (pr-str variant)}
(:name variant)])]]])))
(mf/defc spacing-options (mf/defc spacing-options
{::mf/wrap-props false} {::mf/wrap-props false}
@ -452,152 +347,87 @@
line-height (or line-height "1.2") line-height (or line-height "1.2")
letter-spacing (or letter-spacing "0") letter-spacing (or letter-spacing "0")
new-css-system (mf/use-ctx ctx/new-css-system)
line-height-nillable (if (= (str line-height) "1.2") false true) line-height-nillable (if (= (str line-height) "1.2") false true)
handle-change handle-change
(fn [value attr] (fn [value attr]
(on-change {attr (str value)}))] (on-change {attr (str value)}))]
(if new-css-system
[:div {:class (stl/css :spacing-options)}
[:div {:class (stl/css :line-height)}
[:span {:class (stl/css :icon)
:alt (tr "workspace.options.text-options.line-height")}
i/text-lineheight-refactor]
[:> numeric-input*
{:min -200
:max 200
:step 0.1
:default "1.2"
:class (stl/css :line-height-input)
:value (attr->string line-height)
:placeholder (tr "settings.multiple")
:nillable line-height-nillable
:on-change #(handle-change % :line-height)
:on-blur on-blur}]]
[:div {:class (stl/css :letter-spacing)} [:div {:class (stl/css :spacing-options)}
[:span [:div {:class (stl/css :line-height)}
{:class (stl/css :icon) [:span {:class (stl/css :icon)
:alt (tr "workspace.options.text-options.letter-spacing")} :alt (tr "workspace.options.text-options.line-height")}
i/text-letterspacing-refactor] i/text-lineheight-refactor]
[:> numeric-input* [:> numeric-input*
{:min -200 {:min -200
:max 200 :max 200
:step 0.1 :step 0.1
:class (stl/css :letter-spacing-input) :default "1.2"
:value (attr->string letter-spacing) :class (stl/css :line-height-input)
:placeholder (tr "settings.multiple") :value (attr->string line-height)
:on-change #(handle-change % :letter-spacing) :placeholder (tr "settings.multiple")
:on-blur on-blur}]]] :nillable line-height-nillable
:on-change #(handle-change % :line-height)
:on-blur on-blur}]]
[:div {:class (stl/css :letter-spacing)}
[:div.spacing-options [:span
[:div.input-icon {:class (stl/css :icon)
[:span.icon-before.tooltip.tooltip-bottom :alt (tr "workspace.options.text-options.letter-spacing")}
{:alt (tr "workspace.options.text-options.line-height")} i/text-letterspacing-refactor]
i/line-height] [:> numeric-input*
[:> numeric-input* {:min -200
{:min -200 :max 200
:max 200 :step 0.1
:step 0.1 :class (stl/css :letter-spacing-input)
:default "1.2" :value (attr->string letter-spacing)
:value (attr->string line-height) :placeholder (tr "settings.multiple")
:placeholder (tr "settings.multiple") :on-change #(handle-change % :letter-spacing)
:nillable line-height-nillable :on-blur on-blur}]]]))
:on-change #(handle-change % :line-height)
:on-blur on-blur}]]
[:div.input-icon
[:span.icon-before.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.letter-spacing")}
i/letter-spacing]
[:> numeric-input*
{:min -200
:max 200
:step 0.1
:value (attr->string letter-spacing)
:placeholder (tr "settings.multiple")
:on-change #(handle-change % :letter-spacing)
:on-blur on-blur}]]])))
(mf/defc text-transform-options (mf/defc text-transform-options
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [values on-change on-blur]}] [{:keys [values on-change on-blur]}]
(let [text-transform (or (:text-transform values) "none") (let [text-transform (or (:text-transform values) "none")
new-css-system (mf/use-ctx ctx/new-css-system)
handle-change handle-change
(fn [type] (fn [type]
(if (= text-transform type) (if (= text-transform type)
(on-change {:text-transform "unset"}) (on-change {:text-transform "unset"})
(on-change {:text-transform type})) (on-change {:text-transform type}))
(when (some? on-blur) (on-blur)))] (when (some? on-blur) (on-blur)))]
(if new-css-system
[:div {:class (stl/css :text-transform)}
[:& radio-buttons {:selected text-transform
:on-change handle-change
:name "text-transform"}
[:& radio-button {:icon i/text-uppercase-refactor
:type "checkbox"
:value "uppercase"
:id "text-transform-uppercase"}]
[:& radio-button {:icon i/text-lowercase-refactor
:type "checkbox"
:value "lowercase"
:id "text-transform-lowercase"}]
[:& radio-button {:icon i/text-mixed-refactor
:type "checkbox"
:value "capitalize"
:id "text-transform-capitalize"}]]]
[:div.align-icons [:div {:class (stl/css :text-transform)}
[:span.tooltip.tooltip-bottom [:& radio-buttons {:selected text-transform
{:alt (tr "workspace.options.text-options.none") :on-change handle-change
:class (dom/classnames :current (= "none" text-transform)) :name "text-transform"}
:on-focus #(dom/prevent-default %) [:& radio-button {:icon i/text-uppercase-refactor
:on-click #(handle-change "none")} :type "checkbox"
i/minus] :value "uppercase"
[:span.tooltip.tooltip-bottom :id "text-transform-uppercase"}]
{:alt (tr "workspace.options.text-options.uppercase") [:& radio-button {:icon i/text-lowercase-refactor
:class (dom/classnames :current (= "uppercase" text-transform)) :type "checkbox"
:on-click #(handle-change "uppercase")} :value "lowercase"
i/uppercase] :id "text-transform-lowercase"}]
[:span.tooltip.tooltip-bottom [:& radio-button {:icon i/text-mixed-refactor
{:alt (tr "workspace.options.text-options.lowercase") :type "checkbox"
:class (dom/classnames :current (= "lowercase" text-transform)) :value "capitalize"
:on-click #(handle-change "lowercase")} :id "text-transform-capitalize"}]]]))
i/lowercase]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.titlecase")
:class (dom/classnames :current (= "capitalize" text-transform))
:on-click #(handle-change "capitalize")}
i/titlecase]])))
(mf/defc text-options (mf/defc text-options
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [ids editor values on-change on-blur show-recent]}] [{:keys [ids editor values on-change on-blur show-recent]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [opts #js {:editor editor
opts #js {:editor editor
:ids ids :ids ids
:values values :values values
:on-change on-change :on-change on-change
:on-blur on-blur :on-blur on-blur
:show-recent show-recent}] :show-recent show-recent}]
(if new-css-system [:div {:class (stl/css :text-options)}
[:div {:class (stl/css :text-options)} [:> font-options opts]
[:> font-options opts] [:div {:class (stl/css :typography-variations)}
[:div {:class (stl/css :typography-variations)} [:> spacing-options opts]
[:> spacing-options opts] [:> text-transform-options opts]]]))
[:> text-transform-options opts]]]
[:div.element-set-content
[:> font-options opts]
[:div.row-flex
[:> spacing-options opts]]
[:div.row-flex
[:> text-transform-options opts]]])))
(mf/defc typography-advanced-options (mf/defc typography-advanced-options
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
@ -684,16 +514,11 @@
:on-click navigate-to-library} :on-click navigate-to-library}
(tr "workspace.assets.typography.go-to-edit")])])]))) (tr "workspace.assets.typography.go-to-edit")])])])))
(mf/defc typography-entry (mf/defc typography-entry
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [file-id typography local? selected? on-click on-change on-detach on-context-menu editing? renaming? focus-name? external-open*]}] [{:keys [file-id typography local? selected? on-click on-change on-detach on-context-menu editing? renaming? focus-name? external-open*]}]
(let [hover-detach* (mf/use-state false) (let [name-input-ref (mf/use-ref)
hover-detach? (deref hover-detach*)
name-input-ref (mf/use-ref)
read-only? (mf/use-ctx ctx/workspace-read-only?) read-only? (mf/use-ctx ctx/workspace-read-only?)
new-css-system (mf/use-ctx ctx/new-css-system)
editable? (and local? (not read-only?)) editable? (and local? (not read-only?))
open* (mf/use-state editing?) open* (mf/use-state editing?)
@ -710,12 +535,6 @@
(on-change {:name name}) (on-change {:name name})
(st/emit! #(update % :workspace-global dissoc :rename-typography)))))) (st/emit! #(update % :workspace-global dissoc :rename-typography))))))
on-pointer-enter
(mf/use-fn #(reset! hover-detach* true))
on-pointer-leave
(mf/use-fn #(reset! hover-detach* false))
on-open on-open
(mf/use-fn #(reset! open* true)) (mf/use-fn #(reset! open* true))
@ -755,147 +574,62 @@
(dom/focus! node) (dom/focus! node)
(dom/select-text! node))))) (dom/select-text! node)))))
(if new-css-system [:*
[:* [:div {:class (stl/css-case :typography-entry true
[:div {:class (stl/css-case :typography-entry true :selected ^boolean selected?)
:selected ^boolean selected?) :style {:display (when ^boolean open? "none")}}
:style {:display (when ^boolean open? "none")}} (if renaming?
(if renaming? [:div {:class (stl/css :font-name-wrapper)}
[:div {:class (stl/css :font-name-wrapper)} [:div
[:div {:class (stl/css :typography-sample-input)
{:class (stl/css :typography-sample-input) :style {:font-family (:font-family typography)
:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:input
{:class (stl/css :adv-typography-name)
:type "text"
:ref name-input-ref
:default-value (:name typography)
:on-key-down on-key-down
:on-blur on-name-blur}]]
[:div
{:class (stl/css-case :typography-selection-wrapper true
:is-selectable ^boolean on-click)
:on-click on-click
:on-context-menu on-context-menu}
[:div
{:class (stl/css :typography-sample)
:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:div {:class (stl/css :typography-name)
:title (:name typography)} (:name typography)]
(when-not name-only?
[:div {:class (stl/css :typography-font)
:title (:name font-data)}
(:name font-data)])])
[:div {:class (stl/css :element-set-actions)}
(when ^boolean on-detach
[:button {:class (stl/css :element-set-actions-button)
:on-click on-detach}
i/detach-refactor])
[:button {:class (stl/css :menu-btn)
:on-click on-open}
i/menu-refactor]]]
[:& typography-advanced-options
{:visible? open?
:on-close on-close
:typography typography
:editable? editable?
:name-input-ref name-input-ref
:on-change on-change
:on-name-blur on-name-blur
:on-key-down on-key-down
:local? local?
:navigate-to-library navigate-to-library}]]
[:*
[:div.element-set-options-group.typography-entry
{:class (when ^boolean selected? "selected")
:style {:display (when ^boolean open? "none")}}
[:div.typography-selection-wrapper
{:class (when ^boolean on-click "is-selectable")
:on-click on-click
:on-context-menu on-context-menu}
[:div.typography-sample
{:style {:font-family (:font-family typography)
:font-weight (:font-weight typography) :font-weight (:font-weight typography)
:font-style (:font-style typography)}} :font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")] (tr "workspace.assets.typography.sample")]
[:div.typography-name {:title (:name typography)} (:name typography)]]
[:div.element-set-actions
(when ^boolean on-detach
[:div.element-set-actions-button
{:on-pointer-enter on-pointer-enter
:on-pointer-leave on-pointer-leave
:on-click on-detach}
(if ^boolean hover-detach? i/unchain i/chain)])
[:div.element-set-actions-button [:input
{:on-click on-open} {:class (stl/css :adv-typography-name)
i/actions]]] :type "text"
:ref name-input-ref
:default-value (:name typography)
:on-key-down on-key-down
:on-blur on-name-blur}]]
[:div
{:class (stl/css-case :typography-selection-wrapper true
:is-selectable ^boolean on-click)
:on-click on-click
:on-context-menu on-context-menu}
[:div
{:class (stl/css :typography-sample)
:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:& advanced-options {:visible? open? :on-close on-close} [:div {:class (stl/css :typography-name)
(if ^boolean editable? :title (:name typography)} (:name typography)]
[:*
[:div.element-set-content
[:div.row-flex
[:input.element-name.adv-typography-name
{:type "text"
:ref name-input-ref
:default-value (:name typography)
:on-blur on-name-blur}]
[:div.element-set-actions-button (when-not name-only?
{:on-click on-close} [:div {:class (stl/css :typography-font)
i/actions]]] :title (:name font-data)}
(:name font-data)])])
[:div {:class (stl/css :element-set-actions)}
(when ^boolean on-detach
[:button {:class (stl/css :element-set-actions-button)
:on-click on-detach}
i/detach-refactor])
[:button {:class (stl/css :menu-btn)
:on-click on-open}
i/menu-refactor]]]
[:& text-options {:values typography [:& typography-advanced-options
:on-change on-change {:visible? open?
:show-recent false}]] :on-close on-close
:typography typography
[:div.element-set-content.typography-read-only-data :editable? editable?
[:div.row-flex.typography-name :name-input-ref name-input-ref
[:span {:title (:name typography)} (:name typography)]] :on-change on-change
:on-name-blur on-name-blur
[:div.row-flex :on-key-down on-key-down
[:span.label (tr "workspace.assets.typography.font-id")] :local? local?
[:span (:font-id typography)]] :navigate-to-library navigate-to-library}]]))
[:div.element-set-actions-button.actions-inside
{:on-click on-close}
i/actions]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.font-variant-id")]
[:span (:font-variant-id typography)]]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.font-size")]
[:span (:font-size typography)]]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.line-height")]
[:span (:line-height typography)]]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.letter-spacing")]
[:span (:letter-spacing typography)]]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.text-transform")]
[:span (:text-transform typography)]]
(when-not local?
[:div.row-flex
[:a.go-to-lib-button
{:on-click navigate-to-library}
(tr "workspace.assets.typography.go-to-edit")]])])]])))

View file

@ -142,103 +142,104 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: var(--assets-title-background-color); background-color: var(--assets-title-background-color);
.typography-info-wrapper { }
@include flexColumn;
margin-bottom: $s-12; .typography-info-wrapper {
.typography-name-wrapper { @include flexColumn;
@extend .asset-element; margin-bottom: $s-12;
display: grid; .typography-name-wrapper {
grid-template-columns: $s-24 auto 1fr $s-28; @extend .asset-element;
flex: 1; display: grid;
grid-template-columns: $s-24 auto 1fr $s-28;
flex: 1;
height: $s-32;
width: 100%;
padding: 0 0 0 $s-12;
background-color: var(--assets-item-background-color-hover);
margin-bottom: $s-4;
.typography-sample {
@include flexCenter;
min-width: $s-24;
font-size: $fs-16;
height: $s-32; height: $s-32;
width: 100%; padding: 0;
padding: 0 0 0 $s-12; color: var(--assets-item-name-foreground-color-hover);
background-color: var(--assets-item-background-color-hover); }
margin-bottom: $s-4; .typography-name {
.typography-sample { @include titleTipography;
@include flexCenter; @include textEllipsis;
min-width: $s-24; display: flex;
font-size: $fs-16; align-items: center;
height: $s-32; justify-content: flex-start;
padding: 0; margin-left: $s-6;
color: var(--assets-item-name-foreground-color-hover); color: var(--assets-item-name-foreground-color-hover);
}
.typography-font {
@include titleTipography;
@include textEllipsis;
margin-left: $s-6;
display: flex;
align-items: center;
justify-content: flex-start;
min-width: 0;
color: var(--assets-item-name-foreground-color);
}
.action-btn {
@extend .button-tertiary;
width: $s-28;
height: $s-32;
svg {
@extend .button-icon;
} }
.typography-name { &:active {
@include titleTipography; background-color: transparent;
@include textEllipsis;
display: flex;
align-items: center;
justify-content: flex-start;
margin-left: $s-6;
color: var(--assets-item-name-foreground-color-hover);
}
.typography-font {
@include titleTipography;
@include textEllipsis;
margin-left: $s-6;
display: flex;
align-items: center;
justify-content: flex-start;
min-width: 0;
color: var(--assets-item-name-foreground-color);
}
.action-btn {
@extend .button-tertiary;
width: $s-28;
height: $s-32;
svg {
@extend .button-icon;
}
&:active {
background-color: transparent;
}
} }
} }
}
.info-row { .info-row {
display: grid; display: grid;
grid-template-columns: 50% 50%; grid-template-columns: 50% 50%;
height: $s-32; height: $s-32;
--calcualted-width: calc(var(--width) - $s-48); --calcualted-width: calc(var(--width) - $s-48);
padding-left: $s-2; padding-left: $s-2;
.info-label { .info-label {
@include titleTipography; @include titleTipography;
@include textEllipsis; @include textEllipsis;
width: calc(var(--calcualted-width) / 2); width: calc(var(--calcualted-width) / 2);
padding-top: $s-8; padding-top: $s-8;
color: var(--assets-item-name-foreground-color); color: var(--assets-item-name-foreground-color);
} }
.info-content { .info-content {
@include titleTipography; @include titleTipography;
@include textEllipsis; @include textEllipsis;
padding-top: $s-8; padding-top: $s-8;
width: calc(var(--calcualted-width) / 2); width: calc(var(--calcualted-width) / 2);
color: var(--assets-item-name-foreground-color-hover); color: var(--assets-item-name-foreground-color-hover);
}
}
.link-btn {
@include tabTitleTipography;
@extend .button-secondary;
width: 100%;
height: $s-32;
border-radius: $br-8;
&:hover {
background-color: var(--button-secondary-background-color-hover);
color: var(--button-secondary-foreground-color-hover);
border: $s-1 solid var(--button-secondary-border-color-hover);
text-decoration: none;
svg {
stroke: var(--button-secondary-foreground-color-hover);
} }
} }
&:focus {
.link-btn { background-color: var(--button-secondary-background-color-focus);
@include tabTitleTipography; color: var(--button-secondary-foreground-color-focus);
@extend .button-secondary; border: $s-1 solid var(--button-secondary-border-color-focus);
width: 100%; svg {
height: $s-32; stroke: var(--button-secondary-foreground-color-focus);
border-radius: $br-8;
&:hover {
background-color: var(--button-secondary-background-color-hover);
color: var(--button-secondary-foreground-color-hover);
border: $s-1 solid var(--button-secondary-border-color-hover);
text-decoration: none;
svg {
stroke: var(--button-secondary-foreground-color-hover);
}
}
&:focus {
background-color: var(--button-secondary-background-color-focus);
color: var(--button-secondary-foreground-color-focus);
border: $s-1 solid var(--button-secondary-border-color-focus);
svg {
stroke: var(--button-secondary-foreground-color-focus);
}
} }
} }
} }