diff --git a/CHANGES.md b/CHANGES.md index 8f5fb32edf..df3edd087a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ - Improve file menu by adding semantically groups [Github #1203](https://github.com/penpot/penpot/issues/1203) - Add update components in bulk option in context menu [Taiga #1975](https://tree.taiga.io/project/penpot/us/1975) - Create first E2E tests [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608), [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608) +- Redesign of workspace toolbars [Taiga #2319](https://tree.taiga.io/project/penpot/us/2319) ### :bug: Bugs fixed ### :arrow_up: Deps updates diff --git a/frontend/resources/styles/common/base.scss b/frontend/resources/styles/common/base.scss index 34ff9c2320..ebd5568d1e 100644 --- a/frontend/resources/styles/common/base.scss +++ b/frontend/resources/styles/common/base.scss @@ -11,6 +11,13 @@ body { display: flex; flex-direction: column; font-family: "worksans", sans-serif; + width: 100vw; + height: 100vh; + overflow: hidden; +} + +#app { + width: 100vw; height: 100vh; overflow: hidden; } diff --git a/frontend/resources/styles/main-default.scss b/frontend/resources/styles/main-default.scss index ca1c5c61b7..bb6dafbfb0 100644 --- a/frontend/resources/styles/main-default.scss +++ b/frontend/resources/styles/main-default.scss @@ -55,6 +55,7 @@ @import "main/partials/zoom-widget"; @import "main/partials/activity-bar"; @import "main/partials/color-palette"; +@import "main/partials/text-palette"; @import "main/partials/colorpicker"; @import "main/partials/dashboard"; @import "main/partials/dashboard-header"; diff --git a/frontend/resources/styles/main/layouts/handoff.scss b/frontend/resources/styles/main/layouts/handoff.scss index 087c0c6f47..59d981d227 100644 --- a/frontend/resources/styles/main/layouts/handoff.scss +++ b/frontend/resources/styles/main/layouts/handoff.scss @@ -1,4 +1,5 @@ -$width-settings-bar: 16rem; +$width-left-toolbar: 48px; +$width-settings-bar: 256px; .handoff-layout { height: 100vh; diff --git a/frontend/resources/styles/main/partials/color-bullet.scss b/frontend/resources/styles/main/partials/color-bullet.scss index c9c1acfa64..3ee47482f1 100644 --- a/frontend/resources/styles/main/partials/color-bullet.scss +++ b/frontend/resources/styles/main/partials/color-bullet.scss @@ -5,30 +5,26 @@ // Copyright (c) UXBOX Labs SL .color-cell { + display: grid; + grid-template-columns: 100%; + grid-template-rows: 1fr auto; + height: 100%; + justify-items: center; + width: 65px; + .color-bullet { - // Creates strange artifacts border: 2px solid $color-gray-60; - // box-shadow: 0 0 0 2px $color-gray-60; - border-radius: 50%; + position: relative; + width: var(--bullet-size); + height: var(--bullet-size); &:hover { border-color: $color-primary; } } - &.cell-big .color-bullet { - width: 50px; - height: 50px; - } - - &.cell-small .color-bullet { - width: 40px; - height: 40px; - } - - .color-bullet.color-big { - width: 50px; - height: 50px; + & > * { + overflow: hidden; } } @@ -41,7 +37,6 @@ ul.palette-menu .color-bullet { width: 20px; height: 20px; - border-radius: 12px; border: 1px solid $color-gray-10; margin-right: 5px; background-size: 8px; @@ -67,14 +62,12 @@ ul.palette-menu .color-bullet { grid-area: color; width: 20px; height: 20px; - border-radius: 12px; border: 1px solid $color-gray-10; background-size: 8px; } .asset-section .asset-list-item .color-bullet { border: 1px solid $color-gray-20; - border-radius: 10px; height: 20px; margin-right: $size-1; width: 20px; @@ -91,38 +84,31 @@ ul.palette-menu .color-bullet { .color-bullet { display: flex; flex-direction: row; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=") - left center; - background-color: $color-white; + border-radius: 50%; - & > * { + & .color-bullet-wrapper { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=") + left center; + background-color: $color-white; + clip-path: circle(50%); + display: flex; + flex-direction: row; + height: 100%; + width: 100%; + } + + &.is-gradient { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=") + left center; + background-color: $color-white; + } + + & .color-bullet-wrapper > * { width: 100%; height: 100%; } } -.color-bullet.is-library-color .color-bullet-left, -.selected-colors .color-bullet .color-bullet-left { - border-radius: 10px 0 0 10px; -} - -.color-bullet.is-library-color .color-bullet-right, -.selected-colors .color-bullet .color-bullet-right { - border-radius: 0 10px 10px 0; -} - -.color-palette .color-bullet .color-bullet-left { - border-radius: 25px 0 0 25px; -} - -.color-palette .color-bullet .color-bullet-right { - border-radius: 0 25px 25px 0; -} - -.color-data .color-bullet.is-library-color { - border-radius: 50%; -} - .color-data .color-bullet.multiple { background: transparent; @@ -133,7 +119,7 @@ ul.palette-menu .color-bullet { .color-data .color-bullet { border: 1px solid $color-gray-30; - border-radius: $br-small; + border-radius: 50%; cursor: pointer; display: flex; align-items: center; @@ -144,10 +130,6 @@ ul.palette-menu .color-bullet { margin: 5px 4px 0 0; width: 20px; - &.color-name { - border-radius: 10px; - } - &.palette-th { align-items: center; border: 1px solid $color-gray-30; @@ -198,3 +180,11 @@ ul.palette-menu .color-bullet { fill: $color-black; } } + +.color-data .color-bullet.is-not-library-color { + border-radius: $br-small; + + & .color-bullet-wrapper { + clip-path: none; + } +} diff --git a/frontend/resources/styles/main/partials/color-palette.scss b/frontend/resources/styles/main/partials/color-palette.scss index fb42b2418b..2edac74577 100644 --- a/frontend/resources/styles/main/partials/color-palette.scss +++ b/frontend/resources/styles/main/partials/color-palette.scss @@ -9,11 +9,10 @@ align-items: center; background-color: $color-gray-50; border-top: 1px solid $color-gray-60; - display: flex; - position: absolute; - bottom: 0; - left: 0; - width: 100%; + + display: grid; + grid-template-columns: auto auto 1fr auto auto; + z-index: 11; & .right-arrow, @@ -46,16 +45,21 @@ @include animation(0, 0.5s, fadeOutDown); } - &.left-sidebar-open { - left: 303px; - width: calc(100% - 303px); - } - & .context-menu-items { bottom: 1.5rem; top: initial; min-width: 10rem; } + + & .resize-area { + position: absolute; + height: 8px; + width: 100%; + z-index: 10; + cursor: ns-resize; + top: 0; + left: 0; + } } .color-palette-actions { @@ -119,8 +123,8 @@ display: flex; overflow: hidden; width: 100%; - height: 5rem; padding: 0.25rem; + height: 100%; &.size-small { height: 3.5rem; @@ -134,6 +138,7 @@ transition: all 0.6s ease; width: 100%; scroll-behavior: smooth; + height: 100%; } .color-cell { @@ -144,24 +149,21 @@ flex-shrink: 0; position: relative; - &.cell-big { - flex-basis: 66px; - } - - &.cell-small { - flex-basis: 52px; - } - .color-text { color: $color-gray-20; font-size: $fs12; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: 66px; + width: 65px; text-align: center; margin-top: 0.25rem; + + .no-text & { + display: none; + } } + &.current { .color-text { color: $color-gray-50; @@ -252,7 +254,7 @@ ul.palette-menu { left: 8px; top: auto; - bottom: 4.5rem; + bottom: var(--height); color: $color-black; li { diff --git a/frontend/resources/styles/main/partials/left-toolbar.scss b/frontend/resources/styles/main/partials/left-toolbar.scss index 9b5cf562e8..1c787bd96b 100644 --- a/frontend/resources/styles/main/partials/left-toolbar.scss +++ b/frontend/resources/styles/main/partials/left-toolbar.scss @@ -5,16 +5,8 @@ // Copyright (c) 2015-2020 Andrey Antukh // Copyright (c) 2015-2020 Juan de la Cruz -$width-left-toolbar: 48px; - .left-toolbar { background-color: $color-gray-50; - bottom: 0; - height: 100%; - position: fixed; - left: 0; - width: $width-left-toolbar; - z-index: 11; } .left-toolbar-inside { @@ -23,7 +15,6 @@ $width-left-toolbar: 48px; display: flex; flex-direction: column; overflow: visible; - padding-top: 48px; height: 100%; } @@ -44,6 +35,7 @@ $width-left-toolbar: 48px; justify-content: center; position: relative; width: 48px; + color: $color-gray-20; svg { fill: $color-gray-20; @@ -53,6 +45,7 @@ $width-left-toolbar: 48px; &:hover { background-color: $color-primary; + color: $color-gray-50; svg { fill: $color-gray-50; @@ -61,6 +54,7 @@ $width-left-toolbar: 48px; &.selected { background-color: $color-gray-60; + color: $color-primary; svg { fill: $color-primary; diff --git a/frontend/resources/styles/main/partials/sidebar-assets.scss b/frontend/resources/styles/main/partials/sidebar-assets.scss index eed7e64b3e..75907e30fc 100644 --- a/frontend/resources/styles/main/partials/sidebar-assets.scss +++ b/frontend/resources/styles/main/partials/sidebar-assets.scss @@ -231,15 +231,23 @@ .asset-grid { display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-columns: repeat(4, 1fr); grid-auto-rows: 6vh; column-gap: 0.5rem; row-gap: 0.5rem; &.big { - grid-template-columns: 1fr 1fr; + grid-template-columns: repeat(2, 1fr); grid-auto-rows: 10vh; + .three-row & { + grid-template-columns: repeat(3, 1fr); + } + + .four-row & { + grid-template-columns: repeat(4, 1fr); + } + .grid-cell { padding: $size-1; diff --git a/frontend/resources/styles/main/partials/sidebar-document-history.scss b/frontend/resources/styles/main/partials/sidebar-document-history.scss index 93ea710f1a..72553e3367 100644 --- a/frontend/resources/styles/main/partials/sidebar-document-history.scss +++ b/frontend/resources/styles/main/partials/sidebar-document-history.scss @@ -40,6 +40,9 @@ font-size: $fs12; color: $color-gray-20; fill: $color-gray-20; + height: 100%; + overflow-x: hidden; + overflow-y: auto; } .history-entry { diff --git a/frontend/resources/styles/main/partials/sidebar-layers.scss b/frontend/resources/styles/main/partials/sidebar-layers.scss index ce99e46335..e8747f1325 100644 --- a/frontend/resources/styles/main/partials/sidebar-layers.scss +++ b/frontend/resources/styles/main/partials/sidebar-layers.scss @@ -207,6 +207,11 @@ span.element-name { margin-left: auto; position: relative; width: 32px; + right: 20px; + + &.is-parent { + right: 0; + } svg { height: 13px; @@ -242,7 +247,7 @@ span.element-name { } .toggle-content { - margin-left: auto; + margin-left: 8px; width: 12px; svg { diff --git a/frontend/resources/styles/main/partials/sidebar-sitemap.scss b/frontend/resources/styles/main/partials/sidebar-sitemap.scss index 3a14879f97..ffc67c1371 100644 --- a/frontend/resources/styles/main/partials/sidebar-sitemap.scss +++ b/frontend/resources/styles/main/partials/sidebar-sitemap.scss @@ -5,8 +5,8 @@ // Copyright (c) 2015-2016 Andrey Antukh // Copyright (c) 2015-2016 Juan de la Cruz -.sitemap { - flex: none !important; +#sitemap { + height: var(--height, 200px); .element-list { li { @@ -118,6 +118,15 @@ } } } + + & .resize-area { + position: absolute; + width: 100%; + height: 16px; + bottom: -8px; + left: 0; + cursor: ns-resize; + } } .add-page, diff --git a/frontend/resources/styles/main/partials/sidebar.scss b/frontend/resources/styles/main/partials/sidebar.scss index 1de3a52642..e086a1d06b 100644 --- a/frontend/resources/styles/main/partials/sidebar.scss +++ b/frontend/resources/styles/main/partials/sidebar.scss @@ -5,67 +5,25 @@ // Copyright (c) 2015-2020 Andrey Antukh // Copyright (c) 2015-2020 Juan de la Cruz -$width-settings-bar: 16rem; -// This width is also used in update-viewport-size at frontend/src/app/main/data/workspace.cljs - .settings-bar { background-color: $color-gray-50; border-left: 1px solid $color-gray-60; - bottom: 0; - height: 100%; - position: fixed; - right: 0; - width: $width-settings-bar; - - &.expanded { - width: $width-settings-bar * 3; - } - - z-index: 10; - overflow-y: auto; + position: relative; &.settings-bar-left { border-left: none; border-right: 1px solid $color-gray-60; - left: 48px; + + & .tab-container-tabs { + padding-left: 1.5rem; + } } .settings-bar-inside { - align-items: flex-start; display: grid; grid-template-columns: 100%; - - &[data-layout*="sitemap-pages"] { - grid-template-rows: auto; - } - - &[data-layout*="layers"] { - grid-template-rows: auto 1fr; - } - - &[data-layout*="libraries"] { - grid-template-rows: auto 1fr; - } - - &[data-layout*="layers"][data-layout*="sitemap-pages"] { - grid-template-rows: 11.5rem 1fr; - } - - &[data-layout*="libraries"][data-layout*="sitemap-pages"] { - grid-template-rows: 11.5rem 1fr; - } - - &[data-layout*="layers"][data-layout*="libraries"] { - grid-template-rows: auto 30% 1fr; - } - - &[data-layout*="layers"][data-layout*="libraries"][data-layout*="sitemap-pages"] { - grid-template-rows: 11.5rem 25% 1fr; - } - - flex-direction: column; - padding-top: 48px; - height: 100%; + grid-template-rows: 100%; + height: calc(100% - 2px); .tool-window { position: relative; @@ -75,7 +33,6 @@ $width-settings-bar: 16rem; flex: 1; width: 100%; height: 100%; - overflow: hidden; .tool-window-bar { align-items: center; @@ -163,14 +120,30 @@ $width-settings-bar: 16rem; height: auto; } } + + & > .resize-area { + position: absolute; + width: 8px; + height: 100%; + z-index: 10; + cursor: ew-resize; + } + + &.settings-bar-left > .resize-area { + right: -8px; + } + + &.settings-bar-right > .resize-area { + left: -4px; + } } .tool-window-content { display: flex; flex-direction: column; - overflow-y: auto; height: 100%; width: 100%; + overflow-y: auto; } .element-list { @@ -222,3 +195,47 @@ $width-settings-bar: 16rem; width: 100%; } } + +button.collapse-sidebar { + background: none; + border: none; + cursor: pointer; + height: 2.5rem; + padding-top: 0.75rem; + position: absolute; + width: 1rem; + + & svg { + width: 12px; + height: 12px; + fill: $color-gray-20; + transform: rotate(180deg); + } + + &.collapsed { + background: $color-gray-60; + left: 48px; + top: 48px; + width: 28px; + height: 48px; + padding: 0; + border-radius: 0px 4px 4px 0px; + border-left: 1px solid $color-gray-50; + + & svg { + transform: rotate(0deg); + } + } +} + +#layers.tool-window { + overflow: auto; +} + +.layers-tab { + display: grid; + grid-template-rows: auto 1fr; + grid-template-columns: 100%; + height: 100%; + overflow: hidden; +} diff --git a/frontend/resources/styles/main/partials/tab-container.scss b/frontend/resources/styles/main/partials/tab-container.scss index 76417795ae..be52565e56 100644 --- a/frontend/resources/styles/main/partials/tab-container.scss +++ b/frontend/resources/styles/main/partials/tab-container.scss @@ -1,8 +1,8 @@ .tab-container { - display: flex; - flex-direction: column; + display: grid; + grid-template-rows: auto 1fr; + grid-template-columns: 100%; height: 100%; - width: 100%; } .tab-container-tabs { @@ -31,11 +31,8 @@ } .tab-container-content { - flex: 1; - height: 100%; - max-height: 100%; - overflow-x: hidden; overflow-y: auto; + overflow-x: hidden; } .tab-element, diff --git a/frontend/resources/styles/main/partials/text-palette.scss b/frontend/resources/styles/main/partials/text-palette.scss new file mode 100644 index 0000000000..b1c223da1e --- /dev/null +++ b/frontend/resources/styles/main/partials/text-palette.scss @@ -0,0 +1,26 @@ +.typography-item { + padding: 0 1rem; + margin-right: 1rem; + cursor: pointer; + + & > * { + white-space: nowrap; + } + + & .typography-name { + color: $color-white; + } + + & .typography-font, + & .typography-data { + font-size: 16px; + color: $color-gray-30; + } + + .no-text & { + & .typography-font, + & .typography-data { + display: none; + } + } +} diff --git a/frontend/resources/styles/main/partials/workspace-header.scss b/frontend/resources/styles/main/partials/workspace-header.scss index 43faf986c4..f2e20d65d6 100644 --- a/frontend/resources/styles/main/partials/workspace-header.scss +++ b/frontend/resources/styles/main/partials/workspace-header.scss @@ -5,16 +5,36 @@ // Copyright (c) UXBOX Labs SL .workspace-header { + position: relative; align-items: center; background-color: $color-gray-50; border-bottom: 1px solid $color-gray-60; display: flex; - height: 48px; padding: $size-1 $size-4 $size-1 55px; - position: relative; - z-index: 12; justify-content: space-between; + display: grid; + grid-template-areas: "left center right"; + grid-template-columns: auto 1fr auto; + grid-template-rows: 100%; + padding: 0; + + .left-area { + grid-area: left; + display: flex; + height: 100%; + } + + .center-area { + grid-area: center; + } + + .right-area { + grid-area: right; + display: flex; + height: 100%; + } + .main-icon { align-items: center; background-color: $color-gray-60; @@ -23,9 +43,6 @@ display: flex; height: 100%; justify-content: center; - left: 0; - position: absolute; - top: 0; width: 48px; a { @@ -46,6 +63,7 @@ } .menu-section { + margin-left: 1rem; display: flex; justify-content: flex-start; align-items: center; @@ -75,6 +93,8 @@ justify-content: flex-end; align-items: center; position: relative; + padding-right: 1rem; + border-right: 1px solid black; > * { margin-left: $size-5; @@ -218,7 +238,8 @@ } .active-users { - align-items: center; + flex: 1; + justify-content: center; display: flex; margin: 0; @@ -235,6 +256,26 @@ } } } + + & button.document-history { + background: $color-gray-60; + border-radius: 3px; + border: none; + cursor: pointer; + height: 24px; + padding: 3px; + width: 24px; + + & svg { + width: 18px; + fill: $color-gray-20; + height: 18px; + } + + &.selected svg { + fill: $color-primary; + } + } } .persistence-status-widget { diff --git a/frontend/resources/styles/main/partials/workspace.scss b/frontend/resources/styles/main/partials/workspace.scss index 101ec69bce..2bba2d53af 100644 --- a/frontend/resources/styles/main/partials/workspace.scss +++ b/frontend/resources/styles/main/partials/workspace.scss @@ -5,8 +5,68 @@ // Copyright (c) 2015-2016 Andrey Antukh // Copyright (c) 2015-2016 Juan de la Cruz +$width-left-toolbar: 48px; + +$width-settings-bar: 256px; +$width-settings-bar-min: 255px; +$width-settings-bar-max: 500px; + +$height-palette: 79px; +$height-palette-min: 54px; +$height-palette-max: 80px; + #workspace { + width: 100vw; + height: 100vh; user-select: none; + + display: grid; + grid-template-areas: + "header header header header" + "toolbar left-sidebar viewport right-sidebar" + "toolbar left-sidebar color-palette right-sidebar"; + + grid-template-rows: auto 1fr auto; + grid-template-columns: auto auto 1fr auto; + + .workspace-header { + grid-area: header; + height: 48px; + } + + .left-toolbar { + grid-area: toolbar; + width: $width-left-toolbar; + } + + .settings-bar.settings-bar-left { + min-width: $width-settings-bar; + max-width: 500px; + width: var(--width, $width-settings-bar); + grid-area: left-sidebar; + } + + .settings-bar.settings-bar-right { + min-width: $width-settings-bar; + max-width: 500px; + width: $width-settings-bar; + grid-area: right-sidebar; + } + + .workspace-loader { + grid-area: viewport; + } + + .workspace-content { + grid-area: viewport; + } + + .color-palette { + grid-area: color-palette; + min-height: $height-palette-min; + max-height: $height-palette-max; + height: var(--height, $height-palette); + } } .workspace-context-menu { @@ -97,7 +157,6 @@ display: flex; justify-content: center; align-items: center; - height: 100vh; svg#loader-pencil { fill: $color-gray-50; @@ -107,12 +166,8 @@ .workspace-content { background-color: $color-canvas; display: flex; - height: 100%; - width: calc(100% - #{$width-left-toolbar} - 2 * #{$width-settings-bar}); padding: 0; margin: 0; - position: fixed; - right: $width-settings-bar; &.scrolling { cursor: grab; @@ -171,14 +226,12 @@ } .workspace-viewport { - height: calc(100% - 40px); overflow: hidden; transition: none; - width: 100%; - display: grid; - grid-template-rows: 20px 100%; - grid-template-columns: 20px 100%; + grid-template-rows: 20px 1fr; + grid-template-columns: 20px 1fr; + flex: 1; } .viewport { @@ -209,10 +262,14 @@ .render-shapes { position: absolute; + width: 100%; + height: 100%; } .viewport-controls { position: absolute; + width: 100%; + height: 100%; } } diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 38613db7bf..d36dde0638 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -432,6 +432,15 @@ stored (d/concat-set flags))))))) +(defn remove-layout-flags + [& flags] + (ptk/reify ::remove-layout-flags + ptk/UpdateEvent + (update [_ state] + (update state :workspace-layout + (fn [stored] + (reduce disj stored (d/concat-set flags))))))) + ;; --- Set element options mode (defn set-options-mode @@ -481,7 +490,7 @@ (cond (or (not (mth/finite? (:width srect))) (not (mth/finite? (:height srect)))) - (assoc local :vbox (assoc size :x 0 :y 0 :left-offset 0)) + (assoc local :vbox (assoc size :x 0 :y 0)) (or (> (:width srect) width) (> (:height srect) height)) @@ -522,25 +531,46 @@ (update :y y))))))) (defn update-viewport-size - [{:keys [width height] :as size}] + [resize-type {:keys [width height] :as size}] (ptk/reify ::update-viewport-size ptk/UpdateEvent (update [_ state] (update state :workspace-local - (fn [{:keys [vport left-sidebar? zoom] :as local}] - (if (or (mth/almost-zero? width) (mth/almost-zero? height)) + (fn [{:keys [vport] :as local}] + (if (or (nil? vport) + (mth/almost-zero? width) + (mth/almost-zero? height)) ;; If we have a resize to zero just keep the old value local (let [wprop (/ (:width vport) width) hprop (/ (:height vport) height) - left-offset (if left-sidebar? 0 (/ (* -1 15 16) zoom))] - (-> local ;; This matches $width-settings-bar - (assoc :vport size) ;; in frontend/resources/styles/main/partials/sidebar.scss - (update :vbox (fn [vbox] - (-> vbox - (update :width #(/ % wprop)) - (update :height #(/ % hprop)) - (assoc :left-offset left-offset)))))))))))) + + vbox (:vbox local) + vbox-x (:x vbox) + vbox-y (:y vbox) + vbox-width (:width vbox) + vbox-height (:height vbox) + + vbox-width' (/ vbox-width wprop) + vbox-height' (/ vbox-height hprop) + + vbox-x' + (case resize-type + :left (+ vbox-x (- vbox-width vbox-width')) + :right vbox-x + (+ vbox-x (/ (- vbox-width vbox-width') 2))) + + vbox-y' + (case resize-type + :top (+ vbox-y (- vbox-height vbox-height')) + :bottom vbox-y + (+ vbox-y (/ (- vbox-height vbox-height') 2)))] + (-> local + (assoc :vport size) + (assoc-in [:vbox :x] vbox-x') + (assoc-in [:vbox :y] vbox-y') + (assoc-in [:vbox :width] vbox-width') + (assoc-in [:vbox :height] vbox-height'))))))))) (defn start-panning [] (ptk/reify ::start-panning @@ -596,14 +626,12 @@ (defn- impl-update-zoom [{:keys [vbox] :as local} center zoom] - (let [vbox (update vbox :x + (:left-offset vbox)) - new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom) + (let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom) old-zoom (:zoom local) center (if center center (gsh/center-rect vbox)) scale (/ old-zoom new-zoom) mtx (gmt/scale-matrix (gpt/point scale) center) - vbox' (gsh/transform-rect vbox mtx) - vbox' (update vbox' :x - (:left-offset vbox))] + vbox' (gsh/transform-rect vbox mtx)] (-> local (assoc :zoom new-zoom) (update :vbox merge (select-keys vbox' [:x :y :width :height]))))) diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index 7c6cc2212f..44667db499 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -17,6 +17,7 @@ [app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.undo :as dwu] [app.main.store :as st] + [app.main.ui.hooks.resize :as r] [app.util.dom :as dom])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -38,9 +39,17 @@ :command (ds/a-mod "h") :fn #(st/emit! (dw/go-to-layout :document-history))} - :toggle-palette {:tooltip (ds/alt "P") - :command (ds/a-mod "p") - :fn #(st/emit! (dw/toggle-layout-flags :colorpalette))} + :toggle-colorpalette {:tooltip (ds/alt "P") + :command (ds/a-mod "p") + :fn #(do (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :textpalette) + (dw/toggle-layout-flags :colorpalette)))} + + :toggle-textpalette {:tooltip (ds/alt "T") + :command (ds/a-mod "t") + :fn #(do (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :colorpalette) + (dw/toggle-layout-flags :textpalette)))} :toggle-rules {:tooltip (ds/meta-shift "R") :command (ds/c-mod "shift+r") @@ -338,9 +347,15 @@ :command (ds/c-mod "alt+l") :fn #(st/emit! (dw/toggle-proportion-lock))} - :create-artboard-from-selection {:tooltip (ds/meta (ds/alt "G")) - :command (ds/c-mod "alt+g") - :fn #(st/emit! (dw/create-artboard-from-selection))}}) + :create-artboard-from-selection {:tooltip (ds/meta (ds/alt "G")) + :command (ds/c-mod "alt+g") + :fn #(st/emit! (dw/create-artboard-from-selection))} + + :hide-ui {:tooltip "\\" + :command "\\" + :fn #(st/emit! (dw/toggle-layout-flags :hide-ui))} + + }) (def opacity-shortcuts (into {} (->> diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index c2efd50d84..b24e1af90d 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -92,7 +92,7 @@ (l/derived :workspace-drawing st/state)) (def selected-shapes - (l/derived wsh/lookup-selected st/state)) + (l/derived wsh/lookup-selected st/state =)) (defn make-selected-ref [id] @@ -124,6 +124,11 @@ :move-overlay-index]) workspace-local =)) +(def typography-data + (l/derived #(select-keys % [:rename-typography + :edit-typography]) + workspace-local =)) + (def local-displacement (l/derived #(select-keys % [:modifiers :selected]) workspace-local =)) @@ -158,15 +163,15 @@ (def current-hover-ids (l/derived :hover-ids context-menu)) -(def editors - (l/derived :editors workspace-local)) - (def selected-assets (l/derived :selected-assets workspace-local)) (def workspace-layout (l/derived :workspace-layout st/state)) +(def current-file-id + (l/derived :current-file-id st/state)) + (def workspace-file (l/derived (fn [state] (let [file (:workspace-file state) diff --git a/frontend/src/app/main/ui/comments.cljs b/frontend/src/app/main/ui/comments.cljs index f65abba074..7677ba4451 100644 --- a/frontend/src/app/main/ui/comments.cljs +++ b/frontend/src/app/main/ui/comments.cljs @@ -300,7 +300,7 @@ (mf/deps thread comments-map) (fn [] (when-let [node (mf/ref-val ref)] - (.scrollIntoViewIfNeeded ^js node)))) + (dom/scroll-into-view-if-needed! node)))) (when (some? comment) [:div.thread-content diff --git a/frontend/src/app/main/ui/components/color_bullet.cljs b/frontend/src/app/main/ui/components/color_bullet.cljs index 62faf19f00..aa177e0947 100644 --- a/frontend/src/app/main/ui/components/color_bullet.cljs +++ b/frontend/src/app/main/ui/components/color_bullet.cljs @@ -7,6 +7,7 @@ (ns app.main.ui.components.color-bullet (:require [app.util.color :as uc] + [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [rumext.alpha :as mf])) @@ -21,17 +22,18 @@ [:div.color-bullet.multiple {:on-click #(when on-click (on-click %))}] ;; No multiple selection - (let [color (if (string? color) {:color color :opacity 1} color) - background (if (:gradient color) (uc/color->background color) "auto")] - [:div.color-bullet.tooltip.tooltip-right {:class (if (:id color) "is-library-color" "is-not-library-color") - :on-click #(when on-click (on-click %)) - :alt (or (:name color) (:color color) (gradient-type->string (:type (:gradient color)))) - :style {:background background}} - (when (not(:gradient color)) - [:* + (let [color (if (string? color) {:color color :opacity 1} color)] + [:div.color-bullet.tooltip.tooltip-right + {:class (dom/classnames :is-library-color (some? (:id color)) + :is-not-library-color (nil? (:id color)) + :is-gradient (some? (:gradient color))) + :on-click #(when on-click (on-click %)) + :alt (or (:name color) (:color color) (gradient-type->string (:type (:gradient color))))} + (if (:gradient color) + [:div.color-bullet-wrapper {:style {:background (uc/color->background color)}}] + [:div.color-bullet-wrapper [:div.color-bullet-left {:style {:background (uc/color->background (assoc color :opacity 1))}}] - [:div.color-bullet-right {:style {:background (uc/color->background color)}}]] - )]))) + [:div.color-bullet-right {:style {:background (uc/color->background color)}}]])]))) (mf/defc color-name [{:keys [color size on-click on-double-click]}] (let [color (if (string? color) {:color color :opacity 1} color) diff --git a/frontend/src/app/main/ui/hooks/resize.cljs b/frontend/src/app/main/ui/hooks/resize.cljs new file mode 100644 index 0000000000..742066c822 --- /dev/null +++ b/frontend/src/app/main/ui/hooks/resize.cljs @@ -0,0 +1,109 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.main.ui.hooks.resize + (:require + [app.common.geom.point :as gpt] + [app.common.logging :as log] + [app.main.refs :as refs] + [app.util.dom :as dom] + [app.util.storage :refer [storage]] + [rumext.alpha :as mf])) + +(log/set-level! :warn) + +(def last-resize-type nil) + +(defn set-resize-type! [type] + (set! last-resize-type type)) + +(defn use-resize-hook + [key initial min-val max-val axis negate? resize-type] + + (let [current-file-id (mf/deref refs/current-file-id) + size-state (mf/use-state (or (get-in @storage [::saved-resize current-file-id key]) initial)) + parent-ref (mf/use-ref nil) + + dragging-ref (mf/use-ref false) + start-size-ref (mf/use-ref nil) + start-ref (mf/use-ref nil) + + on-pointer-down + (mf/use-callback + (mf/deps @size-state) + (fn [event] + (dom/capture-pointer event) + (mf/set-ref-val! start-size-ref @size-state) + (mf/set-ref-val! dragging-ref true) + (mf/set-ref-val! start-ref (dom/get-client-position event)) + (set! last-resize-type resize-type))) + + on-lost-pointer-capture + (mf/use-callback + (fn [event] + (dom/release-pointer event) + (mf/set-ref-val! start-size-ref nil) + (mf/set-ref-val! dragging-ref false) + (mf/set-ref-val! start-ref nil) + (set! last-resize-type nil))) + + on-mouse-move + (mf/use-callback + (mf/deps min-val max-val) + (fn [event] + (when (mf/ref-val dragging-ref) + (let [start (mf/ref-val start-ref) + pos (dom/get-client-position event) + delta (-> (gpt/to-vec start pos) + (cond-> negate? gpt/negate) + (get axis)) + start-size (mf/ref-val start-size-ref) + new-size (-> (+ start-size delta) (max min-val) (min max-val))] + (reset! size-state new-size) + (swap! storage assoc-in [::saved-resize current-file-id key] new-size)))))] + {:on-pointer-down on-pointer-down + :on-lost-pointer-capture on-lost-pointer-capture + :on-mouse-move on-mouse-move + :parent-ref parent-ref + :size @size-state})) + +(defn use-resize-observer + [callback] + (assert (some? callback)) + + (let [prev-val-ref (mf/use-ref nil) + current-observer-ref (mf/use-ref nil) + + ;; We use the ref as a callback when the dom node is ready (or change) + node-ref + (mf/use-callback + (mf/deps callback) + (fn [^js node] + (let [^js current-observer (mf/ref-val current-observer-ref) + ^js prev-val (mf/ref-val prev-val-ref)] + + (when (and (not= prev-val node) (some? current-observer)) + (log/debug :action "disconnect" :js/prev-val prev-val :js/node node) + (.disconnect current-observer) + (mf/set-ref-val! current-observer-ref nil)) + + (when (and (not= prev-val node) (some? node)) + (let [^js observer + (js/ResizeObserver. #(callback last-resize-type (dom/get-client-size node)))] + (mf/set-ref-val! current-observer-ref observer) + (log/debug :action "observe" :js/node node :js/observer observer) + (.observe observer node)))) + (mf/set-ref-val! prev-val-ref node)))] + + (mf/use-effect + (fn [] + ;; On dismount we need to disconnect the current observer + (fn [] + (let [current-observer (mf/ref-val current-observer-ref)] + (when (some? current-observer) + (log/debug :action "disconnect") + (.disconnect current-observer)))))) + node-ref)) diff --git a/frontend/src/app/main/ui/viewer/handoff/right_sidebar.cljs b/frontend/src/app/main/ui/viewer/handoff/right_sidebar.cljs index 53b4895a84..ac9d30d3f6 100644 --- a/frontend/src/app/main/ui/viewer/handoff/right_sidebar.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/right_sidebar.cljs @@ -45,8 +45,7 @@ [:* [:span.tool-window-bar-icon [:& si/element-icon {:shape first-shape}]] - [:span.tool-window-bar-title (->> selected-type d/name (str "handoff.tabs.code.selected.") (tr))]]) - ] + [:span.tool-window-bar-title (->> selected-type d/name (str "handoff.tabs.code.selected.") (tr))]])] [:div.tool-window-content [:& tab-container {:on-change-tab #(do (reset! expanded false) diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 541fb0b843..88d74fbfd9 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -12,6 +12,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.context :as ctx] + [app.main.ui.hooks.resize :refer [use-resize-observer]] [app.main.ui.icons :as i] [app.main.ui.workspace.colorpalette :refer [colorpalette]] [app.main.ui.workspace.colorpicker] @@ -21,10 +22,12 @@ [app.main.ui.workspace.left-toolbar :refer [left-toolbar]] [app.main.ui.workspace.libraries] [app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] + [app.main.ui.workspace.textpalette :refer [textpalette]] [app.main.ui.workspace.viewport :refer [viewport]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.object :as obj] + [debug :refer [debug?]] [okulary.core :as l] [rumext.alpha :as mf])) @@ -39,25 +42,46 @@ {:keys [options-mode]} local file (obj/get props "file") layout (obj/get props "layout") - colorpalette? (:colorpalette layout)] - [:* - (when colorpalette? [:& colorpalette]) - [:section.workspace-content + colorpalette? (:colorpalette layout) + textpalette? (:textpalette layout) + hide-ui? (:hide-ui layout) + + on-resize + (mf/use-callback + (mf/deps (:vport local)) + (fn [resize-type size] + (when (:vport local) + (st/emit! (dw/update-viewport-size resize-type size))))) + + node-ref (use-resize-observer on-resize)] + [:* + (when (and colorpalette? (not hide-ui?)) + [:& colorpalette]) + + (when (and textpalette? (not hide-ui?)) + [:& textpalette]) + + [:section.workspace-content {:ref node-ref} [:section.workspace-viewport - [:& coordinates/coordinates {:colorpalette? colorpalette?}] + (when (debug? :coordinates) + [:& coordinates/coordinates {:colorpalette? colorpalette?}]) [:& viewport {:file file :local local :selected selected :layout layout}]]] - [:& left-toolbar {:layout layout}] - - ;; Aside - [:& left-sidebar {:layout layout}] - [:& right-sidebar {:section options-mode - :selected selected}]])) + (when-not hide-ui? + [:* + [:& left-toolbar {:layout layout}] + (if (:collapse-left-sidebar layout) + [:button.collapse-sidebar.collapsed {:on-click #(st/emit! (dw/toggle-layout-flags :collapse-left-sidebar))} + i/arrow-slide] + [:& left-sidebar {:layout layout}]) + [:& right-sidebar {:section options-mode + :selected selected + :layout layout}]])])) (def trimmed-page-ref (l/derived :trimmed-page st/state =)) @@ -116,10 +140,11 @@ [:& (mf/provider ctx/current-project-id) {:value (:id project)} [:& (mf/provider ctx/current-page-id) {:value page-id} [:section#workspace - [:& header {:file file - :page-id page-id - :project project - :layout layout}] + (when (not (:hide-ui layout)) + [:& header {:file file + :page-id page-id + :project project + :layout layout}]) [:& context-menu] @@ -131,3 +156,5 @@ :layout layout}] [:& workspace-loader])]]]]])) + + diff --git a/frontend/src/app/main/ui/workspace/colorpalette.cljs b/frontend/src/app/main/ui/workspace/colorpalette.cljs index 006fdaaa5c..86b79e0f44 100644 --- a/frontend/src/app/main/ui/workspace/colorpalette.cljs +++ b/frontend/src/app/main/ui/workspace/colorpalette.cljs @@ -12,8 +12,10 @@ [app.main.store :as st] [app.main.ui.components.color-bullet :as cb] [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as i] [app.util.color :as uc] + [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.keyboard :as kbd] [app.util.object :as obj] @@ -38,7 +40,7 @@ ;; --- Components (mf/defc palette-item - [{:keys [color size]}] + [{:keys [color]}] (let [ids-with-children (map :id (mf/deref refs/selected-shapes-with-children)) select-color (fn [event] @@ -46,14 +48,13 @@ (st/emit! (mdc/change-stroke ids-with-children (merge uc/empty-color color))) (st/emit! (mdc/change-fill ids-with-children (merge uc/empty-color color)))))] - [:div.color-cell {:class (str "cell-"(name size)) - :on-click select-color} + [:div.color-cell {:on-click select-color} [:& cb/color-bullet {:color color}] - [:& cb/color-name {:color color :size size}]])) + [:& cb/color-name {:color color}]])) (mf/defc palette - [{:keys [current-colors recent-colors file-colors shared-libs selected size]}] - (let [state (mf/use-state {:show-menu false }) + [{:keys [current-colors recent-colors file-colors shared-libs selected]}] + (let [state (mf/use-state {:show-menu false}) width (:width @state 0) visible (mth/round (/ width 66)) @@ -64,6 +65,9 @@ container (mf/use-ref nil) + {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} + (use-resize-hook :palette 72 54 80 :y true :bottom) + on-left-arrow-click (mf/use-callback (mf/deps max-offset visible) @@ -111,7 +115,13 @@ (fn [] (events/unlistenByKey key1)))) - [:div.color-palette.left-sidebar-open + [:div.color-palette {:ref parent-ref + :class (dom/classnames :no-text (< size 72)) + :style #js {"--height" (str size "px") + "--bullet-size" (str (if (< size 72) (- size 15) (- size 30)) "px")}} + [:div.resize-area {:on-pointer-down on-pointer-down + :on-lost-pointer-capture on-lost-pointer-capture + :on-mouse-move on-mouse-move}] [:& dropdown {:show (:show-menu @state) :on-close #(swap! state assoc :show-menu false)} [:ul.workspace-context-menu.palette-menu @@ -146,33 +156,18 @@ [:div.color-sample (for [[idx color] (map-indexed vector (take 7 (reverse recent-colors))) ] [:& cb/color-bullet {:key (str "color-" idx) - :color color}])]] - - [:hr.dropdown-separator] - - [:li - {:on-click #(st/emit! (mdc/change-palette-size :big))} - (when (= size :big) i/tick) - (tr "workspace.libraries.colors.big-thumbnails")] - - [:li - {:on-click #(st/emit! (mdc/change-palette-size :small))} - (when (= size :small) i/tick) - (tr "workspace.libraries.colors.small-thumbnails")]]] + :color color}])]]]] [:div.color-palette-actions {:on-click #(swap! state assoc :show-menu true)} [:div.color-palette-actions-button i/actions]] [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide] - [:div.color-palette-content {:class (if (= size :big) "size-big" "size-small") - :ref container :on-wheel on-scroll} + [:div.color-palette-content {:ref container :on-wheel on-scroll} [:div.color-palette-inside {:style {:position "relative" :right (str (* 66 offset) "px")}} (for [[idx item] (map-indexed vector current-colors)] - [:& palette-item {:size size - :color item - :key idx}])]] + [:& palette-item {:color item :key idx}])]] [:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]])) @@ -183,13 +178,12 @@ (vals)))) (mf/defc colorpalette + {::mf/wrap [mf/memo]} [] (let [recent-colors (mf/deref refs/workspace-recent-colors) file-colors (mf/deref refs/workspace-file-colors) shared-libs (mf/deref refs/workspace-libraries) selected (or (mf/deref selected-palette-ref) :recent) - size (or (mf/deref selected-palette-size-ref) :big) - current-library-colors (mf/use-state [])] (mf/use-effect @@ -219,5 +213,4 @@ :recent-colors recent-colors :file-colors file-colors :shared-libs shared-libs - :selected selected - :size size}])) + :selected selected}])) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 0406b9dfb5..5f07b7dc95 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -436,10 +436,15 @@ (mf/defc viewport-context-menu [] - (let [do-paste (st/emitf dw/paste)] - [:& menu-entry {:title (tr "workspace.shape.menu.paste") - :shortcut (sc/get-tooltip :paste) - :on-click do-paste}])) + (let [do-paste (st/emitf dw/paste) + do-hide-ui (st/emitf (dw/toggle-layout-flags :hide-ui))] + [:* + [:& menu-entry {:title (tr "workspace.shape.menu.paste") + :shortcut (sc/get-tooltip :paste) + :on-click do-paste}] + [:& menu-entry {:title (tr "workspace.shape.menu.hide-ui") + :shortcut (sc/get-tooltip :hide-ui) + :on-click do-hide-ui}]])) (mf/defc context-menu [] diff --git a/frontend/src/app/main/ui/workspace/header.cljs b/frontend/src/app/main/ui/workspace/header.cljs index f400f2f7ba..038143f176 100644 --- a/frontend/src/app/main/ui/workspace/header.cljs +++ b/frontend/src/app/main/ui/workspace/header.cljs @@ -18,6 +18,7 @@ [app.main.repo :as rp] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] [app.main.ui.workspace.presence :refer [active-sessions]] [app.util.dom :as dom] @@ -297,12 +298,25 @@ (tr "workspace.header.menu.show-layers"))] [:span.shortcut (sc/get-tooltip :toggle-layers)]] - [:li {:on-click #(st/emit! (dw/toggle-layout-flags :colorpalette))} + [:li {:on-click (fn [] + (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :textpalette) + (dw/toggle-layout-flags :colorpalette)))} [:span (if (contains? layout :colorpalette) - (tr "workspace.header.menu.hide-palette") - (tr "workspace.header.menu.show-palette"))] - [:span.shortcut (sc/get-tooltip :toggle-palette)]] + (tr "workspace.header.menu.hide-colorpalette") + (tr "workspace.header.menu.show-colorpalette"))] + [:span.shortcut (sc/get-tooltip :toggle-colorpalette)]] + + [:li {:on-click (fn [] + (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :colorpalette) + (dw/toggle-layout-flags :textpalette)))} + [:span + (if (contains? layout :textpalette) + (tr "workspace.header.menu.hide-textpalette") + (tr "workspace.header.menu.show-textpalette"))] + [:span.shortcut (sc/get-tooltip :toggle-textpalette)]] [:li {:on-click #(st/emit! (dw/toggle-layout-flags :assets))} [:span @@ -360,31 +374,40 @@ (st/emitf (dw/go-to-viewer params)))] [:header.workspace-header - [:div.main-icon - [:a {:on-click go-back} i/logo-icon]] + [:div.left-area + [:div.main-icon + [:a {:on-click go-back} i/logo-icon]] - [:& menu {:layout layout - :project project - :file file - :team-id team-id - :page-id page-id}] + [:& menu {:layout layout + :project project + :file file + :team-id team-id + :page-id page-id}]] - [:div.users-section - [:& active-sessions]] + [:div.center-area + [:div.users-section + [:& active-sessions]]] - [:div.options-section - [:& persistence-state-widget] + [:div.right-area + [:div.options-section + [:& persistence-state-widget] + [:button.document-history + {:alt (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history)) + :class (when (contains? layout :document-history) "selected") + :on-click (st/emitf (dw/toggle-layout-flags :document-history))} + i/recent]] - [:& zoom-widget-workspace - {:zoom zoom - :on-increase #(st/emit! (dw/increase-zoom nil)) - :on-decrease #(st/emit! (dw/decrease-zoom nil)) - :on-zoom-reset #(st/emit! dw/reset-zoom) - :on-zoom-fit #(st/emit! dw/zoom-to-fit-all) - :on-zoom-selected #(st/emit! dw/zoom-to-selected-shape)}] + [:div.options-section + [:& zoom-widget-workspace + {:zoom zoom + :on-increase #(st/emit! (dw/increase-zoom nil)) + :on-decrease #(st/emit! (dw/decrease-zoom nil)) + :on-zoom-reset #(st/emit! dw/reset-zoom) + :on-zoom-fit #(st/emit! dw/zoom-to-fit-all) + :on-zoom-selected #(st/emit! dw/zoom-to-selected-shape)}] - [:a.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left - {:alt (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) - :on-click go-viewer} - i/play]]])) + [:a.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left + {:alt (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) + :on-click go-viewer} + i/play]]]])) diff --git a/frontend/src/app/main/ui/workspace/left_toolbar.cljs b/frontend/src/app/main/ui/workspace/left_toolbar.cljs index be41b8e6dc..dbddf07778 100644 --- a/frontend/src/app/main/ui/workspace/left_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/left_toolbar.cljs @@ -14,6 +14,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.file-uploader :refer [file-uploader]] + [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -119,22 +120,19 @@ [:ul.left-toolbar-options.panels [:li.tooltip.tooltip-right - {:alt (tr "workspace.sidebar.layers" (sc/get-tooltip :toggle-layers)) - :class (when (contains? layout :layers) "selected") - :on-click (st/emitf (dw/go-to-layout :layers))} - i/layers] + {:alt (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) + :class (when (contains? layout :textpalette) "selected") + :on-click (fn [] + (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :colorpalette) + (dw/toggle-layout-flags :textpalette)))} + "Ag"] + [:li.tooltip.tooltip-right - {:alt (tr "workspace.toolbar.assets" (sc/get-tooltip :toggle-assets)) - :class (when (contains? layout :assets) "selected") - :on-click (st/emitf (dw/go-to-layout :assets))} - i/library] - [:li.tooltip.tooltip-right - {:alt (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history)) - :class (when (contains? layout :document-history) "selected") - :on-click (st/emitf (dw/go-to-layout :document-history))} - i/recent] - [:li.tooltip.tooltip-right - {:alt (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-palette)) + {:alt (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) :class (when (contains? layout :colorpalette) "selected") - :on-click (st/emitf (dw/toggle-layout-flags :colorpalette))} + :on-click (fn [] + (r/set-resize-type! :bottom) + (st/emit! (dw/remove-layout-flags :textpalette) + (dw/toggle-layout-flags :colorpalette)))} i/palette]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index da154e26a7..6173862014 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -6,14 +6,21 @@ (ns app.main.ui.workspace.sidebar (:require + [app.main.data.workspace :as dw] [app.main.refs :as refs] + [app.main.store :as st] + [app.main.ui.components.tab-container :refer [tab-container tab-element]] + [app.main.ui.hooks.resize :refer [use-resize-hook]] + [app.main.ui.icons :as i] [app.main.ui.workspace.comments :refer [comments-sidebar]] [app.main.ui.workspace.sidebar.assets :refer [assets-toolbox]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox]] [app.main.ui.workspace.sidebar.layers :refer [layers-toolbox]] [app.main.ui.workspace.sidebar.options :refer [options-toolbox]] [app.main.ui.workspace.sidebar.sitemap :refer [sitemap]] - [cuerdas.core :as str] + [app.util.dom :as dom] + [app.util.i18n :refer [tr]] + [app.util.object :as obj] [rumext.alpha :as mf])) ;; --- Left Sidebar (Component) @@ -21,19 +28,40 @@ (mf/defc left-sidebar {:wrap [mf/memo]} [{:keys [layout ] :as props}] - [:aside.settings-bar.settings-bar-left - [:div.settings-bar-inside - {:data-layout (str/join "," layout)} - (when (contains? layout :layers) - [:* - [:& sitemap {:layout layout}] - [:& layers-toolbox]]) + (let [section (cond (contains? layout :layers) :layers + (contains? layout :assets) :assets) - (when (contains? layout :document-history) - [:& history-toolbox]) + {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} + (use-resize-hook :left-sidebar 255 255 500 :x false :left) - (when (contains? layout :assets) - [:& assets-toolbox])]]) + handle-collapse + (fn [] + (st/emit! (dw/toggle-layout-flags :collapse-left-sidebar)))] + + [:aside.settings-bar.settings-bar-left {:ref parent-ref + :class (dom/classnames + :two-row (<= size 300) + :three-row (and (> size 300) (<= size 400)) + :four-row (> size 400)) + :style #js {"--width" (str size "px")}} + [:div.resize-area {:on-pointer-down on-pointer-down + :on-lost-pointer-capture on-lost-pointer-capture + :on-mouse-move on-mouse-move}] + + [:div.settings-bar-inside + [:button.collapse-sidebar + {:on-click handle-collapse} + i/arrow-slide] + [:& tab-container {:on-change-tab #(st/emit! (dw/go-to-layout %)) + :selected section} + + [:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")} + [:div.layers-tab + [:& sitemap {:layout layout}] + [:& layers-toolbox]]] + + [:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")} + [:& assets-toolbox]]]]])) ;; --- Right Sidebar (Component) @@ -41,10 +69,18 @@ {::mf/wrap-props false ::mf/wrap [mf/memo]} [props] - (let [drawing-tool (:tool (mf/deref refs/workspace-drawing))] - [:aside.settings-bar + (let [layout (obj/get props "layout") + drawing-tool (:tool (mf/deref refs/workspace-drawing))] + + [:aside.settings-bar.settings-bar-right [:div.settings-bar-inside - (if (= drawing-tool :comments) + (cond + (= drawing-tool :comments) [:& comments-sidebar] + + (contains? layout :document-history) + [:& history-toolbox] + + :else [:> options-toolbox props])]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 13b6506961..ca278502c9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -1087,7 +1087,7 @@ ;; ---- Typography box ---- (mf/defc typographies-group - [{:keys [file-id prefix groups open-groups file local? selected-typographies local + [{:keys [file-id prefix groups open-groups file local? selected-typographies local-data editing-id on-asset-click handle-change apply-typography on-rename-group on-ungroup on-context-menu]}] (let [group-open? (get open-groups prefix true)] @@ -1115,7 +1115,7 @@ :on-click #(on-asset-click % (:id typography) (partial apply-typography typography)) :editing? (= editing-id (:id typography)) - :focus-name? (= (:rename-typography local) (:id typography))}])]) + :focus-name? (= (:rename-typography local-data) (:id typography))}])]) (for [[path-item content] groups] (when-not (empty? path-item) @@ -1127,7 +1127,7 @@ :local? local? :selected-typographies selected-typographies :editing-id editing-id - :local local + :local-data local-data :on-asset-click on-asset-click :handle-change handle-change :apply-typography apply-typography @@ -1141,11 +1141,9 @@ (let [state (mf/use-state {:detail-open? false :id nil}) + local-data (mf/deref refs/typography-data) menu-state (mf/use-state auto-pos-menu-state) - - local (deref refs/workspace-local) - - groups (group-assets typographies reverse-sort?) + groups (group-assets typographies reverse-sort?) selected-typographies (:typographies selected-assets) multi-typographies? (> (count selected-typographies) 1) @@ -1174,7 +1172,11 @@ {:typography-ref-file file-id :typography-ref-id (:id typography)} (dissoc typography :id :name))] - (run! #(st/emit! (dwt/update-text-attrs {:id % :editor (get-in local [:editors %]) :attrs attrs})) + (run! #(st/emit! + (dwt/update-text-attrs + {:id % + :editor (get @refs/workspace-editor-state %) + :attrs attrs})) ids))) create-group @@ -1273,14 +1275,15 @@ (dwl/sync-file file-id file-id) (dwu/commit-undo-transaction))))) - editing-id (or (:rename-typography local) (:edit-typography local))] + editing-id (or (:rename-typography local-data) + (:edit-typography local-data))] (mf/use-effect - (mf/deps local) + (mf/deps local-data) (fn [] - (when (:rename-typography local) + (when (:rename-typography local-data) (st/emit! #(update % :workspace-local dissoc :rename-typography))) - (when (:edit-typography local) + (when (:edit-typography local-data) (st/emit! #(update % :workspace-local dissoc :edit-typography))))) [:& asset-section {:file-id file-id @@ -1303,7 +1306,7 @@ :local? local? :selected-typographies selected-typographies :editing-id editing-id - :local local + :local-data local-data :on-asset-click (partial on-asset-click groups) :handle-change handle-change :apply-typography apply-typography diff --git a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs index 6d3fff53da..e18483c09f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs @@ -180,12 +180,17 @@ :name (:name item)})] (mf/use-effect - (mf/deps selected) + (mf/deps selected? selected) (fn [] - (let [subid - (when (and (= (count selected) 1) selected?) - (ts/schedule-on-idle - #(.scrollIntoView (mf/ref-val dref) #js {:block "nearest", :behavior "smooth"})))] + (let [single? (= (count selected) 1) + node (mf/ref-val dref) + + subid + (when (and single? selected?) + (ts/schedule + 100 + #(dom/scroll-into-view! node #js {:block "nearest", :behavior "smooth"})))] + #(when (some? subid) (rx/dispose! subid))))) @@ -208,7 +213,7 @@ :on-start-edit #(reset! disable-drag true) :on-stop-edit #(reset! disable-drag false)}] - [:div.element-actions + [:div.element-actions {:class (when (:shapes item) "is-parent")} [:div.toggle-element {:class (when (:hidden item) "selected") :on-click toggle-visibility} (if (:hidden item) i/eye-closed i/eye)] @@ -247,6 +252,7 @@ {::mf/wrap [#(mf/memo % =)]} [{:keys [objects] :as props}] (let [selected (mf/deref refs/selected-shapes) + selected (hooks/use-equal-memo selected) root (get objects uuid/zero)] [:ul.element-list [:& hooks/sortable-container {} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs index 733fd420b8..7e42847e26 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.workspace.sidebar.options.common (:require + [app.util.dom :as dom] [rumext.alpha :as mf])) (mf/defc advanced-options [{:keys [visible? children]}] @@ -15,7 +16,7 @@ (fn [] (when-let [node (mf/ref-val ref)] (when visible? - (.scrollIntoViewIfNeeded ^js node))))) + (dom/scroll-into-view-if-needed! node))))) (when visible? [:div.advanced-options-wrapper {:ref ref} diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index d2a65a52b5..56ed2bf760 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -14,6 +14,7 @@ [app.main.ui.components.context-menu :refer [context-menu]] [app.main.ui.context :as ctx] [app.main.ui.hooks :as hooks] + [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -106,7 +107,7 @@ (fn [] (when selected? (let [node (mf/ref-val dref)] - (.scrollIntoViewIfNeeded ^js node))))) + (dom/scroll-into-view-if-needed! node))))) (mf/use-layout-effect (mf/deps (:edition @local)) @@ -205,10 +206,14 @@ :project-id (:project-id file)})))) show-pages? (mf/use-state true) + {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} + (use-resize-hook :sitemap 200 38 400 :y false nil) + toggle-pages (mf/use-callback #(reset! show-pages? not))] - [:div.sitemap.tool-window + [:div#sitemap.tool-window {:ref parent-ref + :style #js {"--height" (str size "px")}} [:div.tool-window-bar [:span (tr "workspace.sidebar.sitemap")] [:div.add-page {:on-click create} i/close] @@ -216,4 +221,8 @@ (when @show-pages? [:div.tool-window-content - [:& pages-list {:file file :key (:id file)}]])])) + [:& pages-list {:file file :key (:id file)}]]) + + [:div.resize-area {:on-pointer-down on-pointer-down + :on-lost-pointer-capture on-lost-pointer-capture + :on-mouse-move on-mouse-move}]])) diff --git a/frontend/src/app/main/ui/workspace/textpalette.cljs b/frontend/src/app/main/ui/workspace/textpalette.cljs new file mode 100644 index 0000000000..4d9ca61586 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/textpalette.cljs @@ -0,0 +1,152 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.main.ui.workspace.textpalette + (:require + [app.common.data :as d] + [app.main.data.workspace.texts :as dwt] + [app.main.fonts :as f] + [app.main.refs :as refs] + [app.main.store :as st] + [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.context :as ctx] + [app.main.ui.hooks.resize :refer [use-resize-hook]] + [app.main.ui.icons :as i] + [app.util.dom :as dom] + [app.util.i18n :refer [tr]] + [cuerdas.core :as str] + [rumext.alpha :as mf])) + +(mf/defc typography-item + [{:keys [file-id selected-ids typography name-only?]}] + (let [font-data (f/get-font-data (:font-id typography)) + font-variant-id (:font-variant-id typography) + variant-data (->> font-data :variants (d/seek #(= (:id %) font-variant-id))) + + handle-click + (mf/use-callback + (mf/deps typography selected-ids) + (fn [] + (let [attrs (merge + {:typography-ref-file file-id + :typography-ref-id (:id typography)} + (dissoc typography :id :name))] + + (run! #(st/emit! + (dwt/update-text-attrs + {:id % + :editor (get @refs/workspace-editor-state %) + :attrs attrs})) + selected-ids))))] + + [:div.typography-item {:on-click handle-click} + [:div.typography-name + {:style {:font-family (:font-family typography) + :font-weight (:font-weight typography) + :font-style (:font-style typography)}} + (:name typography)] + (when-not name-only? + [:* + [:div.typography-font (:name font-data)] + [:div.typography-data (str (:font-size typography) "pt | " (:name variant-data))]])])) + +(mf/defc palette + [{:keys [selected-ids current-file-id file-typographies shared-libs]}] + + (let [state (mf/use-state {:show-menu false}) + selected (mf/use-state :file) + + file-id + (case @selected + :recent nil + :file current-file-id + @selected) + + current-typographies + (case @selected + :recent [] + :file (vals file-typographies) + (vals (get-in shared-libs [@selected :data :typographies]))) + + container (mf/use-ref nil) + + on-left-arrow-click + (mf/use-callback + (fn [] + (when-let [node (mf/ref-val container)] + (.scrollBy node #js {:left -200 :behavior "smooth"})))) + + on-right-arrow-click + (mf/use-callback + (fn [] + (when-let [node (mf/ref-val container)] + (.scrollBy node #js {:left 200 :behavior "smooth"})))) + + on-wheel + (mf/use-callback + (fn [event] + (let [delta (+ (.. event -nativeEvent -deltaY) (.. event -nativeEvent -deltaX))] + (if (pos? delta) + (on-right-arrow-click) + (on-left-arrow-click))))) + + {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} + (use-resize-hook :palette 72 54 80 :y true :bottom)] + + [:div.color-palette {:ref parent-ref + :class (dom/classnames :no-text (< size 72)) + :style #js {"--height" (str size "px")}} + [:div.resize-area {:on-pointer-down on-pointer-down + :on-lost-pointer-capture on-lost-pointer-capture + :on-mouse-move on-mouse-move}] + [:& dropdown {:show (:show-menu @state) + :on-close #(swap! state assoc :show-menu false)} + + [:ul.workspace-context-menu.palette-menu + (for [[idx cur-library] (map-indexed vector (vals shared-libs))] + (let [typographies (-> cur-library (get-in [:data :typographies]) vals)] + [:li.palette-library + {:key (str "library-" idx) + :on-click #(reset! selected (:id cur-library))} + + (when (= @selected (:id cur-library)) i/tick) + + [:div.library-name (str (:name cur-library) " " (str/format "(%s)" (count typographies)))]])) + + [:li.palette-library + {:on-click #(reset! selected :file)} + (when (= selected :file) i/tick) + [:div.library-name (str (tr "workspace.libraries.colors.file-library") + (str/format " (%s)" (count file-typographies)))]]]] + + [:div.color-palette-actions + {:on-click #(swap! state assoc :show-menu true)} + [:div.color-palette-actions-button i/actions]] + + [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide] + + [:div.color-palette-content {:ref container :on-wheel on-wheel} + [:div.color-palette-inside + (for [[idx item] (map-indexed vector current-typographies)] + [:& typography-item + {:key idx + :file-id file-id + :selected-ids selected-ids + :typography item}])]] + + [:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]])) + +(mf/defc textpalette + {::mf/wrap [mf/memo]} + [] + (let [selected-ids (mf/deref refs/selected-shapes) + file-typographies (mf/deref refs/workspace-file-typography) + shared-libs (mf/deref refs/workspace-libraries) + current-file-id (mf/use-ctx ctx/current-file-id)] + [:& palette {:current-file-id current-file-id + :selected-ids selected-ids + :file-typographies file-typographies + :shared-libs shared-libs}])) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 4c673a565a..35e8f44b12 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -156,14 +156,13 @@ show-selrect? (and selrect (empty? drawing)) show-measures? (and (not transform) (not node-editing?) show-distances?) show-artboard-names? (contains? layout :display-artboard-names) - show-rules? (contains? layout :rules) + show-rules? (and (contains? layout :rules) (not (contains? layout :hide-ui))) disabled-guides? (or drawing-tool transform)] (hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport?) (hooks/setup-viewport-size viewport-ref) (hooks/setup-cursor cursor alt? panning drawing-tool drawing-path? node-editing?) - (hooks/setup-resize layout viewport-ref) (hooks/setup-keyboard alt? ctrl? space?) (hooks/setup-hover-shapes page-id move-stream base-objects transform selected ctrl? hover hover-ids @hover-disabled? zoom) (hooks/setup-viewport-modifiers modifiers base-objects) @@ -222,8 +221,6 @@ :xmlnsXlink "http://www.w3.org/1999/xlink" :preserveAspectRatio "xMidYMid meet" :key (str "viewport" page-id) - :width (:width vport 0) - :height (:height vport 0) :view-box (utils/format-viewbox vbox) :ref viewport-ref :class (when drawing-tool "drawing") @@ -370,7 +367,8 @@ [:* [:& rules/rules {:zoom zoom - :vbox vbox}] + :vbox vbox + :selected-shapes selected-shapes}] [:& guides/viewport-guides {:zoom zoom diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index 54b46e727f..4862883743 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -492,11 +492,3 @@ (when (and (not (#{"INPUT" "TEXTAREA"} tag-name)) (not @disable-paste)) (st/emit! (dw/paste-from-event event @in-viewport?))))))) -(defn on-resize [viewport-ref] - (mf/use-callback - (fn [_] - (let [node (mf/ref-val viewport-ref) - prnt (dom/get-parent node) - size (dom/get-client-size prnt)] - ;; We schedule the event so it fires after `initialize-page` event - (timers/schedule #(st/emit! (dw/update-viewport-size size))))))) diff --git a/frontend/src/app/main/ui/workspace/viewport/guides.cljs b/frontend/src/app/main/ui/workspace/viewport/guides.cljs index f18d913f61..2a179628c7 100644 --- a/frontend/src/app/main/ui/workspace/viewport/guides.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/guides.cljs @@ -29,6 +29,11 @@ (def guide-pill-corner-radius 4) (def guide-active-area 16) +(def guide-creation-margin-left 8) +(def guide-creation-margin-top 28) +(def guide-creation-width 16) +(def guide-creation-height 24) + (defn use-guide "Hooks to support drag/drop for existing guides and new guides" [on-guide-change get-hover-frame zoom {:keys [position axis frame-id]}] @@ -220,15 +225,15 @@ (defn guide-creation-area [vbox zoom axis] (if (= axis :x) - {:x (:x vbox) + {:x (+ (:x vbox) (/ guide-creation-margin-left zoom)) :y (:y vbox) - :width (/ 24 zoom) + :width (/ guide-creation-width zoom) :height (:height vbox)} - {:x (:x vbox) + {:x (+ (:x vbox) (+ guide-creation-margin-top zoom)) :y (:y vbox) :width (:width vbox) - :height (/ 24 zoom)})) + :height (/ guide-creation-height zoom)})) (defn is-guide-inside-frame? [guide frame] diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 33cf92fe38..21ea3e7001 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -31,10 +31,9 @@ on-key-up (actions/on-key-up) on-mouse-move (actions/on-mouse-move viewport-ref zoom) on-mouse-wheel (actions/on-mouse-wheel viewport-ref zoom) - on-resize (actions/on-resize viewport-ref) on-paste (actions/on-paste disable-paste in-viewport?)] (mf/use-layout-effect - (mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-resize on-paste) + (mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-paste) (fn [] (let [node (mf/ref-val viewport-ref) keys [(events/listen js/document EventType.KEYDOWN on-key-down) @@ -43,7 +42,6 @@ ;; bind with passive=false to allow the event to be cancelled ;; https://stackoverflow.com/a/57582286/3219895 (events/listen js/window EventType.WHEEL on-mouse-wheel #js {:passive false}) - (events/listen js/window EventType.RESIZE on-resize) (events/listen js/window EventType.PASTE on-paste)]] (fn [] @@ -52,12 +50,12 @@ (defn setup-viewport-size [viewport-ref] (mf/use-layout-effect - (fn [] - (let [node (mf/ref-val viewport-ref) - prnt (dom/get-parent node) - size (dom/get-client-size prnt)] - ;; We schedule the event so it fires after `initialize-page` event - (timers/schedule #(st/emit! (dw/initialize-viewport size))))))) + (fn [] + (let [node (mf/ref-val viewport-ref) + prnt (dom/get-parent node) + size (dom/get-client-size prnt)] + ;; We schedule the event so it fires after `initialize-page` event + (timers/schedule #(st/emit! (dw/initialize-viewport size))))))) (defn setup-cursor [cursor alt? panning drawing-tool drawing-path? path-editing?] (mf/use-effect @@ -80,10 +78,6 @@ (when (not= @cursor new-cursor) (reset! cursor new-cursor)))))) -(defn setup-resize [layout viewport-ref] - (let [on-resize (actions/on-resize viewport-ref)] - (mf/use-layout-effect (mf/deps layout) on-resize))) - (defn setup-keyboard [alt? ctrl? space?] (hooks/use-stream ms/keyboard-alt #(reset! alt? %)) (hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %)) diff --git a/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs b/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs index 3c09e952f3..fb35ba9976 100644 --- a/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs @@ -25,7 +25,7 @@ (:import goog.events.EventType)) (defn format-viewbox [vbox] - (str/join " " [(+ (:x vbox 0) (:left-offset vbox 0)) + (str/join " " [(:x vbox 0) (:y vbox 0) (:width vbox 0) (:height vbox 0)])) diff --git a/frontend/src/app/main/ui/workspace/viewport/rules.cljs b/frontend/src/app/main/ui/workspace/viewport/rules.cljs index 6b21452744..eac0324035 100644 --- a/frontend/src/app/main/ui/workspace/viewport/rules.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/rules.cljs @@ -8,13 +8,25 @@ (:require [app.common.colors :as colors] [app.common.data :as d] + [app.common.geom.shapes :as gsh] [app.common.math :as mth] + [app.main.ui.hooks :as hooks] [app.util.object :as obj] [rumext.alpha :as mf])) (def rules-pos 15) (def rules-size 4) (def rules-width 1) +(def rule-area-size 22) +(def rule-area-half-size (/ rule-area-size 2)) +(def rules-background "var(--color-gray-50)") +(def selection-area-color "var(--color-primary)") +(def selection-area-opacity 0.3) +(def over-number-size 50) +(def over-number-opacity 0.7) + +(def font-size 13) +(def font-family "sourcesanspro") ;; ---------------- ;; RULES @@ -53,6 +65,21 @@ height (- (:height vbox) (/ 21 zoom))] {:x x :y y :width width :height height}))) +(defn get-background-area + [vbox zoom axis] + (if (= axis :x) + (let [x (:x vbox) + y (:y vbox) + width (:width vbox) + height (/ rule-area-size zoom)] + {:x x :y y :width width :height height}) + + (let [x (:x vbox) + y (+ (:y vbox) (/ rule-area-size zoom)) + width (/ rule-area-size zoom) + height (- (:height vbox) (/ 21 zoom))] + {:x x :y y :width width :height height}))) + (defn get-rule-params [vbox axis] (if (= axis :x) @@ -89,49 +116,156 @@ step (calculate-step-size zoom) clip-id (str "clip-rule-" (d/name axis))] - [:g.rules {:clipPath (str "url(#" clip-id ")")} + + [:* + (let [{:keys [x y width height]} (get-background-area vbox zoom axis)] + [:rect {:x x :y y :width width :height height :style {:fill rules-background}}]) - [:defs - [:clipPath {:id clip-id} - (let [{:keys [x y width height]} (get-clip-area vbox zoom axis)] - [:rect {:x x :y y :width width :height height}])]] + [:g.rules {:clipPath (str "url(#" clip-id ")")} - (let [{:keys [start end]} (get-rule-params vbox axis) - minv (max (mth/round start) -100000) - minv (* (mth/ceil (/ minv step)) step) - maxv (min (mth/round end) 100000) - maxv (* (mth/floor (/ maxv step)) step)] + [:defs + [:clipPath {:id clip-id} + (let [{:keys [x y width height]} (get-clip-area vbox zoom axis)] + [:rect {:x x :y y :width width :height height}])]] - (for [step-val (range minv (inc maxv) step)] - (let [{:keys [text-x text-y line-x1 line-y1 line-x2 line-y2]} - (get-rule-axis step-val vbox zoom axis)] - [:* - [:text {:key (str "text-" (d/name axis) "-" step-val) - :x text-x - :y text-y - :text-anchor "middle" - :dominant-baseline "middle" - :transform (when (= axis :y) (str "rotate(-90 " text-x "," text-y ")")) - :style {:font-size (/ 13 zoom) - :font-family "sourcesanspro" - :fill colors/gray-30}} - (str (mth/round step-val))] + - [:line {:key (str "line-" (d/name axis) "-" step-val) - :x1 line-x1 - :y1 line-y1 - :x2 line-x2 - :y2 line-y2 - :style {:stroke colors/gray-30 - :stroke-width rules-width}}]])))])) + (let [{:keys [start end]} (get-rule-params vbox axis) + minv (max (mth/round start) -100000) + minv (* (mth/ceil (/ minv step)) step) + maxv (min (mth/round end) 100000) + maxv (* (mth/floor (/ maxv step)) step)] + + (for [step-val (range minv (inc maxv) step)] + (let [{:keys [text-x text-y line-x1 line-y1 line-x2 line-y2]} + (get-rule-axis step-val vbox zoom axis)] + [:* + [:text {:key (str "text-" (d/name axis) "-" step-val) + :x text-x + :y text-y + :text-anchor "middle" + :dominant-baseline "middle" + :transform (when (= axis :y) (str "rotate(-90 " text-x "," text-y ")")) + :style {:font-size (/ font-size zoom) + :font-family font-family + :fill colors/gray-30}} + (str (mth/round step-val))] + + [:line {:key (str "line-" (d/name axis) "-" step-val) + :x1 line-x1 + :y1 line-y1 + :x2 line-x2 + :y2 line-y2 + :style {:stroke colors/gray-30 + :stroke-width rules-width}}]])))]])) + +(mf/defc selection-area + [{:keys [vbox zoom selection-rect]}] + [:g.selection-area + [:g + [:rect {:x (:x selection-rect) + :y (:y vbox) + :width (:width selection-rect) + :height (/ rule-area-size zoom) + :style {:fill selection-area-color + :fill-opacity selection-area-opacity}}] + + [:rect {:x (- (:x selection-rect) (/ over-number-size zoom)) + :y (:y vbox) + :width (/ over-number-size zoom) + :height (/ rule-area-size zoom) + :style {:fill rules-background + :fill-opacity over-number-opacity}}] + + [:text {:x (- (:x1 selection-rect) (/ 4 zoom)) + :y (+ (:y vbox) (/ 12 zoom)) + :text-anchor "end" + :dominant-baseline "middle" + :style {:font-size (/ font-size zoom) + :font-family font-family + :fill selection-area-color}} + (str (mth/round (:x1 selection-rect)))] + + [:rect {:x (:x2 selection-rect) + :y (:y vbox) + :width (/ over-number-size zoom) + :height (/ rule-area-size zoom) + :style {:fill rules-background + :fill-opacity over-number-opacity}}] + + [:text {:x (+ (:x2 selection-rect) (/ 4 zoom)) + :y (+ (:y vbox) (/ 12 zoom)) + :text-anchor "start" + :dominant-baseline "middle" + :style {:font-size (/ font-size zoom) + :font-family font-family + :fill selection-area-color}} + (str (mth/round (:x2 selection-rect)))]] + + (let [center-x (+ (:x vbox) (/ rule-area-half-size zoom)) + center-y (- (+ (:y selection-rect) (/ (:height selection-rect) 2)) (/ rule-area-half-size zoom))] + + [:g {:transform (str "rotate(-90 " center-x "," center-y ")")} + [:rect {:x (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom)) + :y (- center-y (/ rule-area-half-size zoom)) + :width (:height selection-rect) + :height (/ rule-area-size zoom) + :style {:fill selection-area-color + :fill-opacity selection-area-opacity}}] + + [:rect {:x (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom) (/ over-number-size zoom)) + :y (- center-y (/ rule-area-half-size zoom)) + :width (/ over-number-size zoom) + :height (/ rule-area-size zoom) + :style {:fill rules-background + :fill-opacity over-number-opacity}}] + + [:rect {:x (+ (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom) ) (:height selection-rect)) + :y (- center-y (/ rule-area-half-size zoom)) + :width (/ over-number-size zoom) + :height (/ rule-area-size zoom) + :style {:fill rules-background + :fill-opacity over-number-opacity}}] + + [:text {:x (- center-x (/ (:height selection-rect) 2) (/ 15 zoom)) + :y center-y + :text-anchor "end" + :dominant-baseline "middle" + :style {:font-size (/ font-size zoom) + :font-family font-family + :fill selection-area-color}} + (str (mth/round (:y2 selection-rect)))] + + [:text {:x (+ center-x (/ (:height selection-rect) 2) ) + :y center-y + :text-anchor "start" + :dominant-baseline "middle" + :style {:font-size (/ font-size zoom) + :font-family font-family + :fill selection-area-color}} + (str (mth/round (:y1 selection-rect)))]])]) (mf/defc rules {::mf/wrap-props false - ::mf/wrap [mf/memo]} + ::mf/wrap [#(mf/memo' % (mf/check-props ["zoom" "vbox" "selected-shapes"]))]} [props] - (let [zoom (obj/get props "zoom") - vbox (obj/get props "vbox")] + (let [zoom (obj/get props "zoom") + vbox (obj/get props "vbox") + selected-shapes (-> (obj/get props "selected-shapes") + (hooks/use-equal-memo)) + + selection-rect + (mf/use-memo + (mf/deps selected-shapes) + #(when (d/not-empty? selected-shapes) + (gsh/selection-rect selected-shapes)))] + (when (some? vbox) [:g.rules {:pointer-events "none"} [:& rules-axis {:zoom zoom :vbox vbox :axis :x}] - [:& rules-axis {:zoom zoom :vbox vbox :axis :y}]]))) + [:& rules-axis {:zoom zoom :vbox vbox :axis :y}] + + (when (some? selection-rect) + [:& selection-area {:zoom zoom + :vbox vbox + :selection-rect selection-rect}])]))) diff --git a/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs b/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs index be47a40cf8..70aa9746c2 100644 --- a/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs @@ -15,6 +15,16 @@ [app.util.dom :as dom] [rumext.alpha :as mf])) +(def scroll-x 10) +(def scroll-y 10) +(def scroll-height (+ scroll-x 4)) +(def scroll-width (+ scroll-y 4)) +(def other-x 26) +(def other-y 26) +(def other-width 100) +(def other-height 100) + + (mf/defc viewport-scrollbars {::mf/wrap [mf/memo]} [{:keys [objects viewport-ref zoom vbox]}] @@ -49,8 +59,8 @@ (gsh/selection-rect shapes)))) inv-zoom (/ 1 zoom) - vbox-height (- (:height vbox) (* inv-zoom 44)) - vbox-width (- (:width vbox) (* inv-zoom 34)) + vbox-height (- (:height vbox) (* inv-zoom scroll-height)) + vbox-width (- (:width vbox) (* inv-zoom scroll-width)) ;; top space hidden because of the scroll top-offset (-> (- vbox-y (:y base-objects-rect)) @@ -78,28 +88,28 @@ show-v-scroll? (or @v-scrolling? (> top-offset 0) (> bottom-offset 0)) show-h-scroll? (or @h-scrolling? (> left-offset 0) (> right-offset 0)) - v-scrollbar-x (+ vbox-x (:width vbox) (* inv-zoom -32)) + v-scrollbar-x (+ vbox-x (:width vbox) (* inv-zoom (- scroll-x))) v-scrollbar-y (+ vbox-y top-offset) h-scrollbar-x (+ vbox-x left-offset) - h-scrollbar-y (+ vbox-y (:height vbox) (* inv-zoom -40)) + h-scrollbar-y (+ vbox-y (:height vbox) (* inv-zoom (- scroll-y))) scrollbar-height (-> (- (+ vbox-y vbox-height) bottom-offset v-scrollbar-y)) scrollbar-height (-> (cond @v-scrolling? scrollbar-height-stored :else scrollbar-height) - (max (* inv-zoom 100))) + (max (* inv-zoom other-height))) scrollbar-width (-> (- (+ vbox-x vbox-width) right-offset h-scrollbar-x)) scrollbar-width (-> (cond @h-scrolling? scrollbar-width-stored :else scrollbar-width) - (max (* inv-zoom 100))) + (max (* inv-zoom other-width))) v-scrollbar-y (-> (cond @v-scrolling? (- v-scrollbar-y-stored (- (- vbox-y (mf/ref-val vbox-y-ref)))) :else v-scrollbar-y) - (max (+ vbox-y (* inv-zoom 26)))) + (max (+ vbox-y (* inv-zoom other-y)))) v-scrollbar-y (if (> (+ v-scrollbar-y scrollbar-height) (+ vbox-y vbox-height)) ;; the scroll bar is stick to the bottom (-> (+ vbox-y vbox-height) @@ -109,7 +119,7 @@ h-scrollbar-x (-> (cond @h-scrolling? (- h-scrollbar-x-stored (- (- vbox-x (mf/ref-val vbox-x-ref)))) :else h-scrollbar-x) - (max (+ vbox-x (* inv-zoom 26)))) + (max (+ vbox-x (* inv-zoom other-x)))) h-scrollbar-x (if (> (+ h-scrollbar-x scrollbar-width) (+ vbox-x vbox-width)) ;; the scroll bar is stick to the right (-> (+ vbox-x vbox-width) diff --git a/frontend/src/app/main/ui/workspace/viewport/utils.cljs b/frontend/src/app/main/ui/workspace/viewport/utils.cljs index b7c6ff280d..9c0734afaa 100644 --- a/frontend/src/app/main/ui/workspace/viewport/utils.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/utils.cljs @@ -148,7 +148,7 @@ (dom/remove-attribute node "transform"))))))) (defn format-viewbox [vbox] - (str/join " " [(+ (:x vbox 0) (:left-offset vbox 0)) + (str/join " " [(:x vbox 0) (:y vbox 0) (:width vbox 0) (:height vbox 0)])) diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index e6505c51a8..b202fab0ff 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -407,21 +407,19 @@ (defn scroll-into-view! ([^js element] - (when (some? element) - (.scrollIntoView element false))) + (scroll-into-view! element false)) - ([^js element scroll-top] + ([^js element options] (when (some? element) - (.scrollIntoView element scroll-top)))) + (.scrollIntoView element options)))) (defn scroll-into-view-if-needed! ([^js element] - (when (some? element) - (.scrollIntoViewIfNeeded ^js element false))) + (scroll-into-view-if-needed! element false)) - ([^js element scroll-top] + ([^js element options] (when (some? element) - (.scrollIntoViewIfNeeded ^js element scroll-top)))) + (.scrollIntoViewIfNeeded ^js element options)))) (defn is-in-viewport? [^js element] diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs index ef4bb46e57..50f93a7bd7 100644 --- a/frontend/src/debug.cljs +++ b/frontend/src/debug.cljs @@ -278,3 +278,8 @@ dw/reset-zoom (dw/update-viewport-position {:x (constantly 0) :y (constantly 0)}))) + +(defn ^:export hide-ui + [] + (st/emit! + (dw/toggle-layout-flags :hide-ui))) diff --git a/frontend/translations/ca.po b/frontend/translations/ca.po index af16177e50..9976f5e048 100644 --- a/frontend/translations/ca.po +++ b/frontend/translations/ca.po @@ -3127,7 +3127,7 @@ msgstr "Historial (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Capes (%s)" +msgstr "Capes" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3143,7 +3143,7 @@ msgstr "Mapa del lloc" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Recursos (%s)" +msgstr "Recursos" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/de.po b/frontend/translations/de.po index f9389599f6..beafaf1319 100644 --- a/frontend/translations/de.po +++ b/frontend/translations/de.po @@ -3032,7 +3032,7 @@ msgstr "Verlauf (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Ebenen (%s)" +msgstr "Ebenen" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3048,7 +3048,7 @@ msgstr "Sitemap" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Assets (%s)" +msgstr "Assets" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/el.po b/frontend/translations/el.po index 8ad56d4dba..f3100b1c49 100644 --- a/frontend/translations/el.po +++ b/frontend/translations/el.po @@ -2163,7 +2163,7 @@ msgstr "Ιστορικό (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "στρώσεις (%s)" +msgstr "στρώσεις" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -2179,7 +2179,7 @@ msgstr "Χάρτης ιστοτόπου" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Στοιχεία (%s)" +msgstr "Στοιχεία" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 1f575ac6e2..7dbf326b7e 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -3244,7 +3244,7 @@ msgstr "History (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Layers (%s)" +msgstr "Layers" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3260,7 +3260,7 @@ msgstr "Sitemap" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Assets (%s)" +msgstr "Assets" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" @@ -3430,4 +3430,7 @@ msgid "workspace.updates.update" msgstr "Update" msgid "workspace.viewport.click-to-close-path" -msgstr "Click to close the path" \ No newline at end of file +msgstr "Click to close the path" + +msgid "workspace.shape.menu.hide-ui" +msgstr "Show/Hide UI" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 477b300942..ba784e4056 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -3257,7 +3257,7 @@ msgstr "Historial (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Capas (%s)" +msgstr "Capas" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3273,7 +3273,7 @@ msgstr "Mapa del sitio" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Recursos (%s)" +msgstr "Recursos" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" @@ -3443,4 +3443,7 @@ msgid "workspace.updates.update" msgstr "Actualizar" msgid "workspace.viewport.click-to-close-path" -msgstr "Pulsar para cerrar la ruta" \ No newline at end of file +msgstr "Pulsar para cerrar la ruta" + +msgid "workspace.shape.menu.hide-ui" +msgstr "Mostrar/Ocultar Interfaz" diff --git a/frontend/translations/fr.po b/frontend/translations/fr.po index 70f85c1fe9..eb704a5ac9 100644 --- a/frontend/translations/fr.po +++ b/frontend/translations/fr.po @@ -2535,7 +2535,7 @@ msgstr "Historique (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Calques (%s)" +msgstr "Calques" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -2551,7 +2551,7 @@ msgstr "Plan du site" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Ressources (%s)" +msgstr "Ressources" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/he.po b/frontend/translations/he.po index 01956021b7..eaa620b490 100644 --- a/frontend/translations/he.po +++ b/frontend/translations/he.po @@ -3078,7 +3078,7 @@ msgstr "היסטוריה (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "שכבות (%s)" +msgstr "שכבות" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3094,7 +3094,7 @@ msgstr "מפת אתר" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "משאבים (%s)" +msgstr "משאבים" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/pt_BR.po b/frontend/translations/pt_BR.po index cfdf4e3207..cd0442519e 100644 --- a/frontend/translations/pt_BR.po +++ b/frontend/translations/pt_BR.po @@ -1844,7 +1844,7 @@ msgstr "Histórico (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Camadas (%s)" +msgstr "Camadas" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" diff --git a/frontend/translations/ro.po b/frontend/translations/ro.po index a16acbce51..26c1f7e93e 100644 --- a/frontend/translations/ro.po +++ b/frontend/translations/ro.po @@ -2417,7 +2417,7 @@ msgstr "Istoric (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Layere (%s)" +msgstr "Layere" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -2433,7 +2433,7 @@ msgstr "Harta site-ului" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Obiecte (%s)" +msgstr "Obiecte" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/tr.po b/frontend/translations/tr.po index 523f8cbd30..ff4cb091fd 100644 --- a/frontend/translations/tr.po +++ b/frontend/translations/tr.po @@ -3112,7 +3112,7 @@ msgstr "Geçmiş (%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "Katmanlar (%s)" +msgstr "Katmanlar" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -3128,7 +3128,7 @@ msgstr "Site haritası" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "Varlıklar(%s)" +msgstr "Varlıklar" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette" diff --git a/frontend/translations/zh_CN.po b/frontend/translations/zh_CN.po index c01314468d..43cfecabd2 100644 --- a/frontend/translations/zh_CN.po +++ b/frontend/translations/zh_CN.po @@ -2527,7 +2527,7 @@ msgstr "历史(%s)" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.sidebar.layers" -msgstr "图层(%s)" +msgstr "图层" #: src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs, src/app/main/ui/handoff/attributes/svg.cljs msgid "workspace.sidebar.options.svg-attrs.title" @@ -2543,7 +2543,7 @@ msgstr "站点地图" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.assets" -msgstr "素材(%s)" +msgstr "素材" #: src/app/main/ui/workspace/left_toolbar.cljs msgid "workspace.toolbar.color-palette"