mirror of
https://github.com/penpot/penpot.git
synced 2025-06-09 03:51:38 +02:00
💄 Update comment UI with new design
This commit is contained in:
parent
25c60f3e0f
commit
f4323fd1ac
12 changed files with 999 additions and 255 deletions
|
@ -75,6 +75,12 @@
|
||||||
stroke: var(--button-primary-foreground-color-active);
|
stroke: var(--button-primary-foreground-color-active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&:global(.disabled) {
|
||||||
|
background-color: var(--button-background-color-disabled);
|
||||||
|
border: $s-1 solid var(--button-border-color-disabled);
|
||||||
|
color: var(--button-foreground-color-disabled);
|
||||||
|
cursor: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-secondary {
|
.button-secondary {
|
||||||
|
@ -118,6 +124,12 @@
|
||||||
stroke: var(--button-secondary-foreground-color-active);
|
stroke: var(--button-secondary-foreground-color-active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&:global(.disabled) {
|
||||||
|
background-color: var(--button-background-color-disabled);
|
||||||
|
border: $s-1 solid var(--button-border-color-disabled);
|
||||||
|
color: var(--button-foreground-color-disabled);
|
||||||
|
cursor: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-tertiary {
|
.button-tertiary {
|
||||||
|
@ -161,6 +173,12 @@
|
||||||
stroke: var(--button-tertiary-foreground-color-active);
|
stroke: var(--button-tertiary-foreground-color-active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&:global(.disabled) {
|
||||||
|
background-color: var(--button-background-color-disabled);
|
||||||
|
border: $s-1 solid var(--button-border-color-disabled);
|
||||||
|
color: var(--button-foreground-color-disabled);
|
||||||
|
cursor: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-radio {
|
.button-radio {
|
||||||
|
@ -375,6 +393,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox-icon {
|
||||||
|
@include flexCenter;
|
||||||
|
width: $s-16;
|
||||||
|
height: $s-16;
|
||||||
|
min-width: $s-16;
|
||||||
|
min-height: $s-16;
|
||||||
|
border-radius: $br-6;
|
||||||
|
background-color: var(--input-background-color);
|
||||||
|
svg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&:global(.checked) {
|
||||||
|
background-color: var(--input-border-color-active);
|
||||||
|
svg {
|
||||||
|
@extend .button-icon-small;
|
||||||
|
stroke: var(--input-details-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input-checkbox {
|
.input-checkbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -385,20 +423,7 @@
|
||||||
gap: $s-6;
|
gap: $s-6;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
span {
|
span {
|
||||||
@include flexCenter;
|
@extend .checkbox-icon;
|
||||||
width: $s-16;
|
|
||||||
height: $s-16;
|
|
||||||
min-width: $s-16;
|
|
||||||
min-height: $s-16;
|
|
||||||
border-radius: $br-6;
|
|
||||||
background-color: var(--input-background-color);
|
|
||||||
&:global(.checked) {
|
|
||||||
background-color: var(--input-border-color-active);
|
|
||||||
svg {
|
|
||||||
@extend .button-icon-small;
|
|
||||||
stroke: var(--input-details-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -505,6 +530,28 @@
|
||||||
grid-template-columns: $s-92 1fr;
|
grid-template-columns: $s-92 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment-bubbles {
|
||||||
|
@include titleTipography;
|
||||||
|
@include flexCenter;
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-32;
|
||||||
|
border-radius: $br-circle;
|
||||||
|
background-color: var(--comment-bullet-background-color-rest);
|
||||||
|
border: $s-1 solid var(--comment-bullet-border-color-rest);
|
||||||
|
color: var(--comment-bullet-foreground-color-rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
.resolved-comment-bubble {
|
||||||
|
background-color: var(--comment-bullet-background-color-resolved);
|
||||||
|
border: $s-1 solid var(--comment-bullet-border-color-resolved);
|
||||||
|
color: var(--comment-bullet-foreground-color-resolved);
|
||||||
|
}
|
||||||
|
.unread-comment-bubble {
|
||||||
|
background-color: var(--comment-bullet-background-color-unread);
|
||||||
|
border: $s-1 solid var(--comment-bullet-border-color-unread);
|
||||||
|
color: var(--comment-bullet-foreground-color-unread);
|
||||||
|
}
|
||||||
|
|
||||||
// SELECTS AND DROPDOWNS
|
// SELECTS AND DROPDOWNS
|
||||||
.menu-dropdown {
|
.menu-dropdown {
|
||||||
@include menuShadow;
|
@include menuShadow;
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
--button-background-focus: var(--color-background-secondary);
|
--button-background-focus: var(--color-background-secondary);
|
||||||
--button-foreground-focus: var(--color-foreground-primary);
|
--button-foreground-focus: var(--color-foreground-primary);
|
||||||
--button-border-focus: var(--color-accent-primary);
|
--button-border-focus: var(--color-accent-primary);
|
||||||
--button-foreground-color-disabled: var(--color-background-quaternary);
|
--button-foreground-color-disabled: var(--color-foreground-secondary);
|
||||||
|
--button-background-color-disabled: var(--color-background-primary);
|
||||||
|
--button-border-color-disabled: var(--color-background-quaternary);
|
||||||
|
|
||||||
--button-primary-background-color-rest: var(--color-accent-primary);
|
--button-primary-background-color-rest: var(--color-accent-primary);
|
||||||
--button-primary-border-color-rest: var(--color-accent-primary);
|
--button-primary-border-color-rest: var(--color-accent-primary);
|
||||||
|
@ -228,4 +230,18 @@
|
||||||
--colorpicker-details-color: var(--color-background-quaternary);
|
--colorpicker-details-color: var(--color-background-quaternary);
|
||||||
--colorpicker-details-color-selected: var(--color-accent-primary);
|
--colorpicker-details-color-selected: var(--color-accent-primary);
|
||||||
--colorpicker-handlers-color: var(--color-foreground-primary);
|
--colorpicker-handlers-color: var(--color-foreground-primary);
|
||||||
|
|
||||||
|
// COMMENTS
|
||||||
|
--comment-title-color: var(--color-foreground-primary);
|
||||||
|
--comment-subtitle-color: var(--color-foreground-secondary);
|
||||||
|
--comment-bullet-background-color-rest: var(--color-background-quaternary);
|
||||||
|
--comment-bullet-foreground-color-rest: var(--color-foreground-primary);
|
||||||
|
--comment-bullet-border-color-rest: var(--color-background-secondary);
|
||||||
|
--comment-bullet-background-color-unread: var(--color-accent-primary);
|
||||||
|
--comment-bullet-foreground-color-unread: var(--color-background-primary);
|
||||||
|
--comment-bullet-border-color-unread: var(--color-background-secondary);
|
||||||
|
--comment-bullet-background-color-resolved: var(--color-background-primary);
|
||||||
|
--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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.main.ui.comments
|
(ns app.main.ui.comments
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||||
[app.main.ui.components.forms :as fm]
|
[app.main.ui.components.forms :as fm]
|
||||||
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
|
@ -69,8 +71,6 @@
|
||||||
;; In webkit browsers the mouseup event will be called after the on-focus causing and unselect
|
;; In webkit browsers the mouseup event will be called after the on-focus causing and unselect
|
||||||
(.addEventListener target "mouseup" dom/prevent-default #js {:once true})))))]
|
(.addEventListener target "mouseup" dom/prevent-default #js {:once true})))))]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
nil
|
nil
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -90,9 +90,13 @@
|
||||||
|
|
||||||
(mf/defc reply-form
|
(mf/defc reply-form
|
||||||
[{:keys [thread] :as props}]
|
[{:keys [thread] :as props}]
|
||||||
(let [show-buttons? (mf/use-state false)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
show-buttons? (mf/use-state false)
|
||||||
content (mf/use-state "")
|
content (mf/use-state "")
|
||||||
|
|
||||||
|
disabled? (or (fm/all-spaces? @content)
|
||||||
|
(str/empty-or-nil? @content))
|
||||||
|
|
||||||
on-focus
|
on-focus
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
#(reset! show-buttons? true))
|
#(reset! show-buttons? true))
|
||||||
|
@ -116,29 +120,52 @@
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dcm/add-comment thread @content))
|
(st/emit! (dcm/add-comment thread @content))
|
||||||
(on-cancel)))]
|
(on-cancel)))]
|
||||||
|
(if new-css-system
|
||||||
|
[:div {:class (stl/css :reply-form)}
|
||||||
|
[:& resizing-textarea {:value @content
|
||||||
|
:placeholder "Reply"
|
||||||
|
:on-blur on-blur
|
||||||
|
:on-focus on-focus
|
||||||
|
:select-on-focus? false
|
||||||
|
:on-change on-change}]
|
||||||
|
(when (or @show-buttons? (seq @content))
|
||||||
|
[:div {:class (stl/css :buttons-wrapper)}
|
||||||
|
[:input.btn-secondary
|
||||||
|
{:type "button"
|
||||||
|
:class (stl/css :cancel-btn)
|
||||||
|
:value "Cancel"
|
||||||
|
:on-click on-cancel}]
|
||||||
|
[:input
|
||||||
|
{:type "button"
|
||||||
|
:class (stl/css-case :post-btn true
|
||||||
|
:global/disabled disabled?)
|
||||||
|
:value "Post"
|
||||||
|
:on-click on-submit
|
||||||
|
:disabled disabled?}]])]
|
||||||
|
|
||||||
[:div.reply-form
|
|
||||||
[:& resizing-textarea {:value @content
|
[:div.reply-form
|
||||||
:placeholder "Reply"
|
[:& resizing-textarea {:value @content
|
||||||
:on-blur on-blur
|
:placeholder "Reply"
|
||||||
:on-focus on-focus
|
:on-blur on-blur
|
||||||
:on-change on-change}]
|
:on-focus on-focus
|
||||||
(when (or @show-buttons? (seq @content))
|
:on-change on-change}]
|
||||||
[:div.buttons
|
(when (or @show-buttons? (seq @content))
|
||||||
[:input.btn-primary
|
[:div.buttons
|
||||||
{:type "button"
|
[:input.btn-primary
|
||||||
:value "Post"
|
{:type "button"
|
||||||
:on-click on-submit
|
:value "Post"
|
||||||
:disabled (or (fm/all-spaces? @content)
|
:on-click on-submit
|
||||||
(str/empty-or-nil? @content))}]
|
:disabled disabled?}]
|
||||||
[:input.btn-secondary
|
[:input.btn-secondary
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:value "Cancel"
|
:value "Cancel"
|
||||||
:on-click on-cancel}]])]))
|
:on-click on-cancel}]])])))
|
||||||
|
|
||||||
(mf/defc draft-thread
|
(mf/defc draft-thread
|
||||||
[{:keys [draft zoom on-cancel on-submit position-modifier]}]
|
[{:keys [draft zoom on-cancel on-submit position-modifier]}]
|
||||||
(let [position (cond-> (:position draft)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
position (cond-> (:position draft)
|
||||||
(some? position-modifier)
|
(some? position-modifier)
|
||||||
(gpt/transform position-modifier))
|
(gpt/transform position-modifier))
|
||||||
content (:content draft)
|
content (:content draft)
|
||||||
|
@ -146,6 +173,9 @@
|
||||||
pos-x (* (:x position) zoom)
|
pos-x (* (:x position) zoom)
|
||||||
pos-y (* (:y position) zoom)
|
pos-y (* (:y position) zoom)
|
||||||
|
|
||||||
|
disabled? (or (fm/all-spaces? content)
|
||||||
|
(str/empty-or-nil? content))
|
||||||
|
|
||||||
on-esc
|
on-esc
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps draft)
|
(mf/deps draft)
|
||||||
|
@ -165,38 +195,70 @@
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps draft)
|
(mf/deps draft)
|
||||||
(partial on-submit draft))]
|
(partial on-submit draft))]
|
||||||
|
(if new-css-system
|
||||||
|
[:*
|
||||||
|
[:div
|
||||||
|
{:class (stl/css :floating-thread-bubble)
|
||||||
|
:style {:top (str pos-y "px")
|
||||||
|
:left (str pos-x "px")}
|
||||||
|
:on-click dom/stop-propagation}
|
||||||
|
"?"]
|
||||||
|
[:div {:class (stl/css :thread-content)
|
||||||
|
:style {:top (str (- pos-y 24) "px")
|
||||||
|
:left (str (+ pos-x 28) "px")}
|
||||||
|
:on-click dom/stop-propagation}
|
||||||
|
[:div {:class (stl/css :reply-form)}
|
||||||
|
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
||||||
|
:value (or content "")
|
||||||
|
:autofocus true
|
||||||
|
:select-on-focus? false
|
||||||
|
:on-esc on-esc
|
||||||
|
:on-change on-change}]
|
||||||
|
[:div {:class (stl/css :buttons-wrapper)}
|
||||||
|
|
||||||
[:*
|
[:input {:on-click on-esc
|
||||||
[:div.thread-bubble
|
:class (stl/css :cancel-btn)
|
||||||
{:style {:top (str pos-y "px")
|
:type "button"
|
||||||
:left (str pos-x "px")}
|
:value "Cancel"}]
|
||||||
:on-click dom/stop-propagation}
|
|
||||||
[:span "?"]]
|
[:input {:on-click on-submit
|
||||||
[:div.thread-content
|
:type "button"
|
||||||
{:style {:top (str (- pos-y 14) "px")
|
:value "Post"
|
||||||
:left (str (+ pos-x 14) "px")}
|
:class (stl/css-case :post-btn true
|
||||||
:on-click dom/stop-propagation}
|
:global/disabled disabled?)
|
||||||
[:div.reply-form
|
:disabled disabled?}]]]]]
|
||||||
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
|
||||||
:value (or content "")
|
[:*
|
||||||
:autofocus true
|
[:div.thread-bubble
|
||||||
:on-esc on-esc
|
{:style {:top (str pos-y "px")
|
||||||
:on-change on-change}]
|
:left (str pos-x "px")}
|
||||||
[:div.buttons
|
:on-click dom/stop-propagation}
|
||||||
[:input.btn-primary
|
[:span "?"]]
|
||||||
{:on-click on-submit
|
[:div.thread-content
|
||||||
:type "button"
|
{:style {:top (str (- pos-y 14) "px")
|
||||||
:value "Post"
|
:left (str (+ pos-x 14) "px")}
|
||||||
:disabled (or (fm/all-spaces? content)
|
:on-click dom/stop-propagation}
|
||||||
(str/empty-or-nil? content))}]
|
[:div.reply-form
|
||||||
[:input.btn-secondary
|
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
||||||
{:on-click on-esc
|
:value (or content "")
|
||||||
:type "button"
|
:autofocus true
|
||||||
:value "Cancel"}]]]]]))
|
:on-esc on-esc
|
||||||
|
:on-change on-change}]
|
||||||
|
[:div.buttons
|
||||||
|
[:input.btn-primary
|
||||||
|
{:on-click on-submit
|
||||||
|
:type "button"
|
||||||
|
:value "Post"
|
||||||
|
:disabled disabled?}]
|
||||||
|
[:input.btn-secondary
|
||||||
|
{:on-click on-esc
|
||||||
|
:type "button"
|
||||||
|
:value "Cancel"}]]]]])))
|
||||||
|
|
||||||
(mf/defc edit-form
|
(mf/defc edit-form
|
||||||
[{:keys [content on-submit on-cancel] :as props}]
|
[{:keys [content on-submit on-cancel] :as props}]
|
||||||
(let [content (mf/use-state content)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
content (mf/use-state content)
|
||||||
|
|
||||||
on-change
|
on-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -205,34 +267,56 @@
|
||||||
on-submit*
|
on-submit*
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps @content)
|
(mf/deps @content)
|
||||||
(fn [] (on-submit @content)))]
|
(fn [] (on-submit @content)))
|
||||||
|
|
||||||
|
disabled? (or (fm/all-spaces? @content)
|
||||||
|
(str/empty-or-nil? @content))]
|
||||||
|
|
||||||
|
(if new-css-system
|
||||||
|
[:div {:class (stl/css :edit-form)}
|
||||||
|
[:& resizing-textarea {:value @content
|
||||||
|
:autofocus true
|
||||||
|
:select-on-focus true
|
||||||
|
:select-on-focus? false
|
||||||
|
:on-change on-change}]
|
||||||
|
[:div {:class (stl/css :buttons-wrapper)}
|
||||||
|
[:input {:type "button"
|
||||||
|
:value "Cancel"
|
||||||
|
:class (stl/css :cancel-btn)
|
||||||
|
:on-click on-cancel}]
|
||||||
|
[:input {:type "button"
|
||||||
|
:class (stl/css-case :post-btn true
|
||||||
|
:global/disabled disabled?)
|
||||||
|
:value "Post"
|
||||||
|
:on-click on-submit*
|
||||||
|
:disabled disabled?}]]]
|
||||||
|
|
||||||
|
|
||||||
[:div.reply-form.edit-form
|
[:div.reply-form.edit-form
|
||||||
[:& resizing-textarea {:value @content
|
[:& resizing-textarea {:value @content
|
||||||
:autofocus true
|
:autofocus true
|
||||||
:select-on-focus true
|
:select-on-focus true
|
||||||
:on-change on-change}]
|
:on-change on-change}]
|
||||||
[:div.buttons
|
[:div.buttons
|
||||||
[:input.btn-primary {:type "button"
|
[:input.btn-primary {:type "button"
|
||||||
:value "Post"
|
:value "Post"
|
||||||
:on-click on-submit*
|
:on-click on-submit*
|
||||||
:disabled (or (fm/all-spaces? @content)
|
:disabled disabled?}]
|
||||||
(str/empty-or-nil? @content))}]
|
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]])))
|
||||||
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]]))
|
|
||||||
|
|
||||||
(mf/defc comment-item
|
(mf/defc comment-item
|
||||||
[{:keys [comment thread users origin] :as props}]
|
[{:keys [comment thread users origin] :as props}]
|
||||||
(let [owner (get users (:owner-id comment))
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
owner (get users (:owner-id comment))
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
options (mf/use-state false)
|
options (mf/use-state false)
|
||||||
edition? (mf/use-state false)
|
edition? (mf/use-state false)
|
||||||
|
|
||||||
on-show-options
|
on-toggle-options
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(reset! options true)))
|
(swap! options not)))
|
||||||
|
|
||||||
on-hide-options
|
on-hide-options
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -264,11 +348,11 @@
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps thread)
|
(mf/deps thread)
|
||||||
#(st/emit! (modal/show
|
#(st/emit! (modal/show
|
||||||
{:type :confirm
|
{:type :confirm
|
||||||
:title (tr "modals.delete-comment-thread.title")
|
:title (tr "modals.delete-comment-thread.title")
|
||||||
:message (tr "modals.delete-comment-thread.message")
|
:message (tr "modals.delete-comment-thread.message")
|
||||||
:accept-label (tr "modals.delete-comment-thread.accept")
|
:accept-label (tr "modals.delete-comment-thread.accept")
|
||||||
:on-accept delete-thread})))
|
:on-accept delete-thread})))
|
||||||
|
|
||||||
on-submit
|
on-submit
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -287,39 +371,82 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dcm/update-comment-thread (update thread :is-resolved not)))))]
|
(st/emit! (dcm/update-comment-thread (update thread :is-resolved not)))))]
|
||||||
|
|
||||||
[:div.comment-container
|
(if new-css-system
|
||||||
[:div.comment
|
[:div {:class (stl/css :comment-container)}
|
||||||
[:div.author
|
[:div {:class (stl/css :comment)}
|
||||||
[:div.avatar
|
[:div {:class (stl/css :author)}
|
||||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
[:div {:class (stl/css :avatar)}
|
||||||
[:div.name
|
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||||
[:div.fullname (:fullname owner)]
|
[:div {:class (stl/css :name)}
|
||||||
[:div.timeago (dt/timeago (:modified-at comment))]]
|
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||||
|
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at comment))]]
|
||||||
|
|
||||||
(when (some? thread)
|
(when (some? thread)
|
||||||
[:div.options-resolve {:on-click toggle-resolved}
|
[:div {:class (stl/css :options-resolve-wrapper)
|
||||||
(if (:is-resolved thread)
|
:on-click toggle-resolved}
|
||||||
[:span i/checkbox-checked]
|
[:span {:class (stl/css-case :options-resolve true
|
||||||
[:span i/checkbox-unchecked])])
|
:global/checked (:is-resolved thread))} i/tick-refactor]])
|
||||||
|
|
||||||
(when (= (:id profile) (:id owner))
|
(when (= (:id profile) (:id owner))
|
||||||
[:div.options
|
[:div {:class (stl/css :options)
|
||||||
[:div.options-icon {:on-click on-show-options} i/actions]])]
|
:on-click on-toggle-options}
|
||||||
|
i/menu-refactor])]
|
||||||
|
|
||||||
[:div.content
|
[:div {:class (stl/css :content)}
|
||||||
(if @edition?
|
(if @edition?
|
||||||
[:& edit-form {:content (:content comment)
|
[:& edit-form {:content (:content comment)
|
||||||
:on-submit on-submit
|
:on-submit on-submit
|
||||||
:on-cancel on-cancel}]
|
:on-cancel on-cancel}]
|
||||||
[:span.text (:content comment)])]]
|
[:span {:class (stl/css :text)} (:content comment)])]]
|
||||||
|
|
||||||
[:& dropdown {:show @options
|
[:& dropdown {:show @options
|
||||||
:on-close on-hide-options}
|
:on-close on-hide-options}
|
||||||
[:ul.dropdown.comment-options-dropdown
|
[:ul {:class (stl/css :comment-options-dropdown)}
|
||||||
[:li {:on-click on-edit-clicked} (tr "labels.edit")]
|
[:li {:class (stl/css :context-menu-option)
|
||||||
(if thread
|
:on-click on-edit-clicked}
|
||||||
[:li {:on-click on-delete-thread} (tr "labels.delete-comment-thread")]
|
(tr "labels.edit")]
|
||||||
[:li {:on-click on-delete-comment} (tr "labels.delete-comment")])]]]))
|
(if thread
|
||||||
|
[:li {:class (stl/css :context-menu-option)
|
||||||
|
:on-click on-delete-thread}
|
||||||
|
(tr "labels.delete-comment-thread")]
|
||||||
|
[:li {:class (stl/css :context-menu-option)
|
||||||
|
:on-click on-delete-comment}
|
||||||
|
(tr "labels.delete-comment")])]]]
|
||||||
|
|
||||||
|
|
||||||
|
[:div.comment-container
|
||||||
|
[:div.comment
|
||||||
|
[:div.author
|
||||||
|
[:div.avatar
|
||||||
|
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||||
|
[:div.name
|
||||||
|
[:div.fullname (:fullname owner)]
|
||||||
|
[:div.timeago (dt/timeago (:modified-at comment))]]
|
||||||
|
|
||||||
|
(when (some? thread)
|
||||||
|
[:div.options-resolve {:on-click toggle-resolved}
|
||||||
|
(if (:is-resolved thread)
|
||||||
|
[:span i/checkbox-checked]
|
||||||
|
[:span i/checkbox-unchecked])])
|
||||||
|
|
||||||
|
(when (= (:id profile) (:id owner))
|
||||||
|
[:div.options
|
||||||
|
[:div.options-icon {:on-click on-toggle-options} i/actions]])]
|
||||||
|
|
||||||
|
[:div.content
|
||||||
|
(if @edition?
|
||||||
|
[:& edit-form {:content (:content comment)
|
||||||
|
:on-submit on-submit
|
||||||
|
:on-cancel on-cancel}]
|
||||||
|
[:span.text (:content comment)])]]
|
||||||
|
|
||||||
|
[:& dropdown {:show @options
|
||||||
|
:on-close on-hide-options}
|
||||||
|
[:ul.dropdown.comment-options-dropdown
|
||||||
|
[:li {:on-click on-edit-clicked} (tr "labels.edit")]
|
||||||
|
(if thread
|
||||||
|
[:li {:on-click on-delete-thread} (tr "labels.delete-comment-thread")]
|
||||||
|
[:li {:on-click on-delete-comment} (tr "labels.delete-comment")])]]])))
|
||||||
|
|
||||||
(defn make-comments-ref
|
(defn make-comments-ref
|
||||||
[thread-id]
|
[thread-id]
|
||||||
|
@ -328,7 +455,8 @@
|
||||||
(mf/defc thread-comments
|
(mf/defc thread-comments
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [thread zoom users origin position-modifier]}]
|
[{:keys [thread zoom users origin position-modifier]}]
|
||||||
(let [ref (mf/use-ref)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
ref (mf/use-ref)
|
||||||
|
|
||||||
|
|
||||||
thread-id (:id thread)
|
thread-id (:id thread)
|
||||||
|
@ -338,8 +466,13 @@
|
||||||
(some? position-modifier)
|
(some? position-modifier)
|
||||||
(gpt/transform position-modifier))
|
(gpt/transform position-modifier))
|
||||||
|
|
||||||
pos-x (+ (* (:x pos) zoom) 14)
|
pos-x (if new-css-system
|
||||||
pos-y (- (* (:y pos) zoom) 14)
|
(+ (* (:x pos) zoom) 24)
|
||||||
|
(+ (* (:x pos) zoom) 14))
|
||||||
|
pos-y (if new-css-system
|
||||||
|
(- (* (:y pos) zoom) 28)
|
||||||
|
(- (* (:y pos) zoom) 14))
|
||||||
|
|
||||||
|
|
||||||
comments-ref (mf/with-memo [thread-id]
|
comments-ref (mf/with-memo [thread-id]
|
||||||
(make-comments-ref thread-id))
|
(make-comments-ref thread-id))
|
||||||
|
@ -360,26 +493,46 @@
|
||||||
(mf/with-layout-effect [thread-pos comments-map]
|
(mf/with-layout-effect [thread-pos comments-map]
|
||||||
(when-let [node (mf/ref-val ref)]
|
(when-let [node (mf/ref-val ref)]
|
||||||
(dom/scroll-into-view-if-needed! node)))
|
(dom/scroll-into-view-if-needed! node)))
|
||||||
|
(if new-css-system
|
||||||
|
(when (some? comment)
|
||||||
|
[:div {:class (stl/css :thread-content)
|
||||||
|
:style {:top (str pos-y "px")
|
||||||
|
:left (str pos-x "px")}
|
||||||
|
:on-click dom/stop-propagation}
|
||||||
|
|
||||||
(when (some? comment)
|
[:div {:class (stl/css :comments)}
|
||||||
[:div.thread-content
|
[:& comment-item {:comment comment
|
||||||
{:style {:top (str pos-y "px")
|
:users users
|
||||||
:left (str pos-x "px")}
|
:thread thread
|
||||||
:on-click dom/stop-propagation}
|
:origin origin}]
|
||||||
|
(for [item (rest comments)]
|
||||||
|
[:* {:key (dm/str (:id item))}
|
||||||
|
[:& comment-item {:comment item
|
||||||
|
:users users
|
||||||
|
:origin origin}]])
|
||||||
|
[:div {:ref ref}]]
|
||||||
|
[:& reply-form {:thread thread}]])
|
||||||
|
|
||||||
[:div.comments
|
|
||||||
[:& comment-item {:comment comment
|
(when (some? comment)
|
||||||
:users users
|
[:div.thread-content
|
||||||
:thread thread
|
{:style {:top (str pos-y "px")
|
||||||
:origin origin}]
|
:left (str pos-x "px")}
|
||||||
(for [item (rest comments)]
|
:on-click dom/stop-propagation}
|
||||||
[:* {:key (dm/str (:id item))}
|
|
||||||
[:hr]
|
[:div.comments
|
||||||
[:& comment-item {:comment item
|
[:& comment-item {:comment comment
|
||||||
:users users
|
:users users
|
||||||
:origin origin}]])
|
:thread thread
|
||||||
[:div {:ref ref}]]
|
:origin origin}]
|
||||||
[:& reply-form {:thread thread}]])))
|
(for [item (rest comments)]
|
||||||
|
[:* {:key (dm/str (:id item))}
|
||||||
|
[:hr]
|
||||||
|
[:& comment-item {:comment item
|
||||||
|
:users users
|
||||||
|
:origin origin}]])
|
||||||
|
[:div {:ref ref}]]
|
||||||
|
[:& reply-form {:thread thread}]]))))
|
||||||
|
|
||||||
(defn use-buble
|
(defn use-buble
|
||||||
[zoom {:keys [position frame-id]}]
|
[zoom {:keys [position frame-id]}]
|
||||||
|
@ -438,7 +591,8 @@
|
||||||
(mf/defc thread-bubble
|
(mf/defc thread-bubble
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [thread zoom open? on-click origin position-modifier]}]
|
[{:keys [thread zoom open? on-click origin position-modifier]}]
|
||||||
(let [pos (cond-> (:position thread)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
pos (cond-> (:position thread)
|
||||||
(some? position-modifier)
|
(some? position-modifier)
|
||||||
(gpt/transform position-modifier))
|
(gpt/transform position-modifier))
|
||||||
|
|
||||||
|
@ -493,23 +647,37 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when (= origin :viewer)
|
(when (= origin :viewer)
|
||||||
(on-click thread))))]
|
(on-click thread))))]
|
||||||
|
(if new-css-system
|
||||||
|
[:div {:style {:top (str pos-y "px")
|
||||||
|
:left (str pos-x "px")}
|
||||||
|
:on-pointer-down on-pointer-down*
|
||||||
|
:on-pointer-up on-pointer-up*
|
||||||
|
:on-pointer-move on-pointer-move*
|
||||||
|
:on-click on-click*
|
||||||
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
|
:class (stl/css-case
|
||||||
|
:floating-thread-bubble true
|
||||||
|
:resolved (:is-resolved thread)
|
||||||
|
:unread (pos? (:count-unread-comments thread)))}
|
||||||
|
[:span (:seqn thread)]]
|
||||||
|
|
||||||
[:div.thread-bubble
|
[:div.thread-bubble
|
||||||
{:style {:top (str pos-y "px")
|
{:style {:top (str pos-y "px")
|
||||||
:left (str pos-x "px")}
|
:left (str pos-x "px")}
|
||||||
:on-pointer-down on-pointer-down*
|
:on-pointer-down on-pointer-down*
|
||||||
:on-pointer-up on-pointer-up*
|
:on-pointer-up on-pointer-up*
|
||||||
:on-pointer-move on-pointer-move*
|
:on-pointer-move on-pointer-move*
|
||||||
:on-click on-click*
|
:on-click on-click*
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:class (dom/classnames
|
:class (dom/classnames
|
||||||
:resolved (:is-resolved thread)
|
:resolved (:is-resolved thread)
|
||||||
:unread (pos? (:count-unread-comments thread)))}
|
:unread (pos? (:count-unread-comments thread)))}
|
||||||
[:span (:seqn thread)]]))
|
[:span (:seqn thread)]])))
|
||||||
|
|
||||||
(mf/defc comment-thread
|
(mf/defc comment-thread
|
||||||
[{:keys [item users on-click]}]
|
[{:keys [item users on-click]}]
|
||||||
(let [owner (get users (:owner-id item))
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
owner (get users (:owner-id item))
|
||||||
on-click*
|
on-click*
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps item)
|
(mf/deps item)
|
||||||
|
@ -519,48 +687,99 @@
|
||||||
(when (fn? on-click)
|
(when (fn? on-click)
|
||||||
(on-click item))))]
|
(on-click item))))]
|
||||||
|
|
||||||
[:div.comment {:on-click on-click*}
|
(if new-css-system
|
||||||
[:div.author
|
[:div {:class (stl/css :comment)
|
||||||
[:div.thread-bubble
|
:on-click on-click*}
|
||||||
{:class (dom/classnames
|
[:div {:class (stl/css :author)}
|
||||||
:resolved (:is-resolved item)
|
[:div {:class (stl/css-case :thread-bubble true
|
||||||
:unread (pos? (:count-unread-comments item)))}
|
:resolved (:is-resolved item)
|
||||||
(:seqn item)]
|
:unread (pos? (:count-unread-comments item)))}
|
||||||
[:div.avatar
|
(:seqn item)]
|
||||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
[:div {:class (stl/css :avatar)}
|
||||||
[:div.name
|
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||||
[:div.fullname (:fullname owner) ", "]
|
[:div {:class (stl/css :name)}
|
||||||
[:div.timeago (dt/timeago (:modified-at item))]]]
|
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||||
[:div.content
|
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at item))]]]
|
||||||
[:span.text (:content item)]]
|
[:div {:class (stl/css :content)}
|
||||||
[:div.content.replies
|
(:content item)]
|
||||||
(let [unread (:count-unread-comments item ::none)
|
[:div {:class (stl/css :replies)}
|
||||||
total (:count-comments item 1)]
|
(let [unread (:count-unread-comments item ::none)
|
||||||
[:*
|
total (:count-comments item 1)]
|
||||||
(when (> total 1)
|
[:*
|
||||||
(if (= total 2)
|
(when (> total 1)
|
||||||
[:span.total-replies "1 reply"]
|
(if (= total 2)
|
||||||
[:span.total-replies (str (dec total) " replies")]))
|
[:span {:class (stl/css :total-replies)} "1 reply"]
|
||||||
|
[:span {:class (stl/css :total-replies)} (str (dec total) " replies")]))
|
||||||
|
|
||||||
(when (and (> total 1) (> unread 0))
|
(when (and (> total 1) (> unread 0))
|
||||||
(if (= unread 1)
|
(if (= unread 1)
|
||||||
[:span.new-replies "1 new reply"]
|
[:span {:class (stl/css :new-replies)} "1 new reply"]
|
||||||
[:span.new-replies (str unread " new replies")]))])]]))
|
[:span {:class (stl/css :new-replies)} (str unread " new replies")]))])]]
|
||||||
|
|
||||||
|
|
||||||
|
[:div.comment {:on-click on-click*}
|
||||||
|
[:div.author
|
||||||
|
[:div.thread-bubble
|
||||||
|
{:class (dom/classnames
|
||||||
|
:resolved (:is-resolved item)
|
||||||
|
:unread (pos? (:count-unread-comments item)))}
|
||||||
|
(:seqn item)]
|
||||||
|
[:div.avatar
|
||||||
|
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||||
|
[:div.name
|
||||||
|
[:div.fullname (:fullname owner) ", "]
|
||||||
|
[:div.timeago (dt/timeago (:modified-at item))]]]
|
||||||
|
[:div.content
|
||||||
|
[:span.text (:content item)]]
|
||||||
|
[:div.content.replies
|
||||||
|
(let [unread (:count-unread-comments item ::none)
|
||||||
|
total (:count-comments item 1)]
|
||||||
|
[:*
|
||||||
|
(when (> total 1)
|
||||||
|
(if (= total 2)
|
||||||
|
[:span.total-replies "1 reply"]
|
||||||
|
[:span.total-replies (str (dec total) " replies")]))
|
||||||
|
|
||||||
|
(when (and (> total 1) (> unread 0))
|
||||||
|
(if (= unread 1)
|
||||||
|
[:span.new-replies "1 new reply"]
|
||||||
|
[:span.new-replies (str unread " new replies")]))])]])))
|
||||||
|
|
||||||
(mf/defc comment-thread-group
|
(mf/defc comment-thread-group
|
||||||
[{:keys [group users on-thread-click]}]
|
[{:keys [group users on-thread-click]}]
|
||||||
[:div.thread-group
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||||
(if (:file-name group)
|
(if new-css-system
|
||||||
[:div.section-title
|
[:div {:class (stl/css :thread-group)}
|
||||||
[:span.label.filename (:file-name group) ", "]
|
(if (:file-name group)
|
||||||
[:span.label (:page-name group)]]
|
[:div {:class (stl/css :section-title)}
|
||||||
[:div.section-title
|
[:span {:class (stl/css :file-name)} (:file-name group) ", "]
|
||||||
[:span.icon i/file-html]
|
[:span {:class (stl/css :page-name)} (:page-name group)]]
|
||||||
[:span.label (:page-name group)]])
|
|
||||||
[:div.threads
|
[:div {:class (stl/css :section-title)}
|
||||||
(for [item (:items group)]
|
[:span {:class (stl/css :icon)} i/document-refactor]
|
||||||
[:& comment-thread
|
[:span {:class (stl/css :page-name)} (:page-name group)]])
|
||||||
{:item item
|
|
||||||
:on-click on-thread-click
|
[:div {:class (stl/css :threads)}
|
||||||
:users users
|
(for [item (:items group)]
|
||||||
:key (:id item)}])]])
|
[:& comment-thread
|
||||||
|
{:item item
|
||||||
|
:on-click on-thread-click
|
||||||
|
:users users
|
||||||
|
:key (:id item)}])]]
|
||||||
|
|
||||||
|
|
||||||
|
[:div.thread-group
|
||||||
|
(if (:file-name group)
|
||||||
|
[:div.section-title
|
||||||
|
[:span.label.filename (:file-name group) ", "]
|
||||||
|
[:span.label (:page-name group)]]
|
||||||
|
[:div.section-title
|
||||||
|
[:span.icon i/file-html]
|
||||||
|
[:span.label (:page-name group)]])
|
||||||
|
[:div.threads
|
||||||
|
(for [item (:items group)]
|
||||||
|
[:& comment-thread
|
||||||
|
{:item item
|
||||||
|
:on-click on-thread-click
|
||||||
|
:users users
|
||||||
|
:key (:id item)}])]])))
|
||||||
|
|
232
frontend/src/app/main/ui/comments.scss
Normal file
232
frontend/src/app/main/ui/comments.scss
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
// 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";
|
||||||
|
|
||||||
|
// Comment-thread-group
|
||||||
|
.thread-group {
|
||||||
|
padding: 0 $s-12;
|
||||||
|
.section-title {
|
||||||
|
@include titleTipography;
|
||||||
|
height: $s-32;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: $s-8;
|
||||||
|
.file-name {
|
||||||
|
color: var(--comment-subtitle-color);
|
||||||
|
}
|
||||||
|
.page-name {
|
||||||
|
color: var(--comment-subtitle-color);
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 $s-6 0 $s-4;
|
||||||
|
width: $s-24;
|
||||||
|
height: $s-32;
|
||||||
|
margin-left: $s-6;
|
||||||
|
svg {
|
||||||
|
@extend .button-icon-small;
|
||||||
|
stroke: var(--icon-foreground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.threads {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment-thread
|
||||||
|
.comment {
|
||||||
|
@include titleTipography;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-12;
|
||||||
|
.author {
|
||||||
|
display: flex;
|
||||||
|
gap: $s-8;
|
||||||
|
.thread-bubble {
|
||||||
|
@extend .comment-bubbles;
|
||||||
|
&.resolved {
|
||||||
|
@extend .resolved-comment-bubble;
|
||||||
|
}
|
||||||
|
&.unread {
|
||||||
|
@extend .unread-comment-bubble;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-32;
|
||||||
|
border-radius: $br-circle;
|
||||||
|
img {
|
||||||
|
border-radius: $br-circle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
flex-grow: 1;
|
||||||
|
.fullname {
|
||||||
|
@include textEllipsis;
|
||||||
|
color: var(--comment-title-color);
|
||||||
|
}
|
||||||
|
.timeago {
|
||||||
|
@include textEllipsis;
|
||||||
|
color: var(--comment-subtitle-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
@include titleTipography;
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
.replies {
|
||||||
|
display: flex;
|
||||||
|
gap: $s-8;
|
||||||
|
.total-replies {
|
||||||
|
color: var(--color-foreground-secondary);
|
||||||
|
}
|
||||||
|
.new-replies {
|
||||||
|
color: var(--color-accent-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thread-bubble
|
||||||
|
|
||||||
|
.floating-thread-bubble {
|
||||||
|
@extend .comment-bubbles;
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
transform: translate(calc(-1 * $s-16), calc(-1 * $s-16));
|
||||||
|
|
||||||
|
&.resolved {
|
||||||
|
@extend .resolved-comment-bubble;
|
||||||
|
}
|
||||||
|
&.unread {
|
||||||
|
@extend .unread-comment-bubble;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// thread-content
|
||||||
|
.thread-content {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: auto;
|
||||||
|
user-select: text;
|
||||||
|
width: $s-284;
|
||||||
|
padding: $s-12;
|
||||||
|
border-radius: $br-8;
|
||||||
|
background-color: var(--comment-modal-background-color);
|
||||||
|
.comments {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// comment-item
|
||||||
|
|
||||||
|
.comment-container {
|
||||||
|
position: relative;
|
||||||
|
.comment {
|
||||||
|
@include titleTipography;
|
||||||
|
.author {
|
||||||
|
display: flex;
|
||||||
|
gap: $s-8;
|
||||||
|
.avatar {
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-32;
|
||||||
|
border-radius: $br-circle;
|
||||||
|
img {
|
||||||
|
border-radius: $br-circle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
flex-grow: 1;
|
||||||
|
.fullname {
|
||||||
|
@include textEllipsis;
|
||||||
|
color: var(--comment-title-color);
|
||||||
|
}
|
||||||
|
.timeago {
|
||||||
|
@include textEllipsis;
|
||||||
|
color: var(--comment-subtitle-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.options-resolve-wrapper {
|
||||||
|
@include flexCenter;
|
||||||
|
width: $s-16;
|
||||||
|
height: $s-32;
|
||||||
|
.options-resolve {
|
||||||
|
@extend .checkbox-icon;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.options {
|
||||||
|
@extend .button-tertiary;
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-28;
|
||||||
|
svg {
|
||||||
|
@extend .button-icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
.text {
|
||||||
|
@include titleTipography;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.comment-options-dropdown {
|
||||||
|
@extend .dropdown-wrapper;
|
||||||
|
position: absolute;
|
||||||
|
width: $s-120;
|
||||||
|
right: 0;
|
||||||
|
left: unset;
|
||||||
|
.context-menu-option {
|
||||||
|
@extend .dropdown-element-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit-form & reply-form
|
||||||
|
|
||||||
|
.edit-form,
|
||||||
|
.reply-form {
|
||||||
|
textarea {
|
||||||
|
@extend .input-element;
|
||||||
|
line-height: 1.45;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
max-width: $s-260;
|
||||||
|
min-width: $s-260;
|
||||||
|
margin-bottom: $s-8;
|
||||||
|
padding: $s-8;
|
||||||
|
color: var(--input-foreground-color-active);
|
||||||
|
&:focus {
|
||||||
|
border: $s-1 solid var(--input-border-color-active);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttons-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: $s-4;
|
||||||
|
.post-btn {
|
||||||
|
@extend .button-primary;
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-92;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.cancel-btn {
|
||||||
|
@extend .button-secondary;
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-92;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,19 +44,19 @@
|
||||||
&.disabled {
|
&.disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
.title-name {
|
.title-name {
|
||||||
color: var(--button-foreground-color-disabled);
|
color: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
border: none;
|
border: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
.title-name {
|
.title-name {
|
||||||
color: var(--button-foreground-color-disabled);
|
color: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
}
|
}
|
||||||
&:disabled {
|
&:disabled {
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
&::after {
|
&::after {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.main.ui.workspace.comments
|
(ns app.main.ui.workspace.comments
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.main.data.comments :as dcm]
|
[app.main.data.comments :as dcm]
|
||||||
[app.main.data.events :as ev]
|
[app.main.data.events :as ev]
|
||||||
|
@ -27,54 +28,104 @@
|
||||||
|
|
||||||
(mf/defc sidebar-options
|
(mf/defc sidebar-options
|
||||||
[]
|
[]
|
||||||
(let [{cmode :mode cshow :show} (mf/deref refs/comments-local)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
{cmode :mode cshow :show} (mf/deref refs/comments-local)
|
||||||
update-mode
|
update-mode
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [mode]
|
(fn [event]
|
||||||
(st/emit! (dcm/update-filters {:mode mode}))))
|
(let [mode (-> (dom/get-current-target event)
|
||||||
|
(dom/get-data "value")
|
||||||
|
(keyword))]
|
||||||
|
(st/emit! (dcm/update-filters {:mode mode})))))
|
||||||
|
|
||||||
update-show
|
update-show
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [mode]
|
(mf/deps cshow)
|
||||||
(st/emit! (dcm/update-filters {:show mode}))))]
|
(fn []
|
||||||
|
(let [mode (if (= :pending cshow) :all :pending)]
|
||||||
|
(st/emit! (dcm/update-filters {:show mode})))))]
|
||||||
|
|
||||||
[:ul.dropdown.with-check
|
(if new-css-system
|
||||||
[:li {:class (dom/classnames :selected (or (= :all cmode) (nil? cmode)))
|
[:ul {:class (stl/css :comment-mode-dropdown)}
|
||||||
:on-click #(update-mode :all)}
|
[:li {:class (stl/css-case :dropdown-item true
|
||||||
[:span.icon i/tick]
|
:selected (or (= :all cmode) (nil? cmode)))
|
||||||
[:span.label (tr "labels.show-all-comments")]]
|
:data-value "all"
|
||||||
|
:on-click update-mode}
|
||||||
|
|
||||||
[:li {:class (dom/classnames :selected (= :yours cmode))
|
[:span {:class (stl/css :label)} (tr "labels.show-all-comments")]
|
||||||
:on-click #(update-mode :yours)}
|
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||||
[:span.icon i/tick]
|
[:li {:class (stl/css-case :dropdown-item true
|
||||||
[:span.label (tr "labels.show-your-comments")]]
|
:selected (= :yours cmode))
|
||||||
|
:data-value "yours"
|
||||||
|
:on-click update-mode}
|
||||||
|
[:span {:class (stl/css :label)} (tr "labels.show-your-comments")]
|
||||||
|
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||||
|
[:li {:class (stl/css :separator)}]
|
||||||
|
[:li {:class (stl/css-case :dropdown-item true
|
||||||
|
:selected (= :pending cshow))
|
||||||
|
:on-click update-show}
|
||||||
|
[:span {:class (stl/css :label)} (tr "labels.hide-resolved-comments")]
|
||||||
|
[:span {:class (stl/css :icon)} i/tick-refactor]]]
|
||||||
|
|
||||||
[:hr]
|
|
||||||
|
|
||||||
[:li {:class (dom/classnames :selected (= :pending cshow))
|
[:ul.dropdown.with-check
|
||||||
:on-click #(update-show (if (= :pending cshow) :all :pending))}
|
[:li {:class (dom/classnames :selected (or (= :all cmode) (nil? cmode)))
|
||||||
[:span.icon i/tick]
|
:data-value "all"
|
||||||
[:span.label (tr "labels.hide-resolved-comments")]]]))
|
:on-click update-mode}
|
||||||
|
[:span.icon i/tick]
|
||||||
|
[:span.label (tr "labels.show-all-comments")]]
|
||||||
|
|
||||||
|
[:li {:class (dom/classnames :selected (= :yours cmode))
|
||||||
|
:data-value "yours"
|
||||||
|
:on-click update-mode}
|
||||||
|
[:span.icon i/tick]
|
||||||
|
[:span.label (tr "labels.show-your-comments")]]
|
||||||
|
|
||||||
|
[:hr]
|
||||||
|
|
||||||
|
[:li {:class (dom/classnames :selected (= :pending cshow))
|
||||||
|
:on-click update-show}
|
||||||
|
[:span.icon i/tick]
|
||||||
|
[:span.label (tr "labels.hide-resolved-comments")]]])
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
(mf/defc comments-sidebar
|
(mf/defc comments-sidebar
|
||||||
[{:keys [users threads page-id]}]
|
[{:keys [users threads page-id]}]
|
||||||
(let [threads-map (mf/deref refs/threads-ref)
|
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||||
|
threads-map (mf/deref refs/threads-ref)
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
users-refs (mf/deref refs/current-file-comments-users)
|
users-refs (mf/deref refs/current-file-comments-users)
|
||||||
users (or users users-refs)
|
users (or users users-refs)
|
||||||
local (mf/deref refs/comments-local)
|
local (mf/deref refs/comments-local)
|
||||||
options? (mf/use-state false)
|
|
||||||
|
state* (mf/use-state false)
|
||||||
|
options? (deref state*)
|
||||||
|
|
||||||
threads (if (nil? threads)
|
threads (if (nil? threads)
|
||||||
(->> (vals threads-map)
|
(->> (vals threads-map)
|
||||||
(sort-by :modified-at)
|
(sort-by :modified-at)
|
||||||
(reverse)
|
(reverse)
|
||||||
(dcm/apply-filters local profile))
|
(dcm/apply-filters local profile))
|
||||||
threads)
|
threads)
|
||||||
tgroups (->> threads
|
|
||||||
(dcm/group-threads-by-page))
|
close-section
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps)
|
||||||
|
#(st/emit! :interrupt (dw/deselect-all true)))
|
||||||
|
|
||||||
|
tgroups (->> threads
|
||||||
|
(dcm/group-threads-by-page))
|
||||||
|
|
||||||
page-id (or page-id (mf/use-ctx ctx/current-page-id))
|
page-id (or page-id (mf/use-ctx ctx/current-page-id))
|
||||||
|
|
||||||
|
toggle-mode-selector
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps)
|
||||||
|
(fn [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(swap! state* not)))
|
||||||
|
|
||||||
on-thread-click
|
on-thread-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps page-id)
|
(mf/deps page-id)
|
||||||
|
@ -88,38 +139,76 @@
|
||||||
(dwcm/center-to-comment-thread thread)
|
(dwcm/center-to-comment-thread thread)
|
||||||
(-> (dcm/open-thread thread)
|
(-> (dcm/open-thread thread)
|
||||||
(with-meta {::ev/origin "workspace"})))))))]
|
(with-meta {::ev/origin "workspace"})))))))]
|
||||||
|
(if new-css-system
|
||||||
|
[:div {:class (stl/css :comments-section)}
|
||||||
|
[:div {:class (stl/css :comments-section-title)}
|
||||||
|
[:span (tr "labels.comments")]
|
||||||
|
[:button {:class (stl/css :close-button)
|
||||||
|
:on-click close-section}
|
||||||
|
i/close-refactor]]
|
||||||
|
|
||||||
[:div.comments-section.comment-threads-section
|
(when (seq tgroups)
|
||||||
[:div.workspace-comment-threads-sidebar-header
|
[:button {:class (stl/css :mode-dropdown-wrapper)
|
||||||
[:div.label (tr "labels.comments")]
|
:on-click toggle-mode-selector}
|
||||||
[:div.options {:on-click
|
|
||||||
(fn [event]
|
|
||||||
(dom/stop-propagation event)
|
|
||||||
(reset! options? true))}
|
|
||||||
[:div.label (case (:mode local)
|
|
||||||
(nil :all) (tr "labels.all")
|
|
||||||
:yours (tr "labels.only-yours"))]
|
|
||||||
[:div.icon i/arrow-down]]
|
|
||||||
|
|
||||||
[:& dropdown {:show @options?
|
[:span {:class (stl/css :mode-label)} (case (:mode local)
|
||||||
:on-close #(reset! options? false)}
|
(nil :all) (tr "labels.show-all-comments")
|
||||||
[:& sidebar-options {:local local}]]]
|
:yours (tr "labels.show-your-comments"))]
|
||||||
|
[:div {:class (stl/css :icon)} i/arrow-refactor]]
|
||||||
|
|
||||||
(if (seq tgroups)
|
[:& dropdown {:show options?
|
||||||
[:div.thread-groups
|
:on-close #(reset! state* false)}
|
||||||
[:& cmt/comment-thread-group
|
[:& sidebar-options {:local local}]])
|
||||||
{:group (first tgroups)
|
|
||||||
:on-thread-click on-thread-click
|
[:div {:class (stl/css :comments-section-content)}
|
||||||
:users users}]
|
|
||||||
(for [tgroup (rest tgroups)]
|
(if (seq tgroups)
|
||||||
[:*
|
[:div {:class (stl/css :thread-groups)}
|
||||||
[:hr]
|
|
||||||
[:& cmt/comment-thread-group
|
[:& cmt/comment-thread-group
|
||||||
{:group tgroup
|
{:group (first tgroups)
|
||||||
:on-thread-click on-thread-click
|
:on-thread-click on-thread-click
|
||||||
:users users
|
:users users}]
|
||||||
:key (:page-id tgroup)}]])]
|
(for [tgroup (rest tgroups)]
|
||||||
|
[:& cmt/comment-thread-group
|
||||||
|
{:group tgroup
|
||||||
|
:on-thread-click on-thread-click
|
||||||
|
:users users
|
||||||
|
:key (:page-id tgroup)}])]
|
||||||
|
|
||||||
[:div.thread-groups-placeholder
|
[:div {:class (stl/css :thread-group-placeholder)}
|
||||||
i/chat
|
[:span {:class (stl/css :placeholder-icon)} i/comments-refactor]
|
||||||
(tr "labels.no-comments-available")])]))
|
[:span {:class (stl/css :placeholder-label)}
|
||||||
|
(tr "labels.no-comments-available")]])]]
|
||||||
|
|
||||||
|
|
||||||
|
[:div.comments-section.comment-threads-section
|
||||||
|
[:div.workspace-comment-threads-sidebar-header
|
||||||
|
[:div.label (tr "labels.comments")]
|
||||||
|
[:div.options {:on-click toggle-mode-selector}
|
||||||
|
[:div.label (case (:mode local)
|
||||||
|
(nil :all) (tr "labels.all")
|
||||||
|
:yours (tr "labels.only-yours"))]
|
||||||
|
[:div.icon i/arrow-down]]
|
||||||
|
|
||||||
|
[:& dropdown {:show options?
|
||||||
|
:on-close #(reset! state* false)}
|
||||||
|
[:& sidebar-options {:local local}]]]
|
||||||
|
|
||||||
|
(if (seq tgroups)
|
||||||
|
[:div.thread-groups
|
||||||
|
[:& cmt/comment-thread-group
|
||||||
|
{:group (first tgroups)
|
||||||
|
:on-thread-click on-thread-click
|
||||||
|
:users users}]
|
||||||
|
(for [tgroup (rest tgroups)]
|
||||||
|
[:*
|
||||||
|
[:hr]
|
||||||
|
[:& cmt/comment-thread-group
|
||||||
|
{:group tgroup
|
||||||
|
:on-thread-click on-thread-click
|
||||||
|
:users users
|
||||||
|
:key (:page-id tgroup)}]])]
|
||||||
|
|
||||||
|
[:div.thread-groups-placeholder
|
||||||
|
i/chat
|
||||||
|
(tr "labels.no-comments-available")])])))
|
||||||
|
|
141
frontend/src/app/main/ui/workspace/comments.scss
Normal file
141
frontend/src/app/main/ui/workspace/comments.scss
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// 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";
|
||||||
|
|
||||||
|
.comments-section {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--panel-background-color);
|
||||||
|
.comments-section-title {
|
||||||
|
@include flexCenter;
|
||||||
|
@include tabTitleTipography;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: $s-32;
|
||||||
|
min-height: $s-32;
|
||||||
|
margin: $s-8 $s-8 0 $s-8;
|
||||||
|
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;
|
||||||
|
height: $s-28;
|
||||||
|
width: $s-28;
|
||||||
|
border-radius: $br-6;
|
||||||
|
svg {
|
||||||
|
@extend .button-icon;
|
||||||
|
stroke: var(--icon-foreground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mode-dropdown-wrapper {
|
||||||
|
@include buttonStyle;
|
||||||
|
@extend .asset-element;
|
||||||
|
background-color: var(--color-background-tertiary);
|
||||||
|
display: flex;
|
||||||
|
width: $s-256;
|
||||||
|
height: $s-32;
|
||||||
|
padding: $s-8;
|
||||||
|
border-radius: $br-8;
|
||||||
|
margin: $s-16 auto 0 auto;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
.mode-label {
|
||||||
|
padding-right: 8px;
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
@include flexCenter;
|
||||||
|
padding-right: 8px;
|
||||||
|
height: $s-24;
|
||||||
|
width: $s-24;
|
||||||
|
svg {
|
||||||
|
@extend .button-icon-small;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
stroke: var(--icon-foreground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.comment-mode-dropdown {
|
||||||
|
@extend .dropdown-wrapper;
|
||||||
|
top: $s-80;
|
||||||
|
left: $s-12;
|
||||||
|
width: $s-256;
|
||||||
|
.dropdown-item {
|
||||||
|
@extend .dropdown-element-base;
|
||||||
|
justify-content: space-between;
|
||||||
|
.icon {
|
||||||
|
@include flexCenter;
|
||||||
|
height: $s-24;
|
||||||
|
width: $s-24;
|
||||||
|
svg {
|
||||||
|
@extend .button-icon-small;
|
||||||
|
stroke: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
@include titleTipography;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.icon svg {
|
||||||
|
stroke: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
.label {
|
||||||
|
color: var(--menu-foreground-color);
|
||||||
|
}
|
||||||
|
.icon svg {
|
||||||
|
stroke: var(--icon-foreground-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.separator {
|
||||||
|
height: $s-12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.comments-section-content {
|
||||||
|
.thread-groups {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-24;
|
||||||
|
}
|
||||||
|
.thread-group-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: $s-4;
|
||||||
|
margin-top: $s-36;
|
||||||
|
.placeholder-icon {
|
||||||
|
@include flexCenter;
|
||||||
|
height: $s-48;
|
||||||
|
width: $s-48;
|
||||||
|
border-radius: $br-circle;
|
||||||
|
background-color: var(--empty-message-background-color);
|
||||||
|
svg {
|
||||||
|
@extend .button-icon;
|
||||||
|
height: $s-28;
|
||||||
|
width: $s-28;
|
||||||
|
stroke: var(--empty-message-foreground-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.placeholder-label {
|
||||||
|
@include titleTipography;
|
||||||
|
text-align: center;
|
||||||
|
width: $s-184;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
height: $s-32;
|
height: $s-32;
|
||||||
min-height: $s-32;
|
min-height: $s-32;
|
||||||
margin: $s-4 $s-4 0 $s-4;
|
margin: $s-8 $s-8 0 $s-8;
|
||||||
border-radius: $br-8;
|
border-radius: $br-8;
|
||||||
background-color: var(--panel-title-background-color);
|
background-color: var(--panel-title-background-color);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
@include flexCenter;
|
@include flexCenter;
|
||||||
height: $s-48;
|
height: $s-48;
|
||||||
width: $s-48;
|
width: $s-48;
|
||||||
border-radius: 50%;
|
border-radius: $br-circle;
|
||||||
background-color: var(--empty-message-background-color);
|
background-color: var(--empty-message-background-color);
|
||||||
svg {
|
svg {
|
||||||
@extend .button-icon;
|
@extend .button-icon;
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
&.disabled {
|
&.disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--panel-background-color);
|
background-color: var(--panel-background-color);
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,12 @@
|
||||||
&.disabled {
|
&.disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--panel-background-color);
|
background-color: var(--panel-background-color);
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
}
|
}
|
||||||
&:disabled {
|
&:disabled {
|
||||||
svg {
|
svg {
|
||||||
stroke: var(--button-foreground-color-disabled);
|
stroke: var(--button-background-color-disabled);
|
||||||
}
|
}
|
||||||
&::after {
|
&::after {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue