diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc
index a12bb40fe..c997c05c0 100644
--- a/common/src/app/common/data.cljc
+++ b/common/src/app/common/data.cljc
@@ -882,3 +882,15 @@
([pred coll]
(transduce (take-until pred) conj [] coll)))
+(defn safe-subvec
+ "Wrapper around subvec so it doesn't throw an exception but returns nil instead"
+ ([v start]
+ (when (and (some? v)
+ (> start 0) (< start (count v)))
+ (subvec v start)))
+ ([v start end]
+ (let [size (count v)]
+ (when (and (some? v)
+ (>= start 0) (< start size)
+ (>= end 0) (<= start end) (<= end size))
+ (subvec v start end)))))
diff --git a/common/src/app/common/geom/point.cljc b/common/src/app/common/geom/point.cljc
index 20680e816..bbb63ec2a 100644
--- a/common/src/app/common/geom/point.cljc
+++ b/common/src/app/common/geom/point.cljc
@@ -495,6 +495,12 @@
(pos->Point (if (mth/almost-zero? x) 0.001 x)
(if (mth/almost-zero? y) 0.001 y))))
+(defn resize
+ "Creates a new vector with the same direction but different length"
+ [vector new-length]
+ (let [old-length (length vector)]
+ (scale vector (/ new-length old-length))))
+
;; FIXME: perfromance
(defn abs
[point]
@@ -522,3 +528,4 @@
:class Point
:wfn #(into {} %)
:rfn map->Point})
+
diff --git a/common/src/app/common/geom/shapes/grid_layout/positions.cljc b/common/src/app/common/geom/shapes/grid_layout/positions.cljc
index eb7695615..c07aa9f7b 100644
--- a/common/src/app/common/geom/shapes/grid_layout/positions.cljc
+++ b/common/src/app/common/geom/shapes/grid_layout/positions.cljc
@@ -25,32 +25,32 @@
(let [hv #(gpo/start-hv layout-bounds %)
vv #(gpo/start-vv layout-bounds %)
- span-column-tracks (subvec column-tracks (dec column) (+ (dec column) column-span))
- span-row-tracks (subvec row-tracks (dec row) (+ (dec row) row-span))
+ span-column-tracks (d/safe-subvec column-tracks (dec column) (+ (dec column) column-span))
+ span-row-tracks (d/safe-subvec row-tracks (dec row) (+ (dec row) row-span))]
- p1
- (gpt/add
- origin
- (gpt/add
- (gpt/to-vec origin (dm/get-in span-column-tracks [0 :start-p]))
- (gpt/to-vec origin (dm/get-in span-row-tracks [0 :start-p]))))
+ (when (and span-column-tracks span-row-tracks)
+ (let [p1
+ (gpt/add
+ origin
+ (gpt/add
+ (gpt/to-vec origin (dm/get-in span-column-tracks [0 :start-p]))
+ (gpt/to-vec origin (dm/get-in span-row-tracks [0 :start-p]))))
- p2
- (as-> p1 $
- (reduce (fn [p track] (gpt/add p (hv (:size track)))) $ span-column-tracks)
- (gpt/add $ (hv (* column-gap (dec (count span-column-tracks))))))
+ p2
+ (as-> p1 $
+ (reduce (fn [p track] (gpt/add p (hv (:size track)))) $ span-column-tracks)
+ (gpt/add $ (hv (* column-gap (dec (count span-column-tracks))))))
- p3
- (as-> p2 $
- (reduce (fn [p track] (gpt/add p (vv (:size track)))) $ span-row-tracks)
- (gpt/add $ (vv (* row-gap (dec (count span-row-tracks))))))
+ p3
+ (as-> p2 $
+ (reduce (fn [p track] (gpt/add p (vv (:size track)))) $ span-row-tracks)
+ (gpt/add $ (vv (* row-gap (dec (count span-row-tracks))))))
- p4
- (as-> p1 $
- (reduce (fn [p track] (gpt/add p (vv (:size track)))) $ span-row-tracks)
- (gpt/add $ (vv (* row-gap (dec (count span-row-tracks))))))]
-
- [p1 p2 p3 p4]))
+ p4
+ (as-> p1 $
+ (reduce (fn [p track] (gpt/add p (vv (:size track)))) $ span-row-tracks)
+ (gpt/add $ (vv (* row-gap (dec (count span-row-tracks))))))]
+ [p1 p2 p3 p4]))))
(defn calc-fill-width-data
"Calculates the size and modifiers for the width of an auto-fill child"
diff --git a/frontend/gulpfile.js b/frontend/gulpfile.js
index 6e561569a..82290f29a 100644
--- a/frontend/gulpfile.js
+++ b/frontend/gulpfile.js
@@ -28,6 +28,8 @@ paths.resources = "./resources/";
paths.output = "./resources/public/";
paths.dist = "./target/dist/";
+const touchSourceOnStyleChange = true;
+
/***********************************************
* Marked Extensions
***********************************************/
@@ -282,12 +284,15 @@ gulp.task("dev:dirs", async function(next) {
});
gulp.task("watch:main", function() {
- gulp.watch("src/**/**.scss", gulp.series("scss"))
- .on("change", function(path) {
+ const watchTask = gulp.watch("src/**/**.scss", gulp.series("scss"));
+
+ if (touchSourceOnStyleChange) {
+ watchTask.on("change", function(path) {
// Replace ".scss" for ".cljs" to refresh the file
- gulp.src(path.replace(".scss", ".cljs"))
- .pipe(touch());
+ gulp.src(path.replace(".scss", ".cljs")).pipe(touch());
});
+ }
+
gulp.watch(paths.resources + "styles/**/**.scss", gulp.series("scss"));
gulp.watch(paths.resources + "images/**/*", gulp.series("copy:assets:images"));
diff --git a/frontend/resources/images/icons/align-content-column-stretch-refactor.svg b/frontend/resources/images/icons/align-content-column-stretch-refactor.svg
new file mode 100644
index 000000000..3acb2ce22
--- /dev/null
+++ b/frontend/resources/images/icons/align-content-column-stretch-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/align-content-row-stretch-refactor.svg b/frontend/resources/images/icons/align-content-row-stretch-refactor.svg
new file mode 100644
index 000000000..1dcf6c421
--- /dev/null
+++ b/frontend/resources/images/icons/align-content-row-stretch-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss
index 553842f5d..8c84e486a 100644
--- a/frontend/resources/styles/common/refactor/basic-rules.scss
+++ b/frontend/resources/styles/common/refactor/basic-rules.scss
@@ -316,6 +316,10 @@
color: var(--input-foreground-color-active);
background-color: var(--input-background-color-active);
}
+ &[disabled] {
+ opacity: 0.5;
+ pointer-events: none;
+ }
}
.input-icon {
diff --git a/frontend/resources/styles/common/refactor/color-defs.scss b/frontend/resources/styles/common/refactor/color-defs.scss
index f9d7e1061..41b0077ce 100644
--- a/frontend/resources/styles/common/refactor/color-defs.scss
+++ b/frontend/resources/styles/common/refactor/color-defs.scss
@@ -16,7 +16,9 @@
--green: #91fadb;
--green-30: rgba(145, 250, 219, 0.3);
--lilac: #bb97d8;
+ --pink: #ff6fe0;
--strong-green: #00d1b8;
+
// NOTIFICATION
--dark-ok-color: var(--strong-green);
--dark-warning-color: #ff9b49;
diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss
index 8af861164..db7638b9f 100644
--- a/frontend/resources/styles/common/refactor/design-tokens.scss
+++ b/frontend/resources/styles/common/refactor/design-tokens.scss
@@ -250,4 +250,13 @@
--comment-bullet-foreground-color-resolved: var(--color-foreground-secondary);
--comment-bullet-border-color-resolved: var(--color-background-quaternary);
--comment-modal-background-color: var(--color-background-primary);
+
+ // GRID LAYOUT
+ --grid-editor-marker-color: var(--color-foreground-tertiary);
+ --grid-editor-marker-text: var(--color-foreground-tertiary);
+ --grid-editor-area-background: var(--color-foreground-tertiary);
+ --grid-editor-area-text: var(--color-foreground-tertiary);
+ --grid-editor-line-color: var(--color-foreground-tertiary);
+ --grid-editor-plus-btn-foreground: var(--white);
+ --grid-editor-plus-btn-background: var(--color-foreground-tertiary);
}
diff --git a/frontend/resources/styles/common/refactor/spacing.scss b/frontend/resources/styles/common/refactor/spacing.scss
index cdacbd4a4..b956d7cd1 100644
--- a/frontend/resources/styles/common/refactor/spacing.scss
+++ b/frontend/resources/styles/common/refactor/spacing.scss
@@ -74,6 +74,7 @@ $s-380: calc(var(--s-4) * 95);
$s-400: calc(var(--s-4) * 100);
$s-480: calc(var(--s-4) * 120);
$s-500: calc(var(--s-4) * 125);
+$s-512: calc(var(--s-4) * 128);
$s-520: calc(var(--s-4) * 130);
$s-664: calc(var(--s-4) * 166);
$s-712: calc(var(--s-4) * 178);
diff --git a/frontend/resources/styles/common/refactor/themes/default-theme.scss b/frontend/resources/styles/common/refactor/themes/default-theme.scss
index 35b7e1b68..cfbead3b8 100644
--- a/frontend/resources/styles/common/refactor/themes/default-theme.scss
+++ b/frontend/resources/styles/common/refactor/themes/default-theme.scss
@@ -13,6 +13,7 @@
--color-background-disabled: var(--off-white);
--color-foreground-primary: var(--white);
--color-foreground-secondary: var(--off-white);
+ --color-foreground-tertiary: var(--pink);
--color-foreground-disabled: var(--dark-gray-4);
--color-accent-primary: var(--green);
--color-accent-primary-muted: var(--green-30);
diff --git a/frontend/resources/styles/common/refactor/themes/light-theme.scss b/frontend/resources/styles/common/refactor/themes/light-theme.scss
index c41da5d0f..8c7698ddd 100644
--- a/frontend/resources/styles/common/refactor/themes/light-theme.scss
+++ b/frontend/resources/styles/common/refactor/themes/light-theme.scss
@@ -13,6 +13,7 @@
--color-background-disabled: var(--light-gray-4);
--color-foreground-primary: var(--black);
--color-foreground-secondary: var(--off-black);
+ --color-foreground-tertiary: var(--pink);
--color-foreground-disabled: var(--light-gray-1);
--color-accent-primary: var(--purple);
--color-accent-primary-muted: var(--purple-30);
diff --git a/frontend/src/app/main/data/workspace/edition.cljs b/frontend/src/app/main/data/workspace/edition.cljs
index 0c5e4220e..f5e3b3486 100644
--- a/frontend/src/app/main/data/workspace/edition.cljs
+++ b/frontend/src/app/main/data/workspace/edition.cljs
@@ -7,6 +7,8 @@
(ns app.main.data.workspace.edition
(:require
[app.common.data.macros :as dm]
+ [app.common.types.shape.layout :as ctl]
+ [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.state-helpers :as wsh]
[beicon.core :as rx]
[potok.core :as ptk]))
@@ -31,11 +33,16 @@
state)))
ptk/WatchEvent
- (watch [_ _ stream]
- (->> stream
- (rx/filter interrupt?)
- (rx/take 1)
- (rx/map (constantly clear-edition-mode))))))
+ (watch [_ state stream]
+ (let [objects (wsh/lookup-page-objects state)]
+ (rx/concat
+ (if (ctl/grid-layout? objects id)
+ (rx/of (dwc/hide-toolbar))
+ (rx/empty))
+ (->> stream
+ (rx/filter interrupt?)
+ (rx/take 1)
+ (rx/map (constantly clear-edition-mode))))))))
;; If these event change modules review /src/app/main/data/workspace/path/undo.cljs
(def clear-edition-mode
diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs
index 9d87eeff3..b24abe32d 100644
--- a/frontend/src/app/main/ui/icons.cljs
+++ b/frontend/src/app/main/ui/icons.cljs
@@ -9,6 +9,7 @@
(:require-macros [app.main.ui.icons :refer [icon-xref]])
(:require
[app.common.data :as d]
+ [cuerdas.core :as str]
[rumext.v2 :as mf]))
@@ -275,11 +276,13 @@
(def align-content-column-evenly-refactor (icon-xref :align-content-column-evenly-refactor))
(def align-content-column-start-refactor (icon-xref :align-content-column-start-refactor))
(def align-content-column-end-refactor (icon-xref :align-content-column-end-refactor))
+(def align-content-column-stretch-refactor (icon-xref :align-content-column-stretch-refactor))
(def align-content-row-end-refactor (icon-xref :align-content-row-end-refactor))
(def align-content-row-around-refactor (icon-xref :align-content-row-around-refactor))
(def align-content-row-between-refactor (icon-xref :align-content-row-between-refactor))
(def align-content-row-evenly-refactor (icon-xref :align-content-row-evenly-refactor))
(def align-content-row-start-refactor (icon-xref :align-content-row-start-refactor))
+(def align-content-row-stretch-refactor (icon-xref :align-content-row-stretch-refactor))
(def align-horizontal-center-refactor (icon-xref :align-horizontal-center-refactor))
(def align-vertical-center-refactor (icon-xref :align-vertical-center-refactor))
(def align-items-row-center-refactor (icon-xref :align-items-row-center-refactor))
@@ -474,12 +477,29 @@
(mf/defc debug-icons-preview
{::mf/wrap-props false}
[]
- [:section.debug-icons-preview
- (for [[key val] (sort-by first (ns-publics 'app.main.ui.icons))]
- (when (not= key 'debug-icons-preview)
- [:div.icon-item {:key key}
- (deref val)
- [:span (pr-str key)]]))])
+ [:*
+ [:section.debug-icons-preview
+ [:h2 "Classic"]
+ [:*
+ (for [[key val] (->> (ns-publics 'app.main.ui.icons)
+ (sort-by first)
+ (remove (fn [[key _]]
+ (str/ends-with? (str key) "-refactor"))))]
+ (when (not= key 'debug-icons-preview)
+ [:div.icon-item {:key key}
+ (deref val)
+ [:span (pr-str key)]]))]]
+
+ [:section.debug-icons-preview
+ [:h2 "Refactor"]
+ [:*
+ (for [[key val] (->> (ns-publics 'app.main.ui.icons)
+ (sort-by first)
+ (filter (fn [[key _]] (str/ends-with? (str key) "-refactor"))))]
+ (when (not= key 'debug-icons-preview)
+ [:div.icon-item {:key key}
+ (deref val)
+ [:span (pr-str key)]]))]]])
(defn key->icon
[icon-key]
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs
index d1fb4e255..e19f46c1b 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.options.menus.grid-cell
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.attrs :as attrs]
[app.common.data :as d]
@@ -15,10 +16,14 @@
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]]
+ [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
+ [app.main.ui.components.title-bar :refer [title-bar]]
+ [app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.menus.layout-container :as lyc]
[app.util.dom :as dom]
+ [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
(def cell-props [:id
@@ -33,25 +38,58 @@
(mf/defc set-self-alignment
[{:keys [is-col? alignment set-alignment] :as props}]
- (let [dir-v [:auto :start :center :end :stretch #_:baseline]
- alignment (or alignment :auto)]
- [: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?)])]))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ dir-v [:auto :start :center :end :stretch #_:baseline]
+ alignment (or alignment :auto)
+ type (if is-col? "col" "row")]
+
+ (if new-css-system
+ [:div {:class (stl/css :self-align-menu)}
+ [:& radio-buttons {:selected (d/name alignment)
+ :on-change #(set-alignment (keyword %))
+ :name (dm/str "flex-align-items-" type)}
+ [:& radio-button {:value "start"
+ :icon (if is-col? i/align-self-row-left-refactor i/align-self-column-top-refactor)
+ :title "Align self start"
+ :id (dm/str "align-self-start-" type)}]
+
+ [:& radio-button {:value "center"
+ :icon (if is-col? i/align-self-row-center-refactor i/align-self-column-center-refactor)
+ :title "Align self center"
+ :id (dm/str "align-self-center-" type)}]
+
+ [:& radio-button {:value "end"
+ :icon (if is-col? i/align-self-row-right-refactor i/align-self-column-bottom-refactor)
+ :title "Align self end"
+ :id (dm/str "align-self-end-" type)}]
+
+ [:& radio-button {:value "stretch"
+ :icon (if is-col? i/align-self-row-strech i/align-self-column-strech)
+ :title "Align self stretch"
+ :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/wrap [mf/memo]}
[{:keys [shape cell cells] :as props}]
- (let [cells (hooks/use-equal-memo cells)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+
+ state* (mf/use-state {:open true})
+ open? (:open @state*)
+
+ cells (hooks/use-equal-memo cells)
cell (or cell (attrs/get-attrs-multi cells cell-props))
multiple? (= :multiple (:id cell))
@@ -126,7 +164,8 @@
(mf/use-callback
(mf/deps (:id shape) cell-ids)
(fn [mode]
- (st/emit! (dwsl/change-cells-mode (:id shape) cell-ids mode))))
+ (let [mode (-> mode keyword)]
+ (st/emit! (dwsl/change-cells-mode (:id shape) cell-ids mode)))))
toggle-edit-mode
(mf/use-fn
@@ -135,106 +174,207 @@
(st/emit! (dw/start-edition-mode (:id shape))
(dwge/clear-selection (:id shape)))))]
- [:div.element-set
- [:div.element-set-title
- [:span "Grid Cell"]]
- [:div.element-set-content.layout-grid-item-menu
- [:div.layout-row
- [:div.row-title.sizing "Position"]
- [:div.position-wrapper
- [:button.position-btn
- {:on-click #(set-cell-mode :auto)
- :class (dom/classnames :active (= :auto cell-mode))} "Auto"]
- (when-not multiple?
+ (if new-css-system
+ [:div {:class (stl/css :grid-cell-menu)}
+ [:div {:class (stl/css :grid-cell-menu-title)}
+ [:& title-bar {:collapsable? true
+ :collapsed? (not open?)
+ :on-collapsed #(swap! state* update :open not)
+ :title "Grid cell"}]]
+
+ (when open?
+ [:div {:class (stl/css :grid-cell-menu-container)}
+ [:div {:class (stl/css :cell-mode :row)}
+ [:& radio-buttons {:selected (d/name cell-mode)
+ :on-change set-cell-mode
+ :name "cell-mode"
+ :wide true}
+ [:& radio-button {:value "auto" :id :auto}]
+ [:& radio-button {:value "manual" :id :manual}]
+ [:& radio-button {:value "area" :id :area}]]]
+
+ (when (= :area cell-mode)
+ [: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/layout-rows]
+ [:div {:class (stl/css :coord-input)}
+ [:> numeric-input*
+ {:placeholder "--"
+ :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/layout-columns]
+ [:div {:class (stl/css :coord-input)}
+ [:> numeric-input*
+ {:placeholder "--"
+ :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}]]]])
+
+ [:div {:class (stl/css :row)}
+ [:& set-self-alignment {:is-col? false
+ :alignment align-self
+ :set-alignment set-alignment}]
+ [:& set-self-alignment {:is-col? true
+ :alignment justify-self
+ :set-alignment set-justify-self}]]
+
+ [:div {:class (stl/css :row)}
+ [:button
+ {:class (stl/css :edit-grid-btn)
+ :alt (tr "workspace.layout_grid.editor.options.edit-grid")
+ :on-click toggle-edit-mode}
+ (tr "workspace.layout_grid.editor.options.edit-grid")]]])]
+
+
+ [:div.element-set
+ [:div.element-set-title
+ [:span "Grid Cell"]]
+
+ [:div.element-set-content.layout-grid-item-menu
+ [:div.layout-row
+ [:div.row-title.sizing "Position"]
+ [:div.position-wrapper
[:button.position-btn
- {:on-click #(set-cell-mode :manual)
- :class (dom/classnames :active (= :manual cell-mode))} "Manual"])
- [:button.position-btn
- {:on-click #(set-cell-mode :area)
- :disabled (not valid-area-cells?)
- :class (dom/classnames :active (= :area cell-mode))} "Area"]]]
+ {:on-click #(set-cell-mode :auto)
+ :class (dom/classnames :active (= :auto cell-mode))} "Auto"]
+ (when-not multiple?
+ [:button.position-btn
+ {:on-click #(set-cell-mode :manual)
+ :class (dom/classnames :active (= :manual cell-mode))} "Manual"])
+ [:button.position-btn
+ {:on-click #(set-cell-mode :area)
+ :disabled (not valid-area-cells?)
+ :class (dom/classnames :active (= :area cell-mode))} "Area"]]]
- [:div.manage-grid-columns
- (when (and (not multiple?) (= :auto cell-mode))
- [:div.grid-auto
- [:div.grid-columns-auto
- [:span.icon i/layout-rows]
+ [:div.manage-grid-columns
+ (when (and (not multiple?) (= :auto cell-mode))
+ [:div.grid-auto
+ [:div.grid-columns-auto
+ [:span.icon i/layout-rows]
+ [:div.input-wrapper
+ [:> numeric-input*
+ {: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.input-wrapper
- [:> numeric-input*
- {: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}]]]])
+ [:input.input-text
+ {:key (dm/str "name-" (:id cell))
+ :id "grid-area-name"
+ :type "text"
+ :aria-label "grid-area-name"
+ :placeholder "--"
+ :default-value area-name
+ :auto-complete "off"
+ :on-change on-area-name-change}]])
- (when (= :area cell-mode)
- [:div.input-wrapper
- [:input.input-text
- {:key (dm/str "name-" (:id cell))
- :id "grid-area-name"
- :type "text"
- :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}]]]])]
- (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
- [: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]]]]]]))
+ [: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]]]]]])))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss
new file mode 100644
index 000000000..0240eed2a
--- /dev/null
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss
@@ -0,0 +1,59 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@import "refactor/common-refactor.scss";
+
+.grid-cell-menu {
+ .grid-cell-menu-container {
+ @include flexColumn;
+ margin-top: $s-8;
+ gap: $s-16;
+ }
+
+ .grid-cell-menu-title {
+ font-size: $fs-11;
+ }
+
+ .row {
+ @include flexRow;
+ }
+
+ .cell-mode :global(label) {
+ padding: 0 $s-12;
+ }
+
+ .edit-grid-btn {
+ @extend .button-secondary;
+ @include tabTitleTipography;
+ width: 100%;
+ padding: $s-8;
+ }
+
+ .area-input {
+ @extend .input-element;
+ width: 100%;
+ padding: $s-8;
+ }
+}
+
+.grid-coord-group {
+ @include flexRow;
+
+ border-radius: $br-8;
+ padding-left: $s-4;
+ background-color: var(--input-background-color);
+
+ .icon svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ fill: var(--icon-foreground);
+ }
+ .coord-input {
+ @extend .input-element;
+ border-radius: 0 $br-8 $br-8 0;
+ border-left: 1px solid var(--panel-background-color);
+ }
+}
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
index 1e78a482b..ba479c5c1 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
@@ -24,6 +24,7 @@
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
+ [app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
@@ -231,6 +232,43 @@
:stretch i/align-self-column-strech
:baseline i/align-self-column-baseline))))
+(defn get-layout-grid-icon-refactor
+ [type val is-col?]
+ (case type
+ :align-items
+ (if is-col?
+ (case val
+ :auto i/remove-refactor
+ :start i/align-self-row-left-refactor
+ :end i/align-self-row-right-refactor
+ :center i/align-self-row-center-refactor
+ :stretch i/align-self-row-strech
+ :baseline i/align-self-row-baseline)
+ (case val
+ :auto i/remove-refactor
+ :start i/align-self-column-top-refactor
+ :end i/align-self-column-bottom-refactor
+ :center i/align-self-column-center-refactor
+ :stretch i/align-self-column-strech
+ :baseline i/align-self-column-baseline))
+
+ :justify-items
+ (if (not is-col?)
+ (case val
+ :start i/align-content-column-start-refactor
+ :center i/align-content-column-center-refactor
+ :end i/align-content-column-end-refactor
+ :space-around i/align-content-column-around-refactor
+ :space-between i/align-content-column-between-refactor
+ :stretch i/align-content-column-stretch-refactor)
+ (case val
+ :start i/align-content-row-start-refactor
+ :center i/align-content-row-center-refactor
+ :end i/align-content-row-end-refactor
+ :space-around i/align-content-row-around-refactor
+ :space-between i/align-content-row-between-refactor
+ :stretch i/align-content-row-stretch-refactor))))
+
(mf/defc direction-row-flex
[{:keys [saved-dir on-change] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
@@ -310,7 +348,7 @@
:id "align-items-end"}]]
[:div.align-items-style
- [:button.align-start.tooltip.tooltip-bottom
+ [:button.align-start.tooltip.tooltip-bottom
{:class (dom/classnames :active (= align-items :start))
:alt "Align items start"
:data-value :start
@@ -687,8 +725,7 @@
[:div {:class (stl/css-case :row-gap true
:disabled (and (= :nowrap wrap-type) (not is-col?)))
:title "Row gap"}
- [:span {:class (stl/css :icon)}
- i/gap-vertical-refactor]
+ [:span {:class (stl/css :icon)} i/gap-vertical-refactor]
[:> numeric-input* {:className (stl/css :numeric-input true)
:no-validate true
:placeholder "--"
@@ -704,6 +741,7 @@
:min 0
:value (:row-gap gap-value)
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]
+
[:div {:class (stl/css-case :column-gap true
:disabled (and (= :nowrap wrap-type) is-col?))
:title "Column gap"}
@@ -792,11 +830,11 @@
:space-evenly i/grid-justify-content-row-between))))
(mf/defc direction-row-grid
- [{:keys [saved-dir on-change-refactor on-click] :as props}]
+ [{:keys [saved-dir on-change on-click] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:& radio-buttons {:selected (d/name saved-dir)
- :on-change on-change-refactor
+ :on-change on-change
:name "grid-direction"}
[:& radio-button {:value "row"
:id "grid-direction-row"
@@ -832,13 +870,18 @@
(st/emit! (udw/start-edition-mode id))
(st/emit! :interrupt))))]
(if new-css-system
- [:div "new-edit-mode"]
+ [:button
+ {:class (stl/css :edit-mode-btn)
+ :alt "Grid edit mode"
+ :on-click toggle-edit-mode}
+ (tr "workspace.layout_grid.editor.options.edit-grid")]
+
[:button.tooltip.tooltip-bottom-left
{:class (dom/classnames :active active?)
:alt "Grid edit mode"
- :on-click #(toggle-edit-mode)
+ :on-click toggle-edit-mode
:style {:padding 0}}
- "Edit grid"
+ (tr "workspace.layout_grid.editor.options.edit-grid")
i/grid-layout-mode])))
(mf/defc align-grid-row
@@ -847,20 +890,20 @@
type (if is-col? :column :row)]
(if new-css-system
[:& radio-buttons {:selected (d/name align-items)
- :on-change set-align
- :name "flex-align-items"}
+ :on-change #(set-align % type)
+ :name (dm/str "flex-align-items-" (d/name type))}
[:& radio-button {:value "start"
- :icon (get-layout-flex-icon-refactor :align-items :start is-col?)
+ :icon (get-layout-grid-icon-refactor :align-items :start is-col?)
:title "Align items start"
- :id "align-items-start"}]
+ :id (dm/str "align-items-start-" (d/name type))}]
[:& radio-button {:value "center"
- :icon (get-layout-flex-icon-refactor :align-items :center is-col?)
+ :icon (get-layout-grid-icon-refactor :align-items :center is-col?)
:title "Align items center"
- :id "align-items-center"}]
+ :id (dm/str "align-items-center-" (d/name type))}]
[:& radio-button {:value "end"
- :icon (get-layout-flex-icon-refactor :align-items :end is-col?)
+ :icon (get-layout-grid-icon-refactor :align-items :end is-col?)
:title "Align items end"
- :id "align-items-end"}]]
+ :id (dm/str "align-items-end-" (d/name type))}]]
[:div.align-items-style
(for [align [:start :center :end]]
[:button.align-start.tooltip
@@ -876,19 +919,31 @@
(mf/defc justify-grid-row
[{:keys [is-col? justify-items set-justify] :as props}]
- (let [type (if is-col? :column :row)]
- [:div.justify-content-style
- (for [align [:start :center :end :space-around :space-between :stretch]]
- [:button.align-start.tooltip
- {:class (dom/classnames :active (= justify-items align)
- :tooltip-bottom-left (not= align :start)
- :tooltip-bottom (= align :start))
- :alt (if is-col?
- (dm/str "align-content: " (d/name align))
- (dm/str "justify-content: " (d/name align)))
- :on-click #(set-justify align type)
- :key (dm/str "justify-content" (d/name align))}
- (get-layout-grid-icon :justify-items align is-col?)])]))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ type (if is-col? :column :row)]
+
+ (if new-css-system
+ [:& radio-buttons {:selected (d/name justify-items)
+ :on-change #(set-justify % type)
+ :name (dm/str "grid-justify-items-" (d/name type))}
+ (for [justify [:start :center :end :space-around :space-between :stretch]]
+ [:& radio-button {:value (d/name justify)
+ :icon (get-layout-grid-icon-refactor :justify-items justify is-col?)
+ :title (dm/str "Justify items " (d/name justify))
+ :id (dm/str "justify-items-" (d/name justify) "-" (d/name type))}])]
+
+ [:div.justify-content-style
+ (for [align [:start :center :end :space-around :space-between :stretch]]
+ [:button.align-start.tooltip
+ {:class (dom/classnames :active (= justify-items align)
+ :tooltip-bottom-left (not= align :start)
+ :tooltip-bottom (= align :start))
+ :alt (if is-col?
+ (dm/str "align-content: " (d/name align))
+ (dm/str "justify-content: " (d/name align)))
+ :on-click #(set-justify align type)
+ :key (dm/str "justify-content" (d/name align))}
+ (get-layout-grid-icon :justify-items align is-col?)])])))
(defn manage-values [{:keys [value type]}]
(case type
@@ -900,7 +955,9 @@
(mf/defc grid-track-info
[{:keys [is-col? type index column set-column-value set-column-type remove-element reorder-track hover-track]}]
- (let [drop-track
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+
+ drop-track
(mf/use-fn
(mf/deps type reorder-track index)
(fn [drop-position data]
@@ -926,74 +983,139 @@
:index index
:column column}
:draggable? true)]
- [:div.column-info
- {:ref dref
- :class (dom/classnames
- :dnd-over-top (or (= (:over dprops) :top)
- (= (:over dprops) :center))
- :dnd-over-bot (= (:over dprops) :bot))
- :on-pointer-enter pointer-enter
- :on-pointer-leave pointer-leave}
- [:div.direction-grid-icon
- (if is-col?
- i/layout-rows
- i/layout-columns)]
- [:div.grid-column-value
- [:> numeric-input* {:no-validate true
- :value (:value column)
- :on-change #(set-column-value type index %)
- :placeholder "--"
- :disabled (= :auto (:type column))}]]
- [:div.grid-column-unit
- [:& select
- {:class "grid-column-unit-selector"
- :default-value (:type column)
- :options [{:value :flex :label "FR"}
- {:value :auto :label "AUTO"}
- {:value :fixed :label "PX"}
- {:value :percent :label "%"}]
- :on-change #(set-column-type type index %)}]]
- [:button.remove-grid-column
- {:on-click #(remove-element type index)}
- i/minus]]))
+ (if new-css-system
+ [:div {:class
+ (stl/css-case :track-info true
+ :dnd-over-top (or (= (:over dprops) :top)
+ (= (:over dprops) :center))
+ :dnd-over-bot (= (:over dprops) :bot))
+ :ref dref
+ :on-pointer-enter pointer-enter
+ :on-pointer-leave pointer-leave}
+
+ [:div {:class (stl/css :track-info-container)}
+ [:div {:class (stl/css :track-info-dir-icon)}
+ (if is-col? i/flex-vertical-refactor i/flex-horizontal-refactor)]
+
+ [:div {:class (stl/css :track-info-value)}
+ [:> numeric-input* {:no-validate true
+ :value (:value column)
+ :on-change #(set-column-value type index %)
+ :placeholder "--"
+ :disabled (= :auto (:type column))}]]
+
+ [:div {:class (stl/css :track-info-unit)}
+ [:& select
+ {:class (stl/css :track-info-unit-selector)
+ :default-value (:type column)
+ :options [{:value :flex :label "FR"}
+ {:value :auto :label "AUTO"}
+ {:value :fixed :label "PX"}
+ {:value :percent :label "%"}]
+ :on-change #(set-column-type type index %)}]]]
+
+ [:button
+ {:class (stl/css :remove-track-btn)
+ :on-click #(remove-element type index)}
+ i/remove-refactor]]
+
+ [:div.column-info
+ {:ref dref
+ :class (dom/classnames
+ :dnd-over-top (or (= (:over dprops) :top)
+ (= (:over dprops) :center))
+ :dnd-over-bot (= (:over dprops) :bot))
+ :on-pointer-enter pointer-enter
+ :on-pointer-leave pointer-leave}
+ [:div.direction-grid-icon
+ (if is-col?
+ i/layout-rows
+ i/layout-columns)]
+
+ [:div.grid-column-value
+ [:> numeric-input* {:no-validate true
+ :value (:value column)
+ :on-change #(set-column-value type index %)
+ :placeholder "--"
+ :disabled (= :auto (:type column))}]]
+ [:div.grid-column-unit
+ [:& select
+ {:class "grid-column-unit-selector"
+ :default-value (:type column)
+ :options [{:value :flex :label "FR"}
+ {:value :auto :label "AUTO"}
+ {:value :fixed :label "PX"}
+ {:value :percent :label "%"}]
+ :on-change #(set-column-type type index %)}]]
+ [:button.remove-grid-column
+ {:on-click #(remove-element type index)}
+ i/minus]])))
(mf/defc grid-columns-row
[{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element reorder-track hover-track] :as props}]
- (let [column-num (count column-values)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+
+ column-num (count column-values)
direction (if (> column-num 1)
(if is-col? "Columns " "Rows ")
(if is-col? "Column " "Row "))
- column-vals (str/join ", " (map manage-values column-values))
- generated-name (dm/str direction (if (= column-num 0) " - empty" (dm/str column-num " (" column-vals ")")))
- type (if is-col? :column :row)]
+ track-name (dm/str direction (if (= column-num 0) " - empty" column-num))
+ track-detail (str/join ", " (map manage-values column-values))
+ generated-name (dm/str direction (if (= column-num 0) " - empty" (dm/str column-num " (" track-detail ")")))
- [:div.grid-columns
- [:div.grid-columns-header
- [:button.expand-icon
- {:on-click toggle} i/actions]
+ type (if is-col? :column :row)
- [:div.columns-info {:title generated-name
- :on-click toggle} generated-name]
- [:button.add-column {:on-click #(do
- (when-not expanded? (toggle))
- (add-new-element type ctl/default-track-value))} i/plus]]
+ add-track
+ #(do
+ (when-not expanded? (toggle))
+ (add-new-element type ctl/default-track-value))]
- (when expanded?
- [:& h/sortable-container {}
- [:div.columns-info-wrapper
- (for [[index column] (d/enumerate column-values)]
- [:& grid-track-info {:key (dm/str index "-" (name type) "-" column)
- :type type
- :is-col? is-col?
- :index index
- :column column
- :set-column-value set-column-value
- :set-column-type set-column-type
- :remove-element remove-element
- :reorder-track reorder-track
- :hover-track hover-track}])]])]))
+ (if new-css-system
+ [:div {:class (stl/css :grid-tracks)}
+ [:div {:class (stl/css :grid-track-header)}
+ [:button {:class (stl/css :expand-icon) :on-click toggle} i/menu-refactor]
+ [:div {:class (stl/css :track-title) :on-click toggle}
+ [:div {:class (stl/css :track-name) :title track-name} track-name]
+ [:div {:class (stl/css :track-detail) :title track-detail} track-detail]]
+ [:button {:class (stl/css :add-column) :on-click add-track} i/add-refactor]]
+
+ (when expanded?
+ [:& h/sortable-container {}
+ [:div {:class (stl/css :grid-tracks-info-container)}
+ (for [[index column] (d/enumerate column-values)]
+ [:& grid-track-info {:key (dm/str index "-" (name type))
+ :type type
+ :is-col? is-col?
+ :index index
+ :column column
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}])]])]
+
+ [:div.grid-columns
+ [:div.grid-columns-header
+ [:button.expand-icon {:on-click toggle} i/actions]
+ [:div.columns-info {:title generated-name :on-click toggle} generated-name]
+ [:button.add-column {:on-click add-track} i/plus]]
+
+ (when expanded?
+ [:& h/sortable-container {}
+ [:div.columns-info-wrapper
+ (for [[index column] (d/enumerate column-values)]
+ [:& grid-track-info {:key (dm/str index "-" (name type))
+ :type type
+ :is-col? is-col?
+ :index index
+ :column column
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}])]])])))
;; LAYOUT COMPONENT
@@ -1169,16 +1291,16 @@
(mf/use-fn
(mf/deps ids)
(fn [type prop val]
- (let [val (mth/finite val 0)]
- (cond
- (and (= type :simple) (= prop :p1))
- (st/emit! (dwsl/update-layout ids {:layout-padding {:p1 val :p3 val}}))
+ (let [val (mth/finite val 0)]
+ (cond
+ (and (= type :simple) (= prop :p1))
+ (st/emit! (dwsl/update-layout ids {:layout-padding {:p1 val :p3 val}}))
- (and (= type :simple) (= prop :p2))
- (st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
+ (and (= type :simple) (= prop :p2))
+ (st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
- :else
- (st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))))
+ :else
+ (st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))))
;; Grid-direction
@@ -1188,9 +1310,9 @@
(mf/use-fn
(mf/deps [layout-type ids new-css-system])
(fn [dir]
- (let [dir (if new-css-system (keyword dir) dir)]
+ (let [dir (cond-> dir new-css-system keyword)]
(if (= :flex layout-type)
- (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir}))
+ (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))
(st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))))
;; Align grid
@@ -1198,10 +1320,13 @@
align-items-column (:layout-justify-items values)
set-align-grid
- (fn [value type]
- (if (= type :row)
- (st/emit! (dwsl/update-layout ids {:layout-align-items value}))
- (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
+ (mf/use-fn
+ (mf/deps ids new-css-system)
+ (fn [value type]
+ (let [value (cond-> value new-css-system keyword)]
+ (if (= type :row)
+ (st/emit! (dwsl/update-layout ids {:layout-align-items value}))
+ (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))))
;; Justify grid
grid-justify-content-row (:layout-justify-content values)
@@ -1211,11 +1336,12 @@
set-justify-grid
(mf/use-fn
- (mf/deps ids)
+ (mf/deps ids new-css-system)
(fn [value type]
- (if (= type :row)
- (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))
- (st/emit! (dwsl/update-layout ids {:layout-align-content value})))))]
+ (let [value (cond-> value new-css-system keyword)]
+ (if (= type :row)
+ (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))
+ (st/emit! (dwsl/update-layout ids {:layout-align-content value}))))))]
(if new-css-system
[:div {:class (stl/css :element-set)}
@@ -1265,7 +1391,7 @@
[:div {:class (stl/css :second-row)}
[:& justify-content-row {:is-col? is-col?
:justify-content justify-content
- :on-change set-justify-content-refactor}]]
+ :on-change set-justify-content-refactor}]]
(when (= :wrap wrap-type)
[:div {:class (stl/css :third-row)}
[:& align-content-row {:is-col? is-col?
@@ -1281,37 +1407,33 @@
[:& padding-section {:values values
:on-change-style change-padding-type
:on-change on-padding-change}]]]
- :grid ;; TODO Finish this with new UI
+
+
+ :grid
[:div {:class (stl/css :grid-layout-menu)}
- [:div {:class (stl/css :first-row)}
- [:div (stl/css :direction-edit)
- [:div {:class (stl/css :direction)}
- [:& direction-row-grid {:set-direction set-direction
- :on-click saved-dir}]
- (when (= 1 (count ids))
- [:div {:class (stl/css :edit)}
- [:& grid-edit-mode {:id (first ids)}]])]]
+ [:div {:class (stl/css :row :first-row)}
+ [:div {:class (stl/css :direction-edit)}
+ [:div {:class (stl/css :direction)}
+ [:& direction-row-grid {:saved-dir saved-grid-dir
+ :on-change set-direction}]]]
- [:div.layout-row
- [:div.align-items-grid.row-title "Items"]
- [:div.btn-wrapper.align-grid-items
- [:& align-grid-row {:is-col? false
- :align-items align-items-row
- :set-align set-align-grid}]
+ [:& align-grid-row {:is-col? false
+ :align-items align-items-row
+ :set-align set-align-grid}]
- [:& align-grid-row {:is-col? true
- :align-items align-items-column
- :set-align set-align-grid}]]]
+ [:& align-grid-row {:is-col? true
+ :align-items align-items-column
+ :set-align set-align-grid}]]
- [:div.layout-row
- [:div.jusfiy-content-grid.row-title "Content"]
- [:div.btn-wrapper.align-grid-content
- [:& justify-grid-row {:is-col? true
- :justify-items grid-justify-content-column
- :set-justify set-justify-grid}]
- [:& justify-grid-row {:is-col? false
- :justify-items grid-justify-content-row
- :set-justify set-justify-grid}]]]]]
+ [:div {:class (stl/css :row :grid-layout-align)}
+ [:& justify-grid-row {:is-col? true
+ :justify-items grid-justify-content-column
+ :set-justify set-justify-grid}]
+ [:& justify-grid-row {:is-col? false
+ :justify-items grid-justify-content-row
+ :set-justify set-justify-grid}]]
+ (when (= 1 (count ids))
+ [:& grid-edit-mode {:id (first ids)}])]
nil)))]
[:div.element-set
@@ -1427,13 +1549,15 @@
:justify-items grid-justify-content-row
:set-justify set-justify-grid}]]]]
- ;; Default if not grid or flex
+ ;; Default if not grid or flex
nil)))])))
(mf/defc grid-layout-edition
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]}
[{:keys [ids values] :as props}]
- (let [;; Gap
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+
+ ;; Gap
gap-selected? (mf/use-state :none)
saved-grid-dir (:layout-grid-dir values)
@@ -1468,23 +1592,28 @@
align-items-row (:layout-align-items values)
align-items-column (:layout-justify-items values)
- set-items-grid
- (fn [value type]
- (if (= type :row)
- (st/emit! (dwsl/update-layout ids {:layout-align-items value}))
- (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
+ set-align-grid
+ (mf/use-fn
+ (mf/deps ids new-css-system)
+ (fn [value type]
+ (let [value (cond-> value new-css-system keyword)]
+ (if (= type :row)
+ (st/emit! (dwsl/update-layout ids {:layout-align-items value}))
+ (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))))
+
;; Justify grid
- grid-justify-content-row (:layout-align-content values)
- grid-justify-content-column (:layout-justify-content values)
+ grid-justify-content-row (:layout-justify-content values)
+ grid-justify-content-column (:layout-align-content values)
- set-content-grid
+ set-justify-grid
(mf/use-fn
- (mf/deps ids)
+ (mf/deps ids new-css-system)
(fn [value type]
- (if (= type :row)
- (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))
- (st/emit! (dwsl/update-layout ids {:layout-align-content value})))))
+ (let [value (cond-> value new-css-system keyword)]
+ (if (= type :row)
+ (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))
+ (st/emit! (dwsl/update-layout ids {:layout-align-content value}))))))
;;Grid columns
column-grid-values (:layout-grid-columns values)
@@ -1543,72 +1672,133 @@
(st/emit! (dwsl/change-layout-track ids type index {:value value
:type track-type})))))]
- [:div.element-set
- [:div.element-set-title
- [:span "Grid Layout"]]
+ (if new-css-system
+ [:div {:class (stl/css :grid-layout-menu)}
+ [:div {:class (stl/css :row)}
+ [:div {:class (stl/css :grid-layout-menu-title)} "GRID LAYOUT"]
+ [:button {:class (stl/css :exit-btn)
+ :on-click #(st/emit! udw/clear-edition-mode)}
+ (tr "workspace.layout_grid.editor.options.exit")]]
- [:div.element-set-content.layout-menu
- [:div.layout-row
- [:div.direction-wrap.row-title "Direction"]
- [:div.btn-wrapper
- [:div.direction
- (for [dir [:row :column]]
- [:& direction-btn {:key (d/name dir)
- :dir dir
- :saved-dir saved-grid-dir
- :on-click set-direction
- :icon? true}])]
+ [:div {:class (stl/css :row :first-row)}
+ [:div {:class (stl/css :direction-edit)}
+ [:div {:class (stl/css :direction)}
+ [:& direction-row-grid {:saved-dir saved-grid-dir
+ :on-change set-direction}]]]
- (when (= 1 (count ids))
- [:div.edit-mode
- [:& grid-edit-mode {:id (first ids)}]])]]
-
- [:div.layout-row
- [:div.align-items-grid.row-title "Items"]
- [:div.btn-wrapper.align-grid
[:& align-grid-row {:is-col? false
:align-items align-items-row
- :set-align set-items-grid}]
+ :set-align set-align-grid}]
[:& align-grid-row {:is-col? true
:align-items align-items-column
- :set-align set-items-grid}]]]
+ :set-align set-align-grid}]]
- [:div.layout-row
- [:div.jusfiy-content-grid.row-title "Content"]
- [:div.btn-wrapper.align-grid-content
+ [:div {:class (stl/css :row :grid-layout-align)}
[:& justify-grid-row {:is-col? true
- :justify-items grid-justify-content-row
- :set-justify set-content-grid}]
- [:& justify-grid-row {:is-col? false
:justify-items grid-justify-content-column
- :set-justify set-content-grid}]]]
- [:& grid-columns-row {:is-col? true
- :expanded? @grid-columns-open?
- :toggle toggle-columns-info
- :column-values column-grid-values
- :add-new-element add-new-element
- :set-column-value set-column-value
- :set-column-type set-column-type
- :remove-element remove-element
- :reorder-track reorder-track
- :hover-track hover-track}]
+ :set-justify set-justify-grid}]
+ [:& justify-grid-row {:is-col? false
+ :justify-items grid-justify-content-row
+ :set-justify set-justify-grid}]]
+ [:div {:class (stl/css :row :grid-tracks-row)}
+ [:& grid-columns-row {:is-col? true
+ :expanded? @grid-columns-open?
+ :toggle toggle-columns-info
+ :column-values column-grid-values
+ :add-new-element add-new-element
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}]
- [:& grid-columns-row {:is-col? false
- :expanded? @grid-rows-open?
- :toggle toggle-rows-info
- :column-values rows-grid-values
- :add-new-element add-new-element
- :set-column-value set-column-value
- :set-column-type set-column-type
- :remove-element remove-element
- :reorder-track reorder-track
- :hover-track hover-track}]
+ [:& grid-columns-row {:is-col? false
+ :expanded? @grid-rows-open?
+ :toggle toggle-rows-info
+ :column-values rows-grid-values
+ :add-new-element add-new-element
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}]]
+ [:div {:class (stl/css :row)}
+ [:& gap-section {:gap-selected? gap-selected?
+ :on-change set-gap
+ :gap-value (:layout-gap values)}]]
- [:& gap-section {:gap-selected? gap-selected?
- :on-change set-gap
- :gap-value (:layout-gap values)}]
+ [:div {:class (stl/css :row :padding-section)}
+ [:& padding-section {:values values
+ :on-change-style change-padding-type
+ :on-change on-padding-change}]]]
- [:& padding-section {:values values
- :on-change-style change-padding-type
- :on-change on-padding-change}]]]))
+ [:div.element-set
+ [:div.element-set-title
+ [:span "Grid Layout"]]
+
+ [:div.element-set-content.layout-menu
+ [:div.layout-row
+ [:div.direction-wrap.row-title "Direction"]
+ [:div.btn-wrapper
+ [:div.direction
+ (for [dir [:row :column]]
+ [:& direction-btn {:key (d/name dir)
+ :dir dir
+ :saved-dir saved-grid-dir
+ :on-click set-direction
+ :icon? true}])]
+
+ (when (= 1 (count ids))
+ [:div.edit-mode
+ [:& grid-edit-mode {:id (first ids)}]])]]
+
+ [:div.layout-row
+ [:div.align-items-grid.row-title "Items"]
+ [:div.btn-wrapper.align-grid
+ [:& align-grid-row {:is-col? false
+ :align-items align-items-row
+ :set-align set-align-grid}]
+
+ [:& align-grid-row {:is-col? true
+ :align-items align-items-column
+ :set-align set-align-grid}]]]
+
+ [:div.layout-row
+ [:div.jusfiy-content-grid.row-title "Content"]
+ [:div.btn-wrapper.align-grid-content
+ [:& justify-grid-row {:is-col? true
+ :justify-items grid-justify-content-row
+ :set-justify set-justify-grid}]
+ [:& justify-grid-row {:is-col? false
+ :justify-items grid-justify-content-column
+ :set-justify set-justify-grid}]]]
+ [:& grid-columns-row {:is-col? true
+ :expanded? @grid-columns-open?
+ :toggle toggle-columns-info
+ :column-values column-grid-values
+ :add-new-element add-new-element
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}]
+
+ [:& grid-columns-row {:is-col? false
+ :expanded? @grid-rows-open?
+ :toggle toggle-rows-info
+ :column-values rows-grid-values
+ :add-new-element add-new-element
+ :set-column-value set-column-value
+ :set-column-type set-column-type
+ :remove-element remove-element
+ :reorder-track reorder-track
+ :hover-track hover-track}]
+
+ [:& gap-section {:gap-selected? gap-selected?
+ :on-change set-gap
+ :gap-value (:layout-gap values)}]
+
+ [:& padding-section {:values values
+ :on-change-style change-padding-type
+ :on-change on-padding-change}]]])))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
index f0e856994..8affcbd3c 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
@@ -63,65 +63,242 @@
}
.forth-row {
@include flexColumn;
- .gap-group {
- display: flex;
- gap: $s-4;
- .column-gap {
- @extend .input-element;
- width: $s-108;
- &.disabled {
- @extend .disabled-input;
- }
- }
- .row-gap {
- @extend .input-element;
- width: $s-108;
- &.disabled {
- @extend .disabled-input;
- }
- }
- }
- .padding-group {
- display: flex;
- gap: $s-4;
- .padding-inputs {
- display: flex;
- gap: $s-4;
- .paddings-simple {
- display: flex;
- gap: $s-4;
- .padding-simple {
- @extend .input-element;
- width: $s-108;
- }
- }
- .paddings-multiple {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: $s-4;
- .padding-multiple {
- @extend .input-element;
- width: $s-108;
- }
- }
- }
- .padding-toggle {
- @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);
- }
- }
- }
+ }
+ }
+}
+
+.gap-group {
+ display: flex;
+ gap: $s-4;
+ .column-gap {
+ @extend .input-element;
+ width: $s-108;
+ &.disabled {
+ @extend .disabled-input;
+ }
+ }
+ .row-gap {
+ @extend .input-element;
+ width: $s-108;
+ &.disabled {
+ @extend .disabled-input;
+ }
+ }
+}
+
+.padding-group {
+ display: flex;
+ gap: $s-4;
+
+ .padding-inputs {
+ display: flex;
+ gap: $s-4;
+ }
+
+ .paddings-simple {
+ display: flex;
+ gap: $s-4;
+
+ .padding-simple {
+ @extend .input-element;
+ width: $s-108;
+ }
+ }
+
+ .paddings-multiple {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: $s-4;
+
+ .padding-multiple {
+ @extend .input-element;
+ width: $s-108;
+ }
+ }
+
+ .padding-toggle {
+ @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);
}
}
}
}
+
+.grid-layout-menu {
+ @include flexColumn;
+ gap: $s-8;
+
+ .row {
+ @include flexRow;
+ }
+
+ .first-row {
+ margin-bottom: $s-8;
+ }
+
+ .grid-layout-align {
+ @include flexColumn;
+ gap: $s-4;
+ align-items: flex-start;
+ }
+
+ .grid-layout-menu-title {
+ flex: 1;
+ font-size: $fs-11;
+ }
+
+ .edit-mode-btn {
+ @extend .button-secondary;
+ @include tabTitleTipography;
+ margin-top: $s-8;
+ width: 100%;
+ padding: $s-8;
+ }
+
+ .exit-btn {
+ @extend .button-secondary;
+ @include tabTitleTipography;
+ padding: $s-8 $s-20;
+ }
+
+ .grid-tracks-info-container {
+ @include flexColumn;
+ margin-top: $s-4;
+ }
+
+ .padding-section {
+ margin-top: $s-8;
+ }
+
+ .grid-tracks-row {
+ @include flexColumn;
+ margin: $s-8 0;
+ gap: $s-12;
+ }
+}
+
+.track-info {
+ display: flex;
+
+ &.dnd-over-top {
+ border-top: $s-2 solid var(--button-foreground-hover);
+ }
+
+ &.dnd-over-bot {
+ border-bottom: $s-2 solid var(--button-foreground-hover);
+ }
+
+ .track-info-container {
+ display: flex;
+ }
+
+ .track-info-dir-icon {
+ border-radius: $br-8 0 0 $br-8;
+ background-color: var(--input-background-color);
+ padding-left: $s-12;
+
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ height: 100%;
+ }
+ }
+
+ .track-info-value {
+ @extend .input-element;
+ border-radius: 0;
+ border-right: $s-1 solid var(--panel-background-color);
+ }
+
+ .track-info-unit {
+ }
+
+ .track-info-unit-selector {
+ border-radius: 0 $br-8 $br-8 0;
+ width: $s-96;
+ }
+
+ .remove-track-btn {
+ @extend .button-tertiary;
+ padding: $s-8;
+
+ svg {
+ @extend .button-icon;
+ width: $s-12;
+ height: $s-12;
+ stroke: var(--icon-foreground);
+ fill: var(--icon-foreground);
+ }
+ }
+}
+
+.grid-tracks {
+ width: 100%;
+ margin-top: $s-8;
+
+ .grid-track-header {
+ @include flexRow;
+ font-size: $fs-12;
+ border-radius: $br-8;
+ overflow: hidden;
+ background: var(--button-secondary-background-color-rest);
+ height: $s-52;
+ }
+
+ .track-title {
+ @include flexColumn;
+ flex-grow: 1;
+ padding: $s-8;
+ gap: 0;
+ }
+
+ .track-name {
+ color: var(--color-foreground-secondary);
+ }
+
+ .expand-icon {
+ @extend .button-secondary;
+ height: $s-52;
+
+ border-radius: $s-8 0 0 $s-8;
+ border-right: $s-1 solid var(--panel-background-color);
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ fill: var(--icon-foreground);
+ }
+ &:hover,
+ &:active {
+ svg {
+ stroke: var(--button-foreground-hover);
+ fill: var(--button-foreground-hover);
+ }
+ }
+ }
+
+ .columns-info {
+ }
+
+ .add-column {
+ @extend .button-tertiary;
+ height: $s-52;
+
+ svg {
+ @extend .button-icon;
+ height: $s-12;
+ width: $s-12;
+ stroke: var(--icon-foreground);
+ fill: var(--icon-foreground);
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs
index 4076b8131..c62c0a385 100644
--- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs
@@ -5,7 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.viewport.grid-layout-editor
- (:require-macros [app.main.style :refer [css]])
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -18,17 +18,20 @@
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]
+ [app.main.data.workspace :as dw]
[app.main.data.workspace.grid-layout.editor :as dwge]
[app.main.data.workspace.modifiers :as dwm]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.refs :as refs]
[app.main.store :as st]
+ [app.main.ui.context :as ctx]
[app.main.ui.css-cursors :as cur]
[app.main.ui.formats :as fmt]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
[app.util.dom :as dom]
+ [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[cuerdas.core :as str]
@@ -47,30 +50,56 @@
:flex (dm/str (fmt/format-number value) "FR")
:auto "AUTO"))
+(mf/defc grid-edition-actions
+ {::mf/wrap-props false}
+ [{:keys [shape]}]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (if new-css-system
+ [:div {:class (stl/css :grid-actions)}
+ [:div {:class (stl/css :grid-actions-container)}
+ [:div {:class (stl/css :grid-actions-title)}
+ (tr "workspace.layout_grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]]
+ [:button {:class (stl/css :locate-btn)
+ :on-click #(st/emit! (dwge/locate-board (:id shape)))}
+ (tr "workspace.layout_grid.editor.top-bar.locate")]
+ [:button {:class (stl/css :done-btn)
+ :on-click #(st/emit! dw/clear-edition-mode)}
+ (tr "workspace.layout_grid.editor.top-bar.done")]]]
+
+ [:div.viewport-actions
+ [:div.viewport-actions-container
+ [:div.viewport-actions-title
+ (tr "workspace.layout_grid.editor.title") " " [:span.grid-edit-board-name (:name shape)]]
+ [:button.btn-secondary {:on-click #(st/emit! (dwge/locate-board (:id shape)))}
+ (tr "workspace.layout_grid.editor.top-bar.locate")]
+ [:button.btn-primary {:on-click #(st/emit! dw/clear-edition-mode)}
+ (tr "workspace.layout_grid.editor.top-bar.done")]
+ [:button.btn-icon-basic {:on-click #(st/emit! dw/clear-edition-mode)} i/close]]])))
+
(mf/defc grid-editor-frame
{::mf/wrap-props false}
[props]
(let [bounds (unchecked-get props "bounds")
+ width (unchecked-get props "width")
+ height (unchecked-get props "height")
zoom (unchecked-get props "zoom")
hv #(gpo/start-hv bounds %)
vv #(gpo/start-vv bounds %)
- width (gpo/width-points bounds)
- height (gpo/height-points bounds)
origin (gpo/origin bounds)
frame-points
(reduce
apply-to-point
[origin]
- [#(gpt/add % (hv width))
+ [#(gpt/add % (hv (+ width (/ 70 zoom))))
#(gpt/subtract % (vv (/ 40 zoom)))
- #(gpt/subtract % (hv (+ width (/ 40 zoom))))
- #(gpt/add % (vv (+ height (/ 40 zoom))))
+ #(gpt/subtract % (hv (+ width (/ 110 zoom))))
+ #(gpt/add % (vv (+ height (/ 110 zoom))))
#(gpt/add % (hv (/ 40 zoom)))])]
[:polygon
- {:class (css :grid-frame)
+ {:class (stl/css :grid-frame)
:points (->> frame-points
(map #(dm/fmt "%,%" (:x %) (:y %)))
(str/join " "))}]))
@@ -78,7 +107,6 @@
(mf/defc plus-btn
{::mf/wrap-props false}
[props]
-
(let [start-p (unchecked-get props "start-p")
zoom (unchecked-get props "zoom")
type (unchecked-get props "type")
@@ -88,34 +116,36 @@
(if (= type :column)
[(:x start-p)
(- (:y start-p) (/ 40 zoom))
- (+ (:x start-p) (/ 12 zoom))
- (- (:y start-p) (/ 28 zoom))]
+ (+ (:x start-p) (/ 9 zoom))
+ (- (:y start-p) (/ 31 zoom))]
[(- (:x start-p) (/ 40 zoom))
(:y start-p)
- (- (:x start-p) (/ 28 zoom))
- (+ (:y start-p) (/ 12 zoom))])
+ (- (:x start-p) (/ 31 zoom))
+ (+ (:y start-p) (/ 9 zoom))])
handle-click
(mf/use-callback
(mf/deps on-click)
#(when on-click (on-click)))]
- [:g {:class (css :grid-plus-button)
+ [:g {:class (stl/css :grid-plus-button)
:on-click handle-click}
- [:rect {:class (css :grid-plus-shape)
- :x rect-x
- :y rect-y
- :width (/ 40 zoom)
- :height (/ 40 zoom)}]
+ [:rect {:class (stl/css :grid-plus-shape)
+ :x (+ rect-x (/ 6 zoom))
+ :y (+ rect-y (/ 6 zoom))
+ :width (/ (- 40 12) zoom)
+ :height (/ (- 40 12) zoom)
+ :rx (/ 4 zoom)
+ :ry (/ 4 zoom)}]
- [:use {:class (css :grid-plus-icon)
+ [:use {:class (stl/css :grid-plus-icon)
:x icon-x
:y icon-y
- :width (/ 16 zoom)
- :height (/ 16 zoom)
- :href (dm/str "#icon-plus")}]]))
+ :width (/ 22 zoom)
+ :height (/ 22 zoom)
+ :href "#icon-add-refactor"}]]))
(defn use-drag
[{:keys [on-drag-start on-drag-end on-drag-delta on-drag-position]}]
@@ -260,11 +290,11 @@
:y area-y
:width area-width
:height area-height
- :style {:fill "var(--color-distance)"
+ :style {:fill "var(--grid-editor-area-background)"
:fill-opacity 0.3}}]
[:text {:x area-text-x
:y area-text-y
- :style {:fill "var(--color-distance)"
+ :style {:fill "var(--grid-editor-area-text)"
:font-family "worksans"
:font-weight 600
:font-size (/ 14 zoom)
@@ -313,9 +343,9 @@
[:g.cell-editor
[:rect
{:transform (dm/str (gmt/transform-in cell-center (:transform shape)))
- :class (dom/classnames (css :grid-cell-outline) true
- (css :hover) hover?
- (css :selected) selected?)
+ :class (dom/classnames (stl/css :grid-cell-outline) true
+ (stl/css :hover) hover?
+ (stl/css :selected) selected?)
:x (:x cell-origin)
:y (:y cell-origin)
:width cell-width
@@ -475,6 +505,78 @@
:style {:fill "transparent"
:stroke-width 0}}]))
+(def marker-width 24)
+(def marker-h1 20)
+(def marker-h2 10)
+(def marker-bradius 2)
+
+(defn marker-shape-d
+ [center zoom]
+ (let [marker-width (/ marker-width zoom)
+ marker-h1 (/ marker-h1 zoom)
+ marker-h2 (/ marker-h2 zoom)
+
+ marker-bradius (/ marker-bradius zoom)
+ marker-half-width (/ marker-width 2)
+ marker-half-height (/ (+ marker-h1 marker-h2) 2)
+
+ start-p
+ (gpt/subtract center (gpt/point marker-half-width marker-half-height))
+
+ [a b c d e]
+ (reduce
+ apply-to-point
+ [start-p]
+ [#(gpt/add % (gpt/point marker-width 0))
+ #(gpt/add % (gpt/point 0 marker-h1))
+ #(gpt/add % (gpt/point (- marker-half-width) marker-h2))
+ #(gpt/subtract % (gpt/point marker-half-width marker-h2))])
+
+ vea (gpt/to-vec e a)
+ vab (gpt/to-vec a b)
+ vbc (gpt/to-vec b c)
+ vcd (gpt/to-vec c d)
+ vde (gpt/to-vec d e)
+
+ lea (gpt/length vea)
+ lab (gpt/length vab)
+ lbc (gpt/length vbc)
+ lcd (gpt/length vcd)
+ lde (gpt/length vde)
+
+ a1 (gpt/add e (gpt/resize vea (- lea marker-bradius)))
+ a2 (gpt/add a (gpt/resize vab marker-bradius))
+
+ b1 (gpt/add a (gpt/resize vab (- lab marker-bradius)))
+ b2 (gpt/add b (gpt/resize vbc marker-bradius))
+
+ c1 (gpt/add b (gpt/resize vbc (- lbc marker-bradius)))
+ c2 (gpt/add c (gpt/resize vcd marker-bradius))
+
+ d1 (gpt/add c (gpt/resize vcd (- lcd marker-bradius)))
+ d2 (gpt/add d (gpt/resize vde marker-bradius))
+
+ e1 (gpt/add d (gpt/resize vde (- lde marker-bradius)))
+ e2 (gpt/add e (gpt/resize vea marker-bradius))]
+ (dm/str
+ (dm/fmt "M%,%" (:x a1) (:y a1))
+ (dm/fmt "Q%,%,%,%" (:x a) (:y a) (:x a2) (:y a2))
+
+ (dm/fmt "L%,%" (:x b1) (:y b1))
+ (dm/fmt "Q%,%,%,%" (:x b) (:y b) (:x b2) (:y b2))
+
+ (dm/fmt "L%,%" (:x c1) (:y c1))
+ (dm/fmt "Q%,%,%,%" (:x c) (:y c) (:x c2) (:y c2))
+
+ (dm/fmt "L%,%" (:x d1) (:y d1))
+ (dm/fmt "Q%,%,%,%" (:x d) (:y d) (:x d2) (:y d2))
+
+ (dm/fmt "L%,%" (:x e1) (:y e1))
+ (dm/fmt "Q%,%,%,%" (:x e) (:y e) (:x e2) (:y e2))
+
+ (dm/fmt "L%,%" (:x a1) (:y a1))
+ "Z")))
+
(mf/defc track-marker
{::mf/wrap-props false}
[props]
@@ -489,23 +591,6 @@
track-after (unchecked-get props "track-after")
snap-pixel? (unchecked-get props "snap-pixel?")
- marker-width (/ 24 zoom)
- marker-h1 (/ 22 zoom)
- marker-h2 (/ 8 zoom)
-
- marker-half-width (/ marker-width 2)
- marker-half-height (/ (+ marker-h1 marker-h2) 2)
-
- marker-points
- (reduce
- apply-to-point
- [(gpt/subtract center
- (gpt/point marker-half-width marker-half-height))]
- [#(gpt/add % (gpt/point marker-width 0))
- #(gpt/add % (gpt/point 0 marker-h1))
- #(gpt/add % (gpt/point (- marker-half-width) marker-h2))
- #(gpt/subtract % (gpt/point marker-half-width marker-h2))])
-
text-x (:x center)
text-y (:y center)
@@ -515,16 +600,14 @@
[:g {:on-pointer-down handle-pointer-down
:on-lost-pointer-capture handle-lost-pointer-capture
:on-pointer-move handle-pointer-move
- :class (dom/classnames (css :grid-track-marker) true
+ :class (dom/classnames (stl/css :grid-track-marker) true
(cur/get-dynamic "resize-ew" (:rotation shape)) (= type :column)
(cur/get-dynamic "resize-ns" (:rotation shape)) (= type :row))
:transform (dm/str (gmt/transform-in center (:transform shape)))}
- [:polygon {:class (css :marker-shape)
- :points (->> marker-points
- (map #(dm/fmt "%,%" (:x %) (:y %)))
- (str/join " "))}]
- [:text {:class (css :marker-text)
+ [:path {:class (stl/css :marker-shape)
+ :d (marker-shape-d center zoom)}]
+ [:text {:class (stl/css :marker-text)
:x text-x
:y text-y
:width (/ 26.26 zoom)
@@ -656,23 +739,23 @@
:width (- text-width (/ 36 zoom))
:height (- text-height (/ 5 zoom))
:rx (/ 3 zoom)
- :fill "var(--color-distance)"
+ :fill "var(--grid-editor-marker-color)"
:opacity 0.2}])
(when (not small?)
[:foreignObject {:x text-x :y text-y :width text-width :height text-height}
- [:div {:class (css :grid-editor-wrapper)}
+ [:div {:class (stl/css :grid-editor-wrapper)}
[:input
{:ref track-input-ref
:style {}
- :class (css :grid-editor-label)
+ :class (stl/css :grid-editor-label)
:type "text"
:default-value (format-size track-data)
:data-default-value (format-size track-data)
:on-key-down handle-keydown-track-input
:on-blur handle-blur-track-input}]
(when (and hovering? (not medium?) (not small?))
- [:button {:class (css :grid-editor-button)
- :on-click handle-remove-track} i/trash])]])]
+ [:button {:class (stl/css :grid-editor-button)
+ :on-click handle-remove-track} i/delete-refactor])]])]
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
[:& track-marker
@@ -757,17 +840,20 @@
bounds (:points shape)
hv #(gpo/start-hv bounds %)
vv #(gpo/start-vv bounds %)
- width (gpo/width-points bounds)
- height (gpo/height-points bounds)
origin (gpo/origin bounds)
all-bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %)))
- {:keys [row-tracks column-tracks] :as layout-data}
+ {:keys [row-tracks column-tracks
+ column-total-size column-total-gap
+ row-total-size row-total-gap] :as layout-data}
(mf/use-memo
(mf/deps shape children)
#(gsg/calc-layout-data shape bounds children all-bounds objects))
+ width (max (gpo/width-points bounds) (+ column-total-size column-total-gap))
+ height (max (gpo/height-points bounds) (+ row-total-size row-total-gap))
+
handle-pointer-down
(mf/use-callback
(fn [event]
@@ -806,15 +892,17 @@
(when-not view-only
[:*
[:& grid-editor-frame {:zoom zoom
- :bounds bounds}]
- (let [start-p (-> origin (gpt/add (hv width)))]
+ :bounds bounds
+ :width width
+ :height height}]
+ (let [start-p (-> origin (gpt/add (hv (+ width (/ 30 zoom)))))]
[:g {:transform (dm/str (gmt/transform-in start-p (:transform shape)))}
[:& plus-btn {:start-p start-p
:zoom zoom
:type :column
:on-click handle-add-column}]])
- (let [start-p (-> origin (gpt/add (vv height)))]
+ (let [start-p (-> origin (gpt/add (vv (+ height (/ 30 zoom)))))]
[:g {:transform (dm/str (gmt/transform-in start-p (:transform shape)))}
[:& plus-btn {:start-p start-p
:zoom zoom
diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss
index db53c71cf..c519a0356 100644
--- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss
+++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss
@@ -1,13 +1,19 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@import "refactor/common-refactor.scss";
+
.grid-track-marker {
.marker-shape {
- fill: var(--color-distance);
- fill-opacity: 0.3;
+ fill: var(--grid-editor-marker-color);
}
.marker-text {
- fill: var(--color-distance);
- font-size: calc(12px / var(--zoom));
+ fill: var(--white);
+ font-size: calc($s-12 / var(--zoom));
font-family: worksans;
- font-weight: 600;
}
}
@@ -21,21 +27,21 @@
.grid-editor-label {
background: none;
- border-bottom: calc(1px / var(--zoom)) solid transparent;
+ border-bottom: calc($s-1 / var(--zoom)) solid transparent;
border: 0;
- color: var(--color-distance);
+ color: var(--grid-editor-marker-text);
font-family: worksans;
- font-size: calc(12px / var(--zoom));
- font-weight: 600;
+ font-size: calc($fs-12 / var(--zoom));
+ font-weight: 400;
margin: 0;
- max-width: calc(80px / var(--zoom));
+ max-width: calc($s-80 / var(--zoom));
padding: 0;
- padding: 4px;
+ padding: $s-4;
text-align: center;
&:focus {
outline: none;
- border-bottom: calc(1px / var(--zoom)) solid var(--color-distance);
+ border-bottom: calc($s-1 / var(--zoom)) solid var(--grid-editor-marker-text);
}
}
@@ -46,40 +52,48 @@
margin: 0;
padding: 0;
position: absolute;
- right: calc(20px / var(--zoom));
- width: calc(20px / var(--zoom));
- height: calc(20px / var(--zoom));
+ top: calc($s-6 / var(--zoom));
+ right: calc($s-20 / var(--zoom));
+ width: calc($s-20 / var(--zoom));
+ height: calc($s-20 / var(--zoom));
svg {
- width: calc(16px / var(--zoom));
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: calc($s-16 / var(--zoom));
height: auto;
- fill: var(--color-distance);
+ stroke: var(--grid-editor-marker-color);
}
}
.grid-frame {
- fill: #f6f6f6;
- stroke: var(--color-distance);
- stroke-width: calc(1 / var(--zoom));
+ fill: var(--grid-editor-marker-color);
+ fill-opacity: 0.1;
}
.grid-plus-button {
cursor: pointer;
+ opacity: 0.5;
.grid-plus-shape {
- fill: var(--color-distance);
- stroke: var(--color-distance);
- stroke-width: calc(1 / var(--zoom));
+ fill: var(--grid-editor-plus-btn-background);
+ stroke: var(--grid-editor-plus-btn-background);
+ stroke-width: calc($s-1 / var(--zoom));
}
.grid-plus-icon {
- fill: white;
+ stroke: var(--grid-editor-plus-btn-foreground);
+ }
+
+ &:hover {
+ opacity: 1;
}
}
.grid-cell-outline {
fill: transparent;
- stroke: var(--color-distance);
+ stroke: var(--grid-editor-line-color);
stroke-opacity: 0.5;
stroke-width: calc(1 / var(--zoom));
@@ -89,3 +103,52 @@
stroke-width: calc(2 / var(--zoom));
}
}
+
+.grid-actions {
+ pointer-events: none;
+ position: absolute;
+ top: $s-44;
+ left: 50%;
+
+ .grid-actions-container {
+ @include flexRow;
+ background: var(--panel-background-color);
+ border-radius: $br-12;
+ box-shadow: 0px 0px $s-12 0px var(--menu-shadow-color);
+ gap: $s-8;
+ height: $s-48;
+ margin-left: -50%;
+ padding: $s-8;
+ pointer-events: initial;
+ width: $s-512;
+ }
+
+ .grid-actions-title {
+ flex: 1;
+ font-size: $fs-12;
+ color: var(--color-foreground-secondary);
+ padding-left: $s-8;
+ }
+
+ .board-name {
+ }
+
+ .locate-btn {
+ @extend .button-secondary;
+ text-transform: uppercase;
+ padding: $s-8 $s-20;
+ font-size: $fs-11;
+ }
+ .done-btn {
+ @extend .button-primary;
+ text-transform: uppercase;
+ padding: $s-8 $s-20;
+ font-size: $fs-11;
+ }
+ .close-btn {
+ @extend .button-tertiary;
+ svg {
+ @extend .button-icon;
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/workspace/viewport/rules.cljs b/frontend/src/app/main/ui/workspace/viewport/rules.cljs
index 0e4420eaf..87ec78766 100644
--- a/frontend/src/app/main/ui/workspace/viewport/rules.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/rules.cljs
@@ -157,7 +157,8 @@
step (calculate-step-size zoom)
clip-id (str "clip-rule-" (d/name axis))
new-css-system (mf/use-ctx ctx/new-css-system)
- font-color (if new-css-system new-css-font-color font-color)]
+ font-color (if new-css-system new-css-font-color font-color)
+ rules-background (if new-css-system new-css-rules-background rules-background)]
[:*
(let [{:keys [x y width height]} (get-background-area vbox zoom-inverse axis)]
diff --git a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs
index 1413693a9..82356e252 100644
--- a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs
@@ -9,11 +9,11 @@
[app.common.pages.helpers :as cph]
[app.common.types.shape.layout :as ctl]
[app.main.data.workspace :as dw]
- [app.main.data.workspace.grid-layout.editor :as dwge]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
+ [app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]]
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@@ -56,7 +56,7 @@
[:div.viewport-actions-title
[:& i18n/tr-html {:tag-name "span"
:label "workspace.top-bar.read-only"}]]
- [:button.btn-primary {:on-click handle-close-view-mode} "Done"]
+ [:button.btn-primary {:on-click handle-close-view-mode} (tr "workspace.top-bar.read-only.done")]
[:button.btn-icon-basic {:on-click handle-close-view-mode} i/close]]]
path-edition?
@@ -64,10 +64,4 @@
[:& path-actions {:shape shape}]]
grid-edition?
- [:div.viewport-actions
- [:div.viewport-actions-container
- [:div.viewport-actions-title
- (tr "workspace.layout_grid.editor.title") " " [:span.grid-edit-board-name (:name shape)]]
- [:button.btn-secondary {:on-click #(st/emit! (dwge/locate-board (:id shape)))} "Locate"]
- [:button.btn-primary {:on-click #(st/emit! dw/clear-edition-mode)} "Done"]
- [:button.btn-icon-basic {:on-click #(st/emit! dw/clear-edition-mode)} i/close]]])))
+ [:& grid-edition-actions {:shape shape}])))
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index 7bb654829..cda611ae5 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -3462,6 +3462,18 @@ msgstr "Zoom to selected"
msgid "workspace.layout_grid.editor.title"
msgstr "Editing grid"
+msgid "workspace.layout_grid.editor.top-bar.locate"
+msgstr "Locate"
+
+msgid "workspace.layout_grid.editor.top-bar.done"
+msgstr "Done"
+
+msgid "workspace.layout_grid.editor.options.edit-grid"
+msgstr "Edit grid"
+
+msgid "workspace.layout_grid.editor.options.exit"
+msgstr "Exit"
+
#: src/app/main/ui/workspace/libraries.cljs
msgid "workspace.libraries.add"
msgstr "Add"
@@ -4994,6 +5006,9 @@ msgstr "Click to close the path"
msgid "workspace.top-bar.read-only"
msgstr "**Inspect mode** (View Only)"
+msgid "workspace.top-bar.read-only.done"
+msgstr "Done"
+
msgid "media.image"
msgstr "Image"
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index 68cc7036d..c547166cb 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -3536,6 +3536,18 @@ msgstr "Zoom a selección"
msgid "workspace.layout_grid.editor.title"
msgstr "Editando rejilla"
+msgid "workspace.layout_grid.editor.top-bar.locate"
+msgstr "Mostrar"
+
+msgid "workspace.layout_grid.editor.top-bar.done"
+msgstr "Hecho"
+
+msgid "workspace.layout_grid.editor.options.edit-grid"
+msgstr "Editar rejilla"
+
+msgid "workspace.layout_grid.editor.options.exit"
+msgstr "Salir"
+
#: src/app/main/ui/workspace/libraries.cljs
msgid "workspace.libraries.add"
msgstr "Añadir"
@@ -5095,6 +5107,9 @@ msgstr "Pulsar para cerrar la ruta"
msgid "workspace.top-bar.read-only"
msgstr "**Modo inspección** (View only)"
+msgid "workspace.top-bar.read-only.done"
+msgstr "Hecho"
+
msgid "media.image"
msgstr "Imagen"