mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 23:49:45 -05:00
💄 History panel redesign
This commit is contained in:
parent
1ff08bfe6a
commit
a77d82883f
11 changed files with 314 additions and 44 deletions
3
frontend/resources/images/icons/history-refactor.svg
Normal file
3
frontend/resources/images/icons/history-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2.4 8a6 6 0 111.758 4.242M2.4 8l2.1-2M2.4 8L1 5.5m7.4-.7v3.6l2.4 1.2"/>
|
||||
</svg>
|
After Width: | Height: | Size: 201 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 10 8-8m0 0H2m8 0v8"/>
|
||||
<path d="M4 12l8-8zm8-8H4zm0 0v8z"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 153 B After Width: | Height: | Size: 156 B |
|
@ -8,6 +8,8 @@
|
|||
.light,
|
||||
.default {
|
||||
--scrollbar-background-color: var(--color-foreground-secondary);
|
||||
--panel-background-color: var(--color-background-primary);
|
||||
--panel-title-background-color: var(--color-background-secondary);
|
||||
|
||||
--button-background-hover: var(--color-background-quaternary);
|
||||
--button-foreground-hover: var(--color-accent-primary);
|
||||
|
@ -64,10 +66,9 @@
|
|||
--tab-foreground-color-hover: var(--color-foreground-primary);
|
||||
--tab-foreground-color-selected: var(--color-accent-primary);
|
||||
|
||||
--title-background-color: var(--color-background-secondary);
|
||||
--title-background-color: var(--color-background-primary);
|
||||
--title-foreground-color: var(--color-foreground-secondary);
|
||||
--title-foreground-color-hover: var(--color-foreground-primary);
|
||||
--title-background-color: var(--color-background-primary);
|
||||
|
||||
--layer-row-background-color: var(--color-background-primary);
|
||||
--layer-row-background-color-hover: var(--color-background-secondary);
|
||||
|
@ -139,6 +140,7 @@
|
|||
--color-bullet-border-color: var(--color-background-quaternary);
|
||||
--palette-handler-background-color: var(--color-background-quaternary);
|
||||
|
||||
--assets-title-background-color: var(--color-background-primary);
|
||||
--assets-item-background-color: var(--color-background-tertiary);
|
||||
--assets-item-background-color-hover: var(--color-background-quaternary);
|
||||
--assets-item-name-foreground-color: var(--color-foreground-secondary);
|
||||
|
@ -163,4 +165,14 @@
|
|||
|
||||
--not-found-background-color: var(--color-background-tertiary);
|
||||
--not-found-foreground-color: var(--color-foreground-secondary);
|
||||
|
||||
--entry-foreground-color: var(--color-foreground-secondary);
|
||||
--entry-background-color: var(--color-background-tertiary);
|
||||
--entry-background-color-disabled: var(--color-background-primary);
|
||||
--entry-border-color-disabled: var(--color-background-quaternary);
|
||||
--entry-foreground-color-hover: var(--color-foreground-primary);
|
||||
--entry-background-color-hover: var(--color-background-quaternary);
|
||||
|
||||
--empty-message-background-color: var(--color-background-tertiary);
|
||||
--empty-message-foreground-color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
|
|
@ -322,6 +322,7 @@
|
|||
(def gutter-horizontal-refactor (icon-xref :gutter-horizontal-refactor))
|
||||
(def gutter-vertical-refactor (icon-xref :gutter-vertical-refactor))
|
||||
(def hide-refactor (icon-xref :hide-refactor))
|
||||
(def history-refactor (icon-xref :history-refactor))
|
||||
(def img-refactor (icon-xref :img-refactor))
|
||||
(def icon-refactor (icon-xref :icon-refactor))
|
||||
(def justify-content-center-refactor (icon-xref :justify-content-center-refactor))
|
||||
|
|
|
@ -17,7 +17,8 @@ $width-settings-bar-max: 500px;
|
|||
max-width: 500px;
|
||||
width: var(--width, $width-settings-bar);
|
||||
height: 100%;
|
||||
background-color: var(--color-background-primary);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--panel-background-color);
|
||||
|
||||
.resize-area {
|
||||
position: absolute;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
width: $s-28;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
@extend .button-icon;
|
||||
fill: var(--title-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,15 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.history
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [t] :as i18n]
|
||||
|
@ -161,6 +165,23 @@
|
|||
:image i/image
|
||||
i/layers))
|
||||
|
||||
(defn entry->icon-refactor [{:keys [type]}]
|
||||
(case type
|
||||
:page i/document-refactor
|
||||
:shape i/svg-refactor
|
||||
:rect i/rectangle-refactor
|
||||
:circle i/elipse-refactor
|
||||
:text i/text-refactor
|
||||
:path i/path-refactor
|
||||
:frame i/board-refactor
|
||||
:group i/group-refactor
|
||||
:color i/drop-refactor
|
||||
:typography i/text-palette-refactor
|
||||
:component i/component-refactor
|
||||
:media i/img-refactor
|
||||
:image i/img-refactor
|
||||
i/svg-refactor))
|
||||
|
||||
(defn is-shape? [type]
|
||||
(contains? #{:shape :rect :circle :text :path :frame :group} type))
|
||||
|
||||
|
@ -180,7 +201,7 @@
|
|||
(let [;; Group by id and type
|
||||
entries (->> candidates
|
||||
(remove nil?)
|
||||
(group-by #(vector (:type %) (:operation %) (:id %)) ))
|
||||
(group-by #(vector (:type %) (:operation %) (:id %))))
|
||||
|
||||
single? (fn [coll] (= (count coll) 1))
|
||||
|
||||
|
@ -256,13 +277,37 @@
|
|||
|
||||
(mf/defc history-entry-details [{:keys [entry]}]
|
||||
(let [{entries :items} (mf/deref workspace-undo)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
objects (mf/deref refs/workspace-page-objects)]
|
||||
|
||||
[:div.history-entry-detail
|
||||
(if new-css-system
|
||||
[:div {:class (css :history-entry-detail)}
|
||||
(case (:operation entry)
|
||||
:new
|
||||
(:name (get-object (:detail entry) entries objects))
|
||||
|
||||
:delete
|
||||
[:ul {:class (css :ul.history-entry-details-list)}
|
||||
(for [id (:detail entry)]
|
||||
(let [shape-name (:name (get-object id entries objects))]
|
||||
[:li {:key id} shape-name]))]
|
||||
|
||||
|
||||
:modify
|
||||
[:ul {:class (css :ul.history-entry-details-list)}
|
||||
(for [[id attributes] (:detail entry)]
|
||||
(let [shape-name (:name (get-object id entries objects))]
|
||||
[:li {:key id}
|
||||
[:div shape-name]
|
||||
[:div (str/join ", " attributes)]]))]
|
||||
|
||||
nil)]
|
||||
|
||||
[:div.history-entry-detail
|
||||
(case (:operation entry)
|
||||
:new
|
||||
(:name (get-object (:detail entry) entries objects))
|
||||
|
||||
:delete
|
||||
[:ul.history-entry-details-list
|
||||
(for [id (:detail entry)]
|
||||
|
@ -278,47 +323,98 @@
|
|||
[:div shape-name]
|
||||
[:div (str/join ", " attributes)]]))]
|
||||
|
||||
nil)]))
|
||||
nil)]
|
||||
)))
|
||||
|
||||
(mf/defc history-entry [{:keys [locale entry idx-entry disabled? current?]}]
|
||||
(let [hover? (mf/use-state false)
|
||||
show-detail? (mf/use-state false)]
|
||||
[:div.history-entry {:class (dom/classnames
|
||||
:disabled disabled?
|
||||
:current current?
|
||||
:hover @hover?
|
||||
:show-detail @show-detail?)
|
||||
:on-pointer-enter #(reset! hover? true)
|
||||
:on-pointer-leave #(reset! hover? false)
|
||||
:on-click #(st/emit! (dwc/undo-to-index idx-entry))}
|
||||
[:div.history-entry-summary
|
||||
[:div.history-entry-summary-icon (entry->icon entry)]
|
||||
[:div.history-entry-summary-text (entry->message locale entry)]
|
||||
(when (:detail entry)
|
||||
[:div.history-entry-summary-button {:on-click #(when (:detail entry)
|
||||
(swap! show-detail? not))}
|
||||
i/arrow-slide])]
|
||||
(let [hover? (mf/use-state false)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
show-detail? (mf/use-state false)]
|
||||
(if new-css-system
|
||||
[:div {:class (dom/classnames (css :history-entry) true
|
||||
(css :disabled) disabled?
|
||||
(css :current) current?
|
||||
(css :hover) @hover?
|
||||
(css :show-detail) @show-detail?)
|
||||
:on-pointer-enter #(reset! hover? true)
|
||||
:on-pointer-leave #(reset! hover? false)
|
||||
:on-click #(st/emit! (dwc/undo-to-index idx-entry))}
|
||||
[:div {:class (dom/classnames (css :history-entry-summary) true)}
|
||||
[:div {:class (dom/classnames (css :history-entry-summary-icon) true)} (entry->icon-refactor entry)]
|
||||
[:div {:class (dom/classnames (css :history-entry-summary-text) true)} (entry->message locale entry)]
|
||||
(when (:detail entry)
|
||||
[:div {:class (dom/classnames (css :history-entry-summary-button) true
|
||||
(css :button-opened) @show-detail?)
|
||||
:on-click #(when (:detail entry)
|
||||
(swap! show-detail? not))}
|
||||
i/arrow-refactor])]
|
||||
|
||||
(when show-detail?
|
||||
[:& history-entry-details {:entry entry}])]))
|
||||
(when @show-detail?
|
||||
[:& history-entry-details {:entry entry}])]
|
||||
|
||||
[:div.history-entry {:class (dom/classnames
|
||||
:disabled disabled?
|
||||
:current current?
|
||||
:hover @hover?
|
||||
:show-detail @show-detail?)
|
||||
:on-pointer-enter #(reset! hover? true)
|
||||
:on-pointer-leave #(reset! hover? false)
|
||||
:on-click #(st/emit! (dwc/undo-to-index idx-entry))}
|
||||
[:div.history-entry-summary
|
||||
[:div.history-entry-summary-icon (entry->icon entry)]
|
||||
[:div.history-entry-summary-text (entry->message locale entry)]
|
||||
(when (:detail entry)
|
||||
[:div.history-entry-summary-button {:on-click #(when (:detail entry)
|
||||
(swap! show-detail? not))}
|
||||
i/arrow-slide])]
|
||||
|
||||
(when show-detail?
|
||||
[:& history-entry-details {:entry entry}])])))
|
||||
|
||||
(mf/defc history-toolbox []
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
objects (mf/deref refs/workspace-page-objects)
|
||||
{:keys [items index]} (mf/deref workspace-undo)
|
||||
entries (parse-entries items objects)]
|
||||
[:div.history-toolbox
|
||||
[:div.history-toolbox-title (t locale "workspace.undo.title")]
|
||||
(if (empty? entries)
|
||||
[:div.history-entry-empty
|
||||
[:div.history-entry-empty-icon i/recent]
|
||||
[:div.history-entry-empty-msg (t locale "workspace.undo.empty")]]
|
||||
[:ul.history-entries
|
||||
(for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
|
||||
[:& history-entry {:key (str "entry-" idx-entry)
|
||||
:locale locale
|
||||
:entry entry
|
||||
:idx-entry idx-entry
|
||||
:current? (= idx-entry index)
|
||||
:disabled? (> idx-entry index)}])])]))
|
||||
entries (parse-entries items objects)
|
||||
toggle-history
|
||||
(mf/use-fn
|
||||
#(st/emit! (-> (dw/toggle-layout-flag :document-history)
|
||||
(vary-meta assoc ::ev/origin "history-toolbox"))))]
|
||||
(if new-css-system
|
||||
[:div {:class (css :history-toolbox)}
|
||||
[:div {:class (css :history-toolbox-title)}
|
||||
[:span (t locale "workspace.undo.title")]
|
||||
[:div {:class (css :close-button)
|
||||
:on-click toggle-history}
|
||||
i/close-refactor]]
|
||||
(if (empty? entries)
|
||||
[:div {:class (css :history-entry-empty)}
|
||||
[:div {:class (css :history-entry-empty-icon)} i/history-refactor]
|
||||
[:div {:class (css :history-entry-empty-msg)} (t locale "workspace.undo.empty")]]
|
||||
[:ul {:class (css :history-entries)}
|
||||
(for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
|
||||
[:& history-entry {:key (str "entry-" idx-entry)
|
||||
:locale locale
|
||||
:entry entry
|
||||
:idx-entry idx-entry
|
||||
:current? (= idx-entry index)
|
||||
:disabled? (> idx-entry index)}])])]
|
||||
|
||||
[:div.history-toolbox
|
||||
[:div.history-toolbox-title (t locale "workspace.undo.title")]
|
||||
(if (empty? entries)
|
||||
[:div.history-entry-empty
|
||||
[:div.history-entry-empty-icon i/recent]
|
||||
[:div.history-entry-empty-msg (t locale "workspace.undo.empty")]]
|
||||
[:ul.history-entries
|
||||
(for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
|
||||
[:& history-entry {:key (str "entry-" idx-entry)
|
||||
:locale locale
|
||||
:entry entry
|
||||
:idx-entry idx-entry
|
||||
:current? (= idx-entry index)
|
||||
:disabled? (> idx-entry index)}])])])))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"sidebar_history_button-primary_3QHPC","button-secondary":"sidebar_history_button-secondary_-f-3z","button-tertiary":"sidebar_history_button-tertiary_IzuLu","history-toolbox":"sidebar_history_history-toolbox_-jdvy","history-toolbox-title":"sidebar_history_history-toolbox-title_9pxvS","close-button":"sidebar_history_close-button_CmY2q","button-tag":"sidebar_history_button-tag_9aylo","button-icon":"sidebar_history_button-icon_UeFr2","history-entry-empty":"sidebar_history_history-entry-empty_SINxx","history-entry-empty-icon":"sidebar_history_history-entry-empty-icon_XJdB6","button-icon-small":"sidebar_history_button-icon-small_9M0oh","history-entries":"sidebar_history_history-entries_NgKRp","history-entry":"sidebar_history_history-entry_lGPio","history-entry-summary":"sidebar_history_history-entry-summary_S3Glf","history-entry-summary-button":"sidebar_history_history-entry-summary-button_AjNW8","history-entry-summary-icon":"sidebar_history_history-entry-summary-icon_F-iya","asset-element":"sidebar_history_asset-element_Lm478","new-scrollbar":"sidebar_history_new-scrollbar_lmxNu","history-entry-empty-msg":"sidebar_history_history-entry-empty-msg_S3wX7","disabled":"sidebar_history_disabled_u0U-e","hover":"sidebar_history_hover_RnLwu","button-opened":"sidebar_history_button-opened_PdprO","history-entry-summary-text":"sidebar_history_history-entry-summary-text_bBYso","history-entry-detail":"sidebar_history_history-entry-detail_-QXf6","history-entry-details-list":"sidebar_history_history-entry-details-list_shkso"}
|
155
frontend/src/app/main/ui/workspace/sidebar/history.scss
Normal file
155
frontend/src/app/main/ui/workspace/sidebar/history.scss
Normal file
|
@ -0,0 +1,155 @@
|
|||
// 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";
|
||||
|
||||
.history-toolbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--panel-background-color);
|
||||
|
||||
.history-toolbox-title {
|
||||
@include flexCenter;
|
||||
@include tabTitleTipography;
|
||||
position: relative;
|
||||
height: $s-32;
|
||||
min-height: $s-32;
|
||||
margin: $s-4 $s-4 0 $s-4;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--panel-title-background-color);
|
||||
|
||||
span {
|
||||
@include flexCenter;
|
||||
flex-grow: 1;
|
||||
color: var(--title-foreground-color-hover);
|
||||
}
|
||||
|
||||
.close-button {
|
||||
@extend .button-tertiary;
|
||||
position: absolute;
|
||||
right: $s-2;
|
||||
top: $s-2;
|
||||
height: $s-28;
|
||||
width: $s-28;
|
||||
border-radius: $br-6;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.history-entry-empty {
|
||||
@include flexCenter;
|
||||
flex-direction: column;
|
||||
gap: $s-16;
|
||||
padding: $s-28 $s-16;
|
||||
text-align: center;
|
||||
|
||||
.history-entry-empty-icon {
|
||||
@include flexCenter;
|
||||
height: $s-48;
|
||||
width: $s-48;
|
||||
border-radius: 50%;
|
||||
background-color: var(--empty-message-background-color);
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
height: $s-28;
|
||||
width: $s-28;
|
||||
margin-left: calc(-1 * $s-2);
|
||||
stroke: var(--empty-message-foreground-color);
|
||||
}
|
||||
}
|
||||
|
||||
.history-entry-empty-msg {
|
||||
@include titleTipography;
|
||||
color: var(--title-foreground-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
ul.history-entries {
|
||||
height: 100%;
|
||||
padding: $s-12;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
font-size: $fs-12;
|
||||
|
||||
.history-entry {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
min-height: $s-32;
|
||||
margin: $s-4;
|
||||
padding: $s-4 $s-8;
|
||||
border: $s-2 solid transparent;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--entry-background-color);
|
||||
cursor: pointer;
|
||||
transition: border 0.2s;
|
||||
|
||||
&.disabled {
|
||||
border-color: var(--entry-border-color-disabled);
|
||||
background-color: var(--entry-background-color-disabled);
|
||||
}
|
||||
|
||||
&.hover,
|
||||
&:hover {
|
||||
background-color: var(--entry-background-color-hover);
|
||||
color: var(--entry-foreground-color-hover);
|
||||
.history-entry-summary {
|
||||
.history-entry-summary-icon {
|
||||
svg {
|
||||
stroke: var(--entry-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
.history-entry-summary-button {
|
||||
opacity: $op-10;
|
||||
&.button-opened {
|
||||
svg {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.history-entry-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.history-entry-summary-icon {
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--entry-foreground-color);
|
||||
}
|
||||
}
|
||||
.history-entry-summary-text {
|
||||
margin: 0 $s-8;
|
||||
}
|
||||
.history-entry-summary-button {
|
||||
opacity: $op-0;
|
||||
margin-left: auto;
|
||||
&.button-opened {
|
||||
svg {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--entry-foreground-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.history-entry-detail {
|
||||
display: block;
|
||||
padding-top: $s-16;
|
||||
|
||||
ul.history-entry-details-list {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -107,7 +107,7 @@
|
|||
.advanced-options-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--title-background-color);
|
||||
background-color: var(--assets-title-background-color);
|
||||
|
||||
.typography-options {
|
||||
position: relative;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
padding: $s-2 $s-2 $s-2 0;
|
||||
margin: $s-4 $s-4 0 $s-4;
|
||||
border-radius: $br-6;
|
||||
background-color: var(--title-background-color);
|
||||
background-color: var(--panel-title-background-color);
|
||||
|
||||
.shortcuts-title {
|
||||
@include flexCenter;
|
||||
|
@ -31,6 +31,7 @@
|
|||
height: $s-28;
|
||||
width: $s-28;
|
||||
border-radius: $br-5;
|
||||
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue