mirror of
https://github.com/penpot/penpot.git
synced 2025-05-07 20:35:53 +02:00
commit
ca5091d8b0
12 changed files with 95 additions and 38 deletions
|
@ -217,5 +217,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chrome-picker {
|
||||||
|
font-family: inherit !important;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) {
|
||||||
|
width: 25px !important;
|
||||||
|
height: 25px !important;
|
||||||
|
border-radius: 20px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,8 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: $fs12;
|
font-size: $fs12;
|
||||||
padding: $small $x-small;
|
padding: $small $x-small;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: $color-gray-60;
|
fill: $color-gray-60;
|
||||||
|
@ -130,6 +132,10 @@
|
||||||
margin: 0 $x-small;
|
margin: 0 $x-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shortcut {
|
||||||
|
color: $color-gray-20;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $color-primary-lighter;
|
background-color: $color-primary-lighter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1516,11 +1516,14 @@
|
||||||
;; Shortcuts impl https://github.com/ccampbell/mousetrap
|
;; Shortcuts impl https://github.com/ccampbell/mousetrap
|
||||||
|
|
||||||
(def shortcuts
|
(def shortcuts
|
||||||
{"ctrl+shift+m" #(st/emit! (toggle-layout-flag :sitemap))
|
{"ctrl+m" #(st/emit! (toggle-layout-flag :sitemap))
|
||||||
"ctrl+shift+i" #(st/emit! (toggle-layout-flag :libraries))
|
"ctrl+i" #(st/emit! (toggle-layout-flag :libraries))
|
||||||
"ctrl+shift+l" #(st/emit! (toggle-layout-flag :layers))
|
"ctrl+l" #(st/emit! (toggle-layout-flag :layers))
|
||||||
"ctrl+shift+r" #(st/emit! (toggle-layout-flag :rules))
|
"ctrl+r" #(st/emit! (toggle-layout-flag :rules))
|
||||||
"ctrl+shift+d" #(st/emit! (toggle-layout-flag :dynamic-alignment))
|
"ctrl+a" #(st/emit! (toggle-layout-flag :dynamic-alignment))
|
||||||
|
"ctrl+p" #(st/emit! (toggle-layout-flag :colorpalette))
|
||||||
|
"ctrl+'" #(st/emit! (toggle-layout-flag :display-grid))
|
||||||
|
"ctrl+shift+'" #(st/emit! (toggle-layout-flag :snap-grid))
|
||||||
"+" #(st/emit! (increase-zoom nil))
|
"+" #(st/emit! (increase-zoom nil))
|
||||||
"-" #(st/emit! (decrease-zoom nil))
|
"-" #(st/emit! (decrease-zoom nil))
|
||||||
"g" #(st/emit! create-group)
|
"g" #(st/emit! create-group)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
[uxbox.main.ui.icons :as i]
|
[uxbox.main.ui.icons :as i]
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]))
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]))
|
||||||
|
|
||||||
(mf/defc editable-select [{:keys [value type options class on-change]}]
|
(mf/defc editable-select [{:keys [value type options class on-change placeholder]}]
|
||||||
(let [state (mf/use-state {:id (uuid/next)
|
(let [state (mf/use-state {:id (uuid/next)
|
||||||
:is-open? false
|
:is-open? false
|
||||||
:current-value value})
|
:current-value value})
|
||||||
|
@ -52,6 +52,7 @@
|
||||||
[:div.editable-select {:class class}
|
[:div.editable-select {:class class}
|
||||||
[:input.input-text {:value (or (-> @state :current-value value->label) "")
|
[:input.input-text {:value (or (-> @state :current-value value->label) "")
|
||||||
:on-change handle-change-input
|
:on-change handle-change-input
|
||||||
|
:placeholder placeholder
|
||||||
:type type}]
|
:type type}]
|
||||||
[:span.dropdown-button {:on-click open-dropdown} i/arrow-down]
|
[:span.dropdown-button {:on-click open-dropdown} i/arrow-down]
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,9 @@
|
||||||
(rx/of handle-drawing-generic)))))
|
(rx/of handle-drawing-generic)))))
|
||||||
|
|
||||||
(def handle-drawing-generic
|
(def handle-drawing-generic
|
||||||
(letfn [(resize-shape [{:keys [x y] :as shape} initial point lock? point-snap]
|
(letfn [(resize-shape [{:keys [x y] :as shape} point lock? point-snap]
|
||||||
(let [shape' (geom/shape->rect-shape shape)
|
(let [initial (gpt/point x y)
|
||||||
|
shape' (geom/shape->rect-shape shape)
|
||||||
shapev (gpt/point (:width shape') (:height shape'))
|
shapev (gpt/point (:width shape') (:height shape'))
|
||||||
deltav (gpt/to-vec initial point-snap)
|
deltav (gpt/to-vec initial point-snap)
|
||||||
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
||||||
|
@ -130,8 +131,8 @@
|
||||||
(assoc-in [:modifiers :resize-origin] (gpt/point x y))
|
(assoc-in [:modifiers :resize-origin] (gpt/point x y))
|
||||||
(assoc-in [:modifiers :resize-rotation] 0))))
|
(assoc-in [:modifiers :resize-rotation] 0))))
|
||||||
|
|
||||||
(update-drawing [state initial point lock? point-snap]
|
(update-drawing [state point lock? point-snap]
|
||||||
(update-in state [:workspace-local :drawing] resize-shape initial point lock? point-snap))]
|
(update-in state [:workspace-local :drawing] resize-shape point lock? point-snap))]
|
||||||
|
|
||||||
(ptk/reify ::handle-drawing-generic
|
(ptk/reify ::handle-drawing-generic
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -140,7 +141,6 @@
|
||||||
stoper? #(or (ms/mouse-up? %) (= % :interrupt))
|
stoper? #(or (ms/mouse-up? %) (= % :interrupt))
|
||||||
stoper (rx/filter stoper? stream)
|
stoper (rx/filter stoper? stream)
|
||||||
initial @ms/mouse-position
|
initial @ms/mouse-position
|
||||||
mouse ms/mouse-position
|
|
||||||
|
|
||||||
page-id (get state :current-page-id)
|
page-id (get state :current-page-id)
|
||||||
objects (get-in state [:workspace-data page-id :objects])
|
objects (get-in state [:workspace-data page-id :objects])
|
||||||
|
@ -165,12 +165,18 @@
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of #(assoc-in state [:workspace-local :drawing] shape))
|
(rx/of #(assoc-in state [:workspace-local :drawing] shape))
|
||||||
|
|
||||||
(->> mouse
|
(->> (snap/closest-snap-point page-id [shape] layout initial)
|
||||||
|
(rx/map (fn [{:keys [x y]}]
|
||||||
|
#(-> %
|
||||||
|
(assoc-in [:workspace-local :drawing :x] x)
|
||||||
|
(assoc-in [:workspace-local :drawing :y] y)))))
|
||||||
|
|
||||||
|
(->> ms/mouse-position
|
||||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||||
(rx/switch-map (fn [[point :as current]]
|
(rx/switch-map (fn [[point :as current]]
|
||||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
(->> (snap/closest-snap-point page-id [shape] layout point)
|
||||||
(rx/map #(conj current %)))))
|
(rx/map #(conj current %)))))
|
||||||
(rx/map (fn [[pt ctrl? point-snap]] #(update-drawing % initial pt ctrl? point-snap)))
|
(rx/map (fn [[pt ctrl? point-snap]] #(update-drawing % pt ctrl? point-snap)))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
(rx/of handle-finish-drawing)))))))
|
(rx/of handle-finish-drawing)))))))
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,16 @@
|
||||||
:stroke-width (str (/ 1 zoom))}}])]])))
|
:stroke-width (str (/ 1 zoom))}}])]])))
|
||||||
|
|
||||||
(mf/defc layout-grid [{:keys [key frame zoom grid]}]
|
(mf/defc layout-grid [{:keys [key frame zoom grid]}]
|
||||||
(let [{color-value :value color-opacity :opacity} (-> grid :params :color)]
|
(let [{color-value :value color-opacity :opacity} (-> grid :params :color)
|
||||||
|
gutter (-> grid :params :gutter)
|
||||||
|
gutter? (and (not (nil? gutter)) (not= gutter 0))
|
||||||
|
|
||||||
|
style (if gutter?
|
||||||
|
#js {:fill color-value
|
||||||
|
:opacity color-opacity}
|
||||||
|
#js {:stroke color-value
|
||||||
|
:strokeOpacity color-opacity
|
||||||
|
:fill "transparent"})]
|
||||||
[:g.grid
|
[:g.grid
|
||||||
(for [{:keys [x y width height]} (gg/grid-areas frame grid)]
|
(for [{:keys [x y width height]} (gg/grid-areas frame grid)]
|
||||||
[:rect {:key (str key "-" x "-" y)
|
[:rect {:key (str key "-" x "-" y)
|
||||||
|
@ -50,8 +59,7 @@
|
||||||
:y y
|
:y y
|
||||||
:width width
|
:width width
|
||||||
:height height
|
:height height
|
||||||
:style {:fill color-value
|
:style style}])]))
|
||||||
:opacity color-opacity}}])]))
|
|
||||||
|
|
||||||
(mf/defc grid-display-frame [{:keys [frame zoom]}]
|
(mf/defc grid-display-frame [{:keys [frame zoom]}]
|
||||||
(let [grids (:grids frame)]
|
(let [grids (:grids frame)]
|
||||||
|
|
|
@ -75,43 +75,50 @@
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :rules)
|
(if (contains? layout :rules)
|
||||||
(t locale "workspace.header.menu.hide-rules")
|
(t locale "workspace.header.menu.hide-rules")
|
||||||
(t locale "workspace.header.menu.show-rules"))]]
|
(t locale "workspace.header.menu.show-rules"))]
|
||||||
|
[:span.shortcut "Ctrl+r"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :display-grid))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :display-grid))}
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :display-grid)
|
(if (contains? layout :display-grid)
|
||||||
(t locale "workspace.header.menu.hide-grid")
|
(t locale "workspace.header.menu.hide-grid")
|
||||||
(t locale "workspace.header.menu.show-grid"))]]
|
(t locale "workspace.header.menu.show-grid"))]
|
||||||
|
[:span.shortcut "Ctrl+'"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :snap-grid))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :snap-grid))}
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :snap-grid)
|
(if (contains? layout :snap-grid)
|
||||||
(t locale "workspace.header.menu.disable-snap-grid")
|
(t locale "workspace.header.menu.disable-snap-grid")
|
||||||
(t locale "workspace.header.menu.enable-snap-grid"))]]
|
(t locale "workspace.header.menu.enable-snap-grid"))]
|
||||||
|
[:span.shortcut "Ctrl+Shift+'"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :sitemap :layers))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :sitemap :layers))}
|
||||||
[:span
|
[:span
|
||||||
(if (or (contains? layout :sitemap) (contains? layout :layers))
|
(if (or (contains? layout :sitemap) (contains? layout :layers))
|
||||||
(t locale "workspace.header.menu.hide-layers")
|
(t locale "workspace.header.menu.hide-layers")
|
||||||
(t locale "workspace.header.menu.show-layers"))]]
|
(t locale "workspace.header.menu.show-layers"))]
|
||||||
|
[:span.shortcut "Ctrl+l"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :colorpalette)
|
(if (contains? layout :colorpalette)
|
||||||
(t locale "workspace.header.menu.hide-palette")
|
(t locale "workspace.header.menu.hide-palette")
|
||||||
(t locale "workspace.header.menu.show-palette"))]]
|
(t locale "workspace.header.menu.show-palette"))]
|
||||||
|
[:span.shortcut "Ctrl+p"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :libraries)
|
(if (contains? layout :libraries)
|
||||||
(t locale "workspace.header.menu.hide-libraries")
|
(t locale "workspace.header.menu.hide-libraries")
|
||||||
(t locale "workspace.header.menu.show-libraries"))]]
|
(t locale "workspace.header.menu.show-libraries"))]
|
||||||
|
[:span.shortcut "Ctrl+i"]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :dynamic-alignment))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :dynamic-alignment))}
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :dynamic-alignment)
|
(if (contains? layout :dynamic-alignment)
|
||||||
(t locale "workspace.header.menu.disable-dynamic-alignment")
|
(t locale "workspace.header.menu.disable-dynamic-alignment")
|
||||||
(t locale "workspace.header.menu.enable-dynamic-alignment"))]]
|
(t locale "workspace.header.menu.enable-dynamic-alignment"))]
|
||||||
|
[:span.shortcut "Ctrl+a"]]
|
||||||
]]]))
|
]]]))
|
||||||
|
|
||||||
;; --- Header Component
|
;; --- Header Component
|
||||||
|
|
|
@ -146,6 +146,7 @@
|
||||||
:type (when (number? (:size params)) "number" )
|
:type (when (number? (:size params)) "number" )
|
||||||
:class "input-option"
|
:class "input-option"
|
||||||
:options size-options
|
:options size-options
|
||||||
|
:placeholder "Auto"
|
||||||
:on-change handle-change-size}])
|
:on-change handle-change-size}])
|
||||||
|
|
||||||
[:div.grid-option-main-actions
|
[:div.grid-option-main-actions
|
||||||
|
@ -167,6 +168,7 @@
|
||||||
:options size-options
|
:options size-options
|
||||||
:value (:size params)
|
:value (:size params)
|
||||||
:min 1
|
:min 1
|
||||||
|
:placeholder "Auto"
|
||||||
:on-change handle-change-size}])
|
:on-change handle-change-size}])
|
||||||
|
|
||||||
(when (= :column type)
|
(when (= :column type)
|
||||||
|
@ -175,6 +177,7 @@
|
||||||
:options size-options
|
:options size-options
|
||||||
:value (:size params)
|
:value (:size params)
|
||||||
:min 1
|
:min 1
|
||||||
|
:placeholder "Auto"
|
||||||
:on-change handle-change-size}])
|
:on-change handle-change-size}])
|
||||||
|
|
||||||
(when (#{:row :column} type)
|
(when (#{:row :column} type)
|
||||||
|
@ -196,6 +199,7 @@
|
||||||
(t locale "workspace.options.grid.params.height")
|
(t locale "workspace.options.grid.params.height")
|
||||||
(t locale "workspace.options.grid.params.width"))
|
(t locale "workspace.options.grid.params.width"))
|
||||||
:class "pixels"
|
:class "pixels"
|
||||||
|
:placeholder "Auto"
|
||||||
:value (or (:item-length params) "")
|
:value (or (:item-length params) "")
|
||||||
:on-change handle-change-item-length}])
|
:on-change handle-change-item-length}])
|
||||||
|
|
||||||
|
@ -205,10 +209,12 @@
|
||||||
:class "pixels"
|
:class "pixels"
|
||||||
:value (:gutter params)
|
:value (:gutter params)
|
||||||
:min 0
|
:min 0
|
||||||
|
:placeholder "0"
|
||||||
:on-change (handle-change :params :gutter)}]
|
:on-change (handle-change :params :gutter)}]
|
||||||
[:& input-row {:label (t locale "workspace.options.grid.params.margin")
|
[:& input-row {:label (t locale "workspace.options.grid.params.margin")
|
||||||
:class "pixels"
|
:class "pixels"
|
||||||
:min 0
|
:min 0
|
||||||
|
:placeholder "0"
|
||||||
:value (:margin params)
|
:value (:margin params)
|
||||||
:on-change (handle-change :params :margin)}]])
|
:on-change (handle-change :params :margin)}]])
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[uxbox.main.ui.components.editable-select :refer [editable-select]]
|
[uxbox.main.ui.components.editable-select :refer [editable-select]]
|
||||||
[uxbox.util.dom :as dom]))
|
[uxbox.util.dom :as dom]))
|
||||||
|
|
||||||
(mf/defc input-row [{:keys [label options value class min max on-change type]}]
|
(mf/defc input-row [{:keys [label options value class min max on-change type placeholder]}]
|
||||||
[:div.row-flex.input-row
|
[:div.row-flex.input-row
|
||||||
[:span.element-set-subtitle label]
|
[:span.element-set-subtitle label]
|
||||||
[:div.input-element {:class class}
|
[:div.input-element {:class class}
|
||||||
|
@ -26,11 +26,13 @@
|
||||||
:class "input-option"
|
:class "input-option"
|
||||||
:options options
|
:options options
|
||||||
:on-change on-change}]
|
:on-change on-change}]
|
||||||
|
|
||||||
:editable-select
|
:editable-select
|
||||||
[:& editable-select {:value value
|
[:& editable-select {:value value
|
||||||
:class "input-option"
|
:class "input-option"
|
||||||
:options options
|
:options options
|
||||||
:type (when (number? value) "number")
|
:type (when (number? value) "number")
|
||||||
|
:placeholder placeholder
|
||||||
:on-change on-change}]
|
:on-change on-change}]
|
||||||
|
|
||||||
(let [handle-change
|
(let [handle-change
|
||||||
|
@ -41,9 +43,9 @@
|
||||||
(or (not max) (<= value max)))
|
(or (not max) (<= value max)))
|
||||||
(on-change value))))]
|
(on-change value))))]
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
{:placeholder label
|
{:placeholder placeholder
|
||||||
:type "number"
|
:type "number"
|
||||||
:on-change handle-change
|
:on-change handle-change
|
||||||
:value value}]))
|
:value (or value "")}]))
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
|
|
@ -56,12 +56,16 @@
|
||||||
(when (not-empty snaps) (map #(vector point %) snaps))) @state))]
|
(when (not-empty snaps) (map #(vector point %) snaps))) @state))]
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
|
(let [sub
|
||||||
(->> subject
|
(->> subject
|
||||||
(rx/switch-map #(rx/combine-latest
|
(rx/switch-map #(rx/combine-latest
|
||||||
concat
|
concat
|
||||||
(get-snap :y %)
|
(get-snap :y %)
|
||||||
(get-snap :x %)))
|
(get-snap :x %)))
|
||||||
(rx/subs #(reset! state %)))))
|
(rx/subs #(reset! state %)))]
|
||||||
|
|
||||||
|
;; On unmount callback
|
||||||
|
#(rx/dispose! sub))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps shapes)
|
(mf/deps shapes)
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
[v]
|
[v]
|
||||||
(try
|
(try
|
||||||
(into [] (gcolor/hexToRgb v))
|
(into [] (gcolor/hexToRgb v))
|
||||||
(catch js/Object e [0 0 0])))
|
(catch :default e [0 0 0])))
|
||||||
|
|
||||||
(defn rgb->hex
|
(defn rgb->hex
|
||||||
[[r g b]]
|
[[r g b]]
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
[{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}]
|
[{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}]
|
||||||
(let [size (if (number? size) size (calculate-size width item-length margin gutter))
|
(let [size (if (number? size) size (calculate-size width item-length margin gutter))
|
||||||
parts (/ width size)
|
parts (/ width size)
|
||||||
item-width (or item-length (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
item-width (min (or item-length ##Inf) (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
||||||
item-height height
|
item-height height
|
||||||
initial-offset (case type
|
initial-offset (case type
|
||||||
:right (- width (* item-width size) (* gutter (dec size)) margin)
|
:right (- width (* item-width size) (* gutter (dec size)) margin)
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
(let [size (if (number? size) size (calculate-size height item-length margin gutter))
|
(let [size (if (number? size) size (calculate-size height item-length margin gutter))
|
||||||
parts (/ height size)
|
parts (/ height size)
|
||||||
item-width width
|
item-width width
|
||||||
item-height (or item-length (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
item-height (min (or item-length ##Inf) (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
||||||
initial-offset (case type
|
initial-offset (case type
|
||||||
:right (- height (* item-height size) (* gutter (dec size)) margin)
|
:right (- height (* item-height size) (* gutter (dec size)) margin)
|
||||||
:center (/ (- height (* item-height size) (* gutter (dec size))) 2)
|
:center (/ (- height (* item-height size) (* gutter (dec size))) 2)
|
||||||
|
|
Loading…
Add table
Reference in a new issue