0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

Merge pull request #3397 from penpot/juan-history-redesign

💄  History panel redesign
This commit is contained in:
Alejandro 2023-07-11 06:52:40 +02:00 committed by GitHub
commit b8dbd16b01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 314 additions and 44 deletions

View 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

View file

@ -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

View file

@ -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);
}

View file

@ -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))

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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)}])])])))

View file

@ -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"}

View 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;
}
}
}
}
}

View file

@ -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;

View file

@ -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;
}