0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00

♻️ Remove new-css-system from colorpicker

This commit is contained in:
Eva 2024-01-02 17:01:52 +01:00 committed by Alonso Torres
parent 67c692fdbd
commit 452289b726
17 changed files with 549 additions and 4111 deletions

View file

@ -58,7 +58,6 @@
@import "main/partials/viewer-header";
@import "main/partials/viewer-thumbnails";
@import "main/partials/activity-bar";
@import "main/partials/colorpicker";
@import "main/partials/dashboard";
@import "main/partials/dashboard-header";
@import "main/partials/dashboard-grid";
@ -71,9 +70,7 @@
@import "main/partials/loader";
@import "main/partials/project-bar";
@import "main/partials/sidebar";
@import "main/partials/sidebar-align-options";
@import "main/partials/sidebar-document-history";
@import "main/partials/sidebar-element-options";
@import "main/partials/sidebar-interactions";
@import "main/partials/tab-container";
@import "main/partials/tool-bar";

View file

@ -1,598 +0,0 @@
// 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
.colorpicker {
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
background-color: $color-white;
}
.colorpicker-content {
display: flex;
flex-direction: column;
padding: $size-2;
& > * {
width: 200px;
}
.top-actions {
display: flex;
margin-bottom: $size-1;
flex-direction: row-reverse;
justify-content: space-between;
.picker-btn {
background: none;
border: none;
cursor: pointer;
&.active svg,
&:hover svg {
fill: $color-primary;
}
svg {
width: 14px;
height: 14px;
}
}
.element-set-content {
width: auto;
padding: 0.25rem 0;
.custom-select {
border: none;
&:hover {
border: none;
}
.custom-select-dropdown {
left: auto;
right: 0;
}
}
}
}
.select-image {
.content {
display: flex;
justify-content: center;
background-image: url("/images/colorpicker-no-image.png");
background-position: center;
background-size: auto 6.75rem;
height: 6.75rem;
img {
height: fit-content;
width: fit-content;
max-height: 100%;
max-width: 100%;
margin: auto;
}
}
button {
width: 100%;
margin-top: 10px;
}
}
.gradients-buttons {
.gradient {
cursor: pointer;
width: 15px;
height: 15px;
padding: 0;
margin: 0;
border: 1px solid $color-gray-20;
border-radius: $br2;
margin-left: $size-1;
}
.active {
border-color: $color-primary;
}
.linear-gradient {
background: linear-gradient(180deg, $color-gray-20, transparent);
}
.radial-gradient {
background: radial-gradient(transparent, $color-gray-20);
}
}
.gradient-stops {
height: 10px;
display: flex;
margin-top: $size-2;
margin-bottom: $size-4;
.gradient-background-wrapper {
height: 100%;
width: 100%;
border: 1px solid $color-gray-10;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
}
.gradient-background {
height: 100%;
width: 100%;
}
.gradient-stop-wrapper {
position: absolute;
width: calc(100% - 2rem);
margin-left: 0.5rem;
}
.gradient-stop {
display: grid;
grid-template-columns: 50% 50%;
position: absolute;
width: 15px;
height: 15px;
border-radius: $br2;
border: 1px solid $color-gray-20;
margin-top: -2px;
margin-left: -7px;
box-shadow: 0 2px 2px rgb(0 0 0 / 15%);
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
background-color: $color-white;
&.active {
border-color: $color-primary;
}
}
}
.picker-detail-wrapper {
position: relative;
.center-circle {
width: 14px;
height: 14px;
border: 2px solid $color-white;
border-radius: $br8;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-7px, -7px);
filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
}
}
#picker-detail {
border: 1px solid $color-gray-10;
}
.slider-selector {
--gradient-direction: 90deg;
--background-repeat: left;
&.vertical {
--gradient-direction: 0deg;
--background-repeat: top;
}
border: 1px solid $color-gray-10;
background: linear-gradient(
var(--gradient-direction),
rgba(var(--color), 0) 0%,
rgba(var(--color), 1) 100%
);
align-self: center;
position: relative;
cursor: pointer;
width: 100%;
height: calc(0.5rem + 1px);
&.vertical {
width: calc(0.5rem + 1px);
height: 100%;
}
&.hue {
background: linear-gradient(
var(--gradient-direction),
#f00 0%,
#ff0 17%,
#0f0 33%,
#0ff 50%,
#00f 67%,
#f0f 83%,
#f00 100%
);
}
&.saturation {
background: linear-gradient(
var(--gradient-direction),
var(--saturation-grad-from) 0%,
var(--saturation-grad-to) 100%
);
}
&.opacity {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
var(--background-repeat) center;
&::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(
var(--gradient-direction),
rgba(var(--color), 0) 0%,
rgba(var(--color), 1) 100%
);
}
}
&.value {
background: linear-gradient(var(--gradient-direction), #000 0%, #fff 100%);
}
.handler {
background-color: $color-white;
box-shadow: rgba(0, 0, 0, 0.37) 0px 1px 4px 0px;
transform: translate(-6px, -2px);
left: 50%;
position: absolute;
width: 12px;
height: 12px;
border-radius: $br6;
z-index: 1;
}
&.vertical .handler {
transform: translate(-6px, 6px);
}
}
.value-saturation-selector {
background-color: rgba(var(--hue-rgb));
position: relative;
height: 6.75rem;
cursor: pointer;
.handler {
position: absolute;
width: 12px;
height: 12px;
border-radius: $br6;
z-index: 1;
border: 1px solid $color-white;
box-shadow:
rgb(255, 255, 255) 0px 0px 0px 1px inset,
rgb(0 0 0 / 0.25) 0px 4px 4px inset,
rgb(0 0 0 / 0.25) 0px 4px 4px;
transform: translate(-6px, -6px);
left: 50%;
top: 50%;
}
&::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
}
&::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}
}
.shade-selector {
display: grid;
justify-items: center;
align-items: center;
grid-template-areas:
"color hue"
"color opacity";
grid-template-columns: 2.5rem 1fr;
height: 3.5rem;
grid-row-gap: 0.5rem;
cursor: pointer;
margin-bottom: 0.25rem;
.slider-selector.hue {
grid-area: "hue";
align-self: flex-end;
}
.slider-selector.opacity {
grid-area: "opacity";
align-self: flex-start;
}
}
.color-values {
display: grid;
grid-template-columns: 3.5rem repeat(4, 1fr);
grid-row-gap: 0.25rem;
justify-items: center;
grid-column-gap: 0.25rem;
&.disable-opacity {
grid-template-columns: 3.5rem repeat(3, 1fr);
}
input {
width: 100%;
margin: 0;
border: 1px solid $color-gray-10;
border-radius: $br2;
font-size: $fs12;
height: 1.5rem;
padding: 0 $size-1;
color: $color-gray-40;
}
label {
font-size: $fs12;
}
}
.libraries {
border-top: 1px solid $color-gray-10;
padding-top: 0.5rem;
margin-top: 0.25rem;
width: 200px;
select {
background-image: url(/images/icons/arrow-down.svg);
background-repeat: no-repeat;
background-position: 95% 48%;
background-size: 10px;
margin: 0;
margin-bottom: $size-2;
width: 100%;
padding: $size-1 0.25rem;
font-size: $fs12;
color: $color-gray-40;
cursor: pointer;
border: 1px solid $color-gray-10;
border-radius: $br2;
option {
padding: 0;
}
}
.selected-colors {
display: grid;
grid-template-columns: repeat(8, 1fr);
justify-content: space-between;
margin-right: -8px;
max-height: 5.5rem;
overflow: auto;
div {
grid-area: unset;
}
}
.selected-colors::after {
content: "";
flex: auto;
}
}
.actions {
margin-top: 0.5rem;
display: flex;
flex-direction: row;
justify-content: center;
.btn-primary {
height: 1.5rem;
font-size: $fs12;
width: 100%;
}
}
.harmony-selector {
display: flex;
flex-direction: row;
margin-bottom: 0.5rem;
.hue-wheel-wrapper {
position: relative;
.hue-wheel {
width: 152px;
height: 152px;
}
.handler {
position: absolute;
width: 12px;
height: 12px;
border-radius: $br6;
z-index: 1;
border: 1px solid $color-white;
box-shadow:
rgb(255, 255, 255) 0px 0px 0px 1px inset,
rgb(0 0 0 / 0.25) 0px 4px 4px inset,
rgb(0 0 0 / 0.25) 0px 4px 4px;
transform: translate(-6px, -6px);
left: 50%;
top: 50%;
}
.handler.complement {
background-color: $color-white;
box-shadow: rgb(0 0 0 / 0.25) 0px 4px 4px;
}
}
.handlers-wrapper {
height: 152px;
display: flex;
flex-direction: row;
flex-grow: 1;
justify-content: space-around;
padding-top: 0.5rem;
& > * {
height: 100%;
}
}
}
.hsva-selector {
display: grid;
padding: 0.25rem;
grid-template-columns: 20px 1fr;
grid-template-rows: repeat(4, 2rem);
grid-row-gap: 0.5rem;
margin-bottom: 0.5rem;
.hue,
.saturation,
.value,
.opacity {
border-radius: $br10;
}
.hsva-selector-label {
grid-column: 1;
align-self: center;
}
}
}
.colorpicker-tooltip {
border-radius: $br3;
display: flex;
flex-direction: column;
left: 1400px;
top: 100px;
position: absolute;
z-index: 11;
width: auto;
span {
color: $color-gray-20;
font-size: $fs12;
}
.inputs-area {
.input-text {
color: $color-gray-60;
font-size: $fs12;
margin: 5px;
padding: 5px;
width: 100%;
}
}
.colorpicker-tabs {
display: flex;
margin-bottom: $size-2;
border-radius: $br5;
border: 1px solid $color-gray-10;
height: 2rem;
.colorpicker-tab {
cursor: pointer;
display: flex;
flex-grow: 1;
justify-content: center;
align-items: center;
svg {
width: 16px;
height: 16px;
fill: $color-gray-20;
}
}
.active {
background-color: $color-gray-10;
svg {
fill: $color-gray-60;
}
}
:hover svg {
fill: $color-primary;
}
}
}
.color-data {
align-items: center;
display: flex;
margin-bottom: $size-2;
position: relative;
&[draggable="true"] {
cursor: pointer;
}
.color-name {
font-size: $fs12;
margin: 5px 6px 0px 6px;
}
.color-info {
flex: 1 1 0;
input {
background-color: $color-gray-50;
border: 1px solid $color-gray-30;
border-radius: $br3;
color: $color-white;
height: 20px;
margin: 5px 0 0 0;
padding: 0 $size-1;
width: 84px;
font-size: $fs12;
&:focus {
border-color: $color-primary !important;
color: $color-white;
outline: none;
}
&:hover {
border-color: $color-gray-20;
}
&:invalid {
border-color: $color-danger;
}
}
}
::placeholder {
color: $color-gray-10;
}
.type {
color: $color-gray-10;
margin-right: $size-1;
}
.number {
color: $color-gray-60;
}
.element-set-actions-button svg {
width: 10px;
height: 10px;
}
}

View file

@ -1,62 +0,0 @@
// 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
.align-options {
display: flex;
border-bottom: solid 1px $color-gray-60;
height: 40px;
.align-group {
padding: 0 $size-1;
display: flex;
justify-content: flex-start;
width: 50%;
&:not(:last-child) {
border-right: solid 1px $color-gray-60;
}
}
.align-button {
align-items: center;
cursor: pointer;
display: flex;
height: 30px;
justify-content: center;
margin: 5px 0;
padding: $size-2 $size-1;
width: 25%;
svg {
height: 16px;
width: 16px;
fill: $color-gray-20;
}
&:hover {
background-color: $color-primary;
svg {
fill: $color-gray-50;
}
}
&.disabled {
background-color: transparent;
cursor: default;
svg {
fill: $color-gray-40;
}
}
&.selected svg {
fill: $color-primary;
}
&.selected:hover svg {
fill: $color-white;
}
}
}

View file

@ -20,7 +20,6 @@
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.workspace.colorpicker.color-inputs :refer [color-inputs]]
[app.main.ui.workspace.colorpicker.gradients :refer [gradients]]
@ -52,8 +51,7 @@
(mf/defc colorpicker
[{:keys [data disable-gradient disable-opacity disable-image on-change on-accept]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
state (mf/deref refs/colorpicker)
(let [state (mf/deref refs/colorpicker)
node-ref (mf/use-ref)
;; TODO: I think we need to put all this picking state under
@ -267,235 +265,123 @@
:h h :s s :v v
:alpha (/ alpha 255)}))))
(if new-css-system
[:div {:class (stl/css :colorpicker)
:ref node-ref
:style {:touch-action "none"}}
[:div {:class (stl/css :top-actions)}
(when (or (not disable-gradient) (not disable-image))
[:div {:class (stl/css :select)}
[:& select
{:default-value selected-mode
:options options
:on-change handle-change-mode}]])
(when (not= selected-mode :image)
[:button {:class (stl/css-case :picker-btn true
:selected picking-color?)
:on-click handle-click-picker}
i/picker-refactor])]
[:div {:class (stl/css :colorpicker)
:ref node-ref
:style {:touch-action "none"}}
[:div {:class (stl/css :top-actions)}
(when (or (not disable-gradient) (not disable-image))
[:div {:class (stl/css :select)}
[:& select
{:default-value selected-mode
:options options
:on-change handle-change-mode}]])
(when (not= selected-mode :image)
[:button {:class (stl/css-case :picker-btn true
:selected picking-color?)
:on-click handle-click-picker}
i/picker-refactor])]
(when (or (= selected-mode :linear-gradient)
(when (or (= selected-mode :linear-gradient)
(= selected-mode :radial-gradient))
[:& gradients
{:stops (:stops state)
:editing-stop (:editing-stop state)
:on-select-stop handle-change-stop}])
[:& gradients
{:stops (:stops state)
:editing-stop (:editing-stop state)
:on-select-stop handle-change-stop}])
(if (= selected-mode :image)
(let [uri (cfg/resolve-file-media (:image current-color))]
[:div {:class (stl/css :select-image)}
[:div {:class (stl/css :content)}
(when (:image current-color)
[:img {:src uri}])]
[:button
{:class (stl/css :choose-image)
:title (tr "media.choose-image")
:aria-label (tr "media.choose-image")
:on-click on-fill-image-click}
(tr "media.choose-image")
[:& file-uploader
{:input-id "fill-image-upload"
:accept "image/jpeg,image/png"
:multi false
:ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:*
[:div {:class (stl/css :colorpicker-tabs)}
[:& tab-container
{:on-change-tab set-tab!
:selected @active-color-tab
:collapsable? false}
[:& tab-element {:id :ramp :title i/rgba-refactor}
(if picking-color?
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& ramp-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]
[:& tab-element {:id :harmony :title i/rgba-complementary-refactor}
(if picking-color?
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& harmony-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]
[:& tab-element {:id :hsva :title i/hsva-refactor}
(if picking-color?
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& hsva-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]]]
[:& color-inputs
{:type (if (= @active-color-tab :hsva) :hsv :rgb)
:disable-opacity disable-opacity
:color current-color
:on-change handle-change-color}]
[:& libraries
{:state state
:current-color current-color
:disable-gradient disable-gradient
:disable-opacity disable-opacity
:disable-image disable-image
:on-select-color on-select-library-color
:on-add-library-color on-add-library-color}]])
(when on-accept
[:div {:class (stl/css :actions)}
[:button {:class (stl/css-case
:accept-color true
:btn-disabled disabled-color-accept?)
:on-click on-color-accept
:disabled disabled-color-accept?}
(tr "workspace.libraries.colors.save-color")]])]
[:div.colorpicker {:ref node-ref
:style {:touch-action "none"}}
[:div.colorpicker-content
[:div.top-actions
(when (or (not disable-gradient) (not disable-image))
[:div.element-set-content
[:& select
{:default-value selected-mode
:options options
:on-change handle-change-mode}]])
(when (not= selected-mode :image)
[:button.picker-btn
{:class (when picking-color? "active")
:on-click handle-click-picker}
i/picker])]
(when (or (= (:type state) :linear-gradient)
(= (:type state) :radial-gradient))
[:& gradients
{:stops (:stops state)
:editing-stop (:editing-stop state)
:on-select-stop handle-change-stop}])
(if (= selected-mode :image)
(let [uri (cfg/resolve-file-media (:image current-color))]
[:div.select-image
[:div.content
(when (:image current-color)
[:img {:src uri}])]
[:button.btn-secondary
{:title (tr "media.choose-image")
:aria-label (tr "media.choose-image")
:on-click on-fill-image-click}
(tr "media.choose-image")
[:& file-uploader
{:input-id "fill-image-upload"
:accept "image/jpeg,image/png"
:multi false
:ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:*
[:div.colorpicker-tabs
[:div.colorpicker-tab.tooltip.tooltip-bottom.tooltip-expand
{:class (when (= @active-color-tab :ramp) "active")
:alt (tr "workspace.libraries.colors.rgba")
:on-click set-tab!
:data-tab "ramp"} i/picker-ramp]
[:div.colorpicker-tab.tooltip.tooltip-bottom.tooltip-expand
{:class (when (= @active-color-tab :harmony) "active")
:alt (tr "workspace.libraries.colors.rgb-complementary")
:on-click set-tab!
:data-tab "harmony"} i/picker-harmony]
[:div.colorpicker-tab.tooltip.tooltip-bottom.tooltip-expand
{:class (when (= @active-color-tab :hsva) "active")
:alt (tr "workspace.libraries.colors.hsv")
:on-click set-tab!
:data-tab "hsva"} i/picker-hsv]]
(if (= selected-mode :image)
(let [uri (cfg/resolve-file-media (:image current-color))]
[:div {:class (stl/css :select-image)}
[:div {:class (stl/css :content)}
(when (:image current-color)
[:img {:src uri}])]
[:button
{:class (stl/css :choose-image)
:title (tr "media.choose-image")
:aria-label (tr "media.choose-image")
:on-click on-fill-image-click}
(tr "media.choose-image")
[:& file-uploader
{:input-id "fill-image-upload"
:accept "image/jpeg,image/png"
:multi false
:ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:*
[:div {:class (stl/css :colorpicker-tabs)}
[:& tab-container
{:on-change-tab set-tab!
:selected @active-color-tab
:collapsable? false}
[:& tab-element {:id :ramp :title i/rgba-refactor}
(if picking-color?
[:div.picker-detail-wrapper
[:div.center-circle]
[:canvas#picker-detail {:width 200 :height 160}]]
(case @active-color-tab
:ramp
[:& ramp-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
:harmony
[:& harmony-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
:hsva
[:& hsva-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
nil))
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& ramp-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]
[:& color-inputs
{:type (if (= @active-color-tab :hsva) :hsv :rgb)
:disable-opacity disable-opacity
:color current-color
:on-change handle-change-color}]
[:& tab-element {:id :harmony :title i/rgba-complementary-refactor}
(if picking-color?
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& harmony-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]
[:& libraries
{:state state
:current-color current-color
:disable-gradient disable-gradient
:disable-opacity disable-opacity
:disable-image disable-image
:on-select-color on-select-library-color
:on-add-library-color on-add-library-color}]])
[:& tab-element {:id :hsva :title i/hsva-refactor}
(if picking-color?
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:width 256 :height 140}]]
[:& hsva-selector
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]]]
(when on-accept
[:div.actions
[:button.btn-primary.btn-large
{:on-click on-color-accept
:disabled disabled-color-accept?
:class (dom/classnames
:btn-disabled disabled-color-accept?)}
(tr "workspace.libraries.colors.save-color")]])]])))
[:& color-inputs
{:type (if (= @active-color-tab :hsva) :hsv :rgb)
:disable-opacity disable-opacity
:color current-color
:on-change handle-change-color}]
[:& libraries
{:state state
:current-color current-color
:disable-gradient disable-gradient
:disable-opacity disable-opacity
:disable-image disable-image
:on-select-color on-select-library-color
:on-add-library-color on-add-library-color}]])
(when on-accept
[:div {:class (stl/css :actions)}
[:button {:class (stl/css-case
:accept-color true
:btn-disabled disabled-color-accept?)
:on-click on-color-accept
:disabled disabled-color-accept?}
(tr "workspace.libraries.colors.save-color")]])]))
(defn calculate-position
"Calculates the style properties for the given coordinates and position"
[{vh :height} position x y new-css-system]
[{vh :height} position x y]
(let [;; picker height in pixels
h(if new-css-system 510 430)
h 510
;; Checks for overflow outside the viewport height
overflow-fix (max 0 (+ y (- 50) h (- vh)))
x-pos (if new-css-system 325 250)]
x-pos 325]
(cond
(or (nil? x) (nil? y)) {:left "auto" :right "16rem" :top "4rem"}
(= position :left) {:left (str (- x x-pos) "px")
@ -512,12 +398,11 @@
disable-opacity
disable-image
on-change on-close on-accept] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
vport (mf/deref viewport)
(let [vport (mf/deref viewport)
dirty? (mf/use-var false)
last-change (mf/use-var nil)
position (or position :left)
style (calculate-position vport position x y new-css-system)
style (calculate-position vport position x y)
handle-change
(fn [new-data]
@ -531,7 +416,7 @@
#(when (and @dirty? @last-change on-close)
(on-close @last-change))))
[:div {:class (stl/css new-css-system :colorpicker-tooltip)
[:div {:class (stl/css :colorpicker-tooltip)
:style (clj->js style)}
[:& colorpicker {:data data
:disable-gradient disable-gradient

View file

@ -11,118 +11,126 @@
top: $s-100;
left: calc(10 * $s-140);
width: auto;
.colorpicker {
border-radius: $br-8;
width: $s-260;
& > * {
width: $s-260;
}
.top-actions {
display: flex;
align-items: flex-start;
flex-direction: row-reverse;
justify-content: space-between;
height: $s-40;
.picker-btn {
@include buttonStyle;
@include flexCenter;
border-radius: $br-8;
background-color: transparent;
border: $s-1 solid transparent;
height: $s-20;
width: $s-20;
border-radius: $br-4;
padding: 0;
margin-top: $s-4;
svg {
@extend .button-icon;
stroke: var(--button-tertiary-foreground-color-rest);
}
&:hover {
svg {
stroke: var(--button-tertiary-foreground-color-focus);
}
}
&:focus,
&:focus-visible {
outline: none;
svg {
stroke: var(--button-secondary-foreground-color-hover);
}
}
&:active {
outline: none;
border: $s-1 solid transparent;
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
&.selected {
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.gradient-buttons {
display: flex;
align-items: center;
gap: $s-8;
.gradient-btn {
@extend .button-tertiary;
height: $s-20;
width: $s-20;
border-radius: $br-4;
border: $s-2 solid transparent;
&:hover {
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
.linear-gradient-btn {
background: linear-gradient(180deg, var(--color-foreground-secondary), transparent);
&.selected {
background: linear-gradient(to bottom, rgba(126, 255, 245, 1) 0%, rgba(126, 255, 245, 0.2) 100%);
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
}
.radial-gradient-btn {
background: radial-gradient(transparent, var(--color-foreground-secondary));
&.selected {
background: radial-gradient(rgba(126, 255, 245, 1) 0%, rgba(126, 255, 245, 0.2) 100%);
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
}
}
.actions {
display: flex;
gap: $s-4;
.accept-color {
@include tabTitleTipography;
@extend .button-secondary;
width: 100%;
height: $s-32;
margin-top: $s-8;
}
.colorpicker {
border-radius: $br-8;
width: $s-260;
& > * {
width: $s-260;
}
}
.top-actions {
display: flex;
align-items: flex-start;
flex-direction: row-reverse;
justify-content: space-between;
height: $s-40;
}
.picker-btn {
@include buttonStyle;
@include flexCenter;
border-radius: $br-8;
background-color: transparent;
border: $s-1 solid transparent;
height: $s-20;
width: $s-20;
border-radius: $br-4;
padding: 0;
margin-top: $s-4;
svg {
@extend .button-icon;
stroke: var(--button-tertiary-foreground-color-rest);
}
&:hover {
svg {
stroke: var(--button-tertiary-foreground-color-focus);
}
}
.colorpicker-tabs {
.picker-detail-wrapper {
@include flexCenter;
position: relative;
margin: $s-12 0 $s-8 0;
.center-circle {
width: $s-24;
height: $s-24;
border: $s-2 solid var(--colorpicker-details-color);
border-radius: $br-circle;
position: absolute;
left: 50%;
top: 50%;
transform: translate(calc(-1 * $s-12), calc(-1 * $s-12));
}
&:focus,
&:focus-visible {
outline: none;
svg {
stroke: var(--button-secondary-foreground-color-hover);
}
}
&:active {
outline: none;
border: $s-1 solid transparent;
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
&.selected {
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.gradient-buttons {
display: flex;
align-items: center;
gap: $s-8;
}
.gradient-btn {
@extend .button-tertiary;
height: $s-20;
width: $s-20;
border-radius: $br-4;
border: $s-2 solid transparent;
&:hover {
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
.linear-gradient-btn {
background: linear-gradient(180deg, var(--color-foreground-secondary), transparent);
&.selected {
background: linear-gradient(to bottom, rgba(126, 255, 245, 1) 0%, rgba(126, 255, 245, 0.2) 100%);
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
.radial-gradient-btn {
background: radial-gradient(transparent, var(--color-foreground-secondary));
&.selected {
background: radial-gradient(rgba(126, 255, 245, 1) 0%, rgba(126, 255, 245, 0.2) 100%);
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
.actions {
display: flex;
gap: $s-4;
}
.accept-color {
@include tabTitleTipography;
@extend .button-secondary;
width: 100%;
height: $s-32;
margin-top: $s-8;
}
.picker-detail-wrapper {
@include flexCenter;
position: relative;
margin: $s-12 0 $s-8 0;
}
.center-circle {
width: $s-24;
height: $s-24;
border: $s-2 solid var(--colorpicker-details-color);
border-radius: $br-circle;
position: absolute;
left: 50%;
top: 50%;
transform: translate(calc(-1 * $s-12), calc(-1 * $s-12));
}
.select {
@ -131,29 +139,31 @@
.select-image {
margin-top: $s-4;
.content {
border-radius: $br-8;
display: flex;
justify-content: center;
background-image: url("/images/colorpicker-no-image.png");
background-position: center;
background-size: auto $s-140;
height: $s-140;
margin-bottom: $s-6;
margin-right: $s-1;
img {
height: fit-content;
width: fit-content;
max-height: 100%;
max-width: 100%;
margin: auto;
}
}
.choose-image {
@extend .button-secondary;
@include tabTitleTipography;
width: 100%;
margin-top: $s-12;
height: $s-32;
}
.content {
border-radius: $br-8;
display: flex;
justify-content: center;
background-image: url("/images/colorpicker-no-image.png");
background-position: center;
background-size: auto $s-140;
height: $s-140;
margin-bottom: $s-6;
margin-right: $s-1;
img {
height: fit-content;
width: fit-content;
max-height: 100%;
max-width: 100%;
margin: auto;
}
}
.choose-image {
@extend .button-secondary;
@include tabTitleTipography;
width: 100%;
margin-top: $s-12;
height: $s-32;
}

View file

@ -8,7 +8,6 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
@ -22,40 +21,22 @@
(mf/defc gradients
[{:keys [stops editing-stop on-select-stop]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :gradient-stops)}
[:div {:class (stl/css :gradient-background-wrapper)}
[:div {:class (stl/css :gradient-background)
:style {:background (gradient->string stops)}}]]
[:div {:class (stl/css :gradient-stops)}
[:div {:class (stl/css :gradient-background-wrapper)}
[:div {:class (stl/css :gradient-background)
:style {:background (gradient->string stops)}}]]
[:div {:class (stl/css :gradient-stop-wrapper)}
(for [{:keys [offset hex r g b alpha] :as value} stops]
[:button {:class (stl/css-case :gradient-stop true
:selected (= editing-stop offset))
:data-value offset
:on-click on-select-stop
:style {:left (dm/str (* offset 100) "%")
:backgroundColor hex}
:key (dm/str offset)}
[:div {:class (stl/css :gradient-stop-wrapper)}
(for [{:keys [offset hex r g b alpha] :as value} stops]
[:button {:class (stl/css-case :gradient-stop true
:selected (= editing-stop offset))
:data-value offset
:on-click on-select-stop
:style {:left (dm/str (* offset 100) "%")
:backgroundColor hex}
:key (dm/str offset)}
[:div {:class (stl/css :gradient-stop-color)
:style {:background-color hex}}]
[:div {:class (stl/css :gradient-stop-alpha)
:style {:background-color (str/ffmt "rgba(%1, %2, %3, %4)" r g b alpha)}}]])]]
[:div.gradient-stops
[:div.gradient-background-wrapper
[:div.gradient-background {:style {:background (gradient->string stops)}}]]
[:div.gradient-stop-wrapper
(for [{:keys [offset hex r g b alpha] :as value} stops]
[:div.gradient-stop
{:class (when (= editing-stop offset) "active")
:data-value offset
:on-click on-select-stop
:style {:left (dm/str (* offset 100) "%")}
:key (dm/str offset)}
[:div.gradient-stop-color {:style {:background-color hex}}]
[:div.gradient-stop-alpha {:style {:background-color (str/ffmt "rgba(%1, %2, %3, %4)" r g b alpha)}}]])]])))
[:div {:class (stl/css :gradient-stop-color)
:style {:background-color hex}}]
[:div {:class (stl/css :gradient-stop-alpha)
:style {:background-color (str/ffmt "rgba(%1, %2, %3, %4)" r g b alpha)}}]])]])

View file

@ -13,39 +13,41 @@
margin: $s-12 0;
background-color: var(--colorpicker-handlers-color);
border-radius: $br-6;
}
.gradient-background-wrapper {
height: 100%;
width: 100%;
border-radius: $br-6;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
.gradient-background-wrapper {
height: 100%;
width: 100%;
border-radius: $br-6;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
}
.gradient-background {
height: 100%;
width: 100%;
border-radius: $br-6;
border: $s-2 solid var(--colorpicker-details-color);
}
}
.gradient-stop-wrapper {
position: absolute;
width: calc(100% - 2rem);
.gradient-stop {
position: absolute;
display: grid;
grid-template-columns: 50% 50%;
width: $s-16;
height: $s-24;
border-radius: $br-4;
margin-top: calc(-1 * $s-2);
margin-left: calc(-1 * $s-8);
border: $s-2 solid var(--colorpicker-handlers-color);
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
&.selected {
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}
.gradient-background {
height: 100%;
width: 100%;
border-radius: $br-6;
border: $s-2 solid var(--colorpicker-details-color);
}
.gradient-stop-wrapper {
position: absolute;
width: calc(100% - 2rem);
}
.gradient-stop {
position: absolute;
display: grid;
grid-template-columns: 50% 50%;
width: $s-16;
height: $s-24;
border-radius: $br-4;
margin-top: calc(-1 * $s-2);
margin-left: calc(-1 * $s-8);
border: $s-2 solid var(--colorpicker-handlers-color);
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
left center;
&.selected {
border: $s-2 solid var(--colorpicker-details-color-selected);
}
}

View file

@ -10,7 +10,6 @@
[app.common.colors :as cc]
[app.common.geom.point :as gpt]
[app.common.math :as mth]
[app.main.ui.context :as ctx]
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
[app.util.dom :as dom]
[app.util.object :as obj]
@ -59,11 +58,8 @@
(gpt/point x y)))
(mf/defc harmony-selector [{:keys [color disable-opacity on-change on-start-drag on-finish-drag]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
canvas-ref (mf/use-ref nil)
canvas-side (if new-css-system
192
152)
(let [canvas-ref (mf/use-ref nil)
canvas-side 192
{hue :h saturation :s value :v alpha :alpha} color
pos-current (color->point canvas-side hue saturation)
@ -128,83 +124,44 @@
(mf/deps canvas-ref)
(fn [] (when canvas-ref
(create-color-wheel (mf/ref-val canvas-ref)))))
(if new-css-system
[:div {:class (stl/css :harmony-selector)}
[:div {:class (stl/css :handlers-wrapper)}
[:& slider-selector {:type :value
:vertical? true
:reverse? true
:value value
:max-value 255
:vertical true
:on-change on-change-value
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[[:& slider-selector {:type :opacity
:vertical? true
:value alpha
:max-value 1
:vertical true
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]])]
[:div {:class (stl/css :harmony-selector)}
[:div {:class (stl/css :handlers-wrapper)}
[:& slider-selector {:type :value
:vertical? true
:reverse? true
:value value
:max-value 255
:vertical true
:on-change on-change-value
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[[:& slider-selector {:type :opacity
:vertical? true
:value alpha
:max-value 1
:vertical true
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]])]
[:div {:class (stl/css :hue-wheel-wrapper)}
[:canvas {:class (stl/css :hue-wheel)
:ref canvas-ref
:width canvas-side
:height canvas-side
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}]
[:div {:class (stl/css :handler)
:style {:pointer-events "none"
:left (:x pos-current)
:top (:y pos-current)}}]
[:div {:class (stl/css-case :handler true
:complement true)
:style {:left (:x pos-complement)
:top (:y pos-complement)
:cursor "pointer"}
:on-click on-complement-click}]]]
[:div.harmony-selector
[:div.hue-wheel-wrapper
[:canvas.hue-wheel
{:ref canvas-ref
:width canvas-side
:height canvas-side
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}]
[:div.handler {:style {:pointer-events "none"
:left (:x pos-current)
:top (:y pos-current)}}]
[:div.handler.complement {:style {:left (:x pos-complement)
:top (:y pos-complement)
:cursor "pointer"}
:on-click on-complement-click}]]
[:div.handlers-wrapper
[:& slider-selector {:class "value"
:vertical? true
:reverse? true
:value value
:max-value 255
:vertical true
:on-change on-change-value
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[:& slider-selector {:class "opacity"
:vertical? true
:value alpha
:max-value 1
:vertical true
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]])))
[:div {:class (stl/css :hue-wheel-wrapper)}
[:canvas {:class (stl/css :hue-wheel)
:ref canvas-ref
:width canvas-side
:height canvas-side
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}]
[:div {:class (stl/css :handler)
:style {:pointer-events "none"
:left (:x pos-current)
:top (:y pos-current)}}]
[:div {:class (stl/css-case :handler true
:complement true)
:style {:left (:x pos-complement)
:top (:y pos-complement)
:cursor "pointer"}
:on-click on-complement-click}]]]))

View file

@ -12,32 +12,33 @@
gap: $s-8;
margin-top: $s-12;
margin-bottom: $s-8;
.hue-wheel-wrapper {
@include flexCenter;
position: relative;
.hue-wheel {
width: $s-196;
height: $s-196;
}
.handler {
@extend .colorpicker-handler;
height: $s-16;
width: $s-16;
border: $s-2 solid var(--colorpicker-handlers-color);
}
.handler.complement {
background-color: var(--colorpicker-handlers-color);
border: $s-2 solid var(--colorpicker-handlers-color);
}
}
.handlers-wrapper {
@include flexRow;
height: $s-200;
width: $s-52;
flex-grow: 1;
}
}
.hue-wheel-wrapper {
@include flexCenter;
position: relative;
}
.hue-wheel {
width: $s-196;
height: $s-196;
}
.handler {
@extend .colorpicker-handler;
height: $s-16;
width: $s-16;
border: $s-2 solid var(--colorpicker-handlers-color);
}
.handler.complement {
background-color: var(--colorpicker-handlers-color);
border: $s-2 solid var(--colorpicker-handlers-color);
}
.handlers-wrapper {
@include flexRow;
height: $s-200;
width: $s-52;
flex-grow: 1;
}

View file

@ -8,13 +8,11 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.colors :as cc]
[app.main.ui.context :as ctx]
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
[rumext.v2 :as mf]))
(mf/defc hsva-selector [{:keys [color disable-opacity on-change on-start-drag on-finish-drag]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
{hue :h saturation :s value :v alpha :alpha} color
(let [{hue :h saturation :s value :v alpha :alpha} color
handle-change-slider (fn [key]
(fn [new-value]
(let [change (hash-map key new-value)
@ -25,87 +23,46 @@
{:hex hex
:r r :g g :b b})))))
on-change-opacity (fn [new-alpha] (on-change {:alpha new-alpha}))]
(if new-css-system
[:div {:class (stl/css :hsva-selector)}
[:div {:class (stl/css :hsva-selector)}
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "H"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :hue
:max-value 360
:value hue
:on-change (handle-change-slider :h)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "S"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :saturation
:max-value 1
:value saturation
:on-change (handle-change-slider :s)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "V"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :value
:reverse? false
:max-value 255
:value value
:on-change (handle-change-slider :v)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
(when (not disable-opacity)
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "H"]
[:span {:class (stl/css :hsva-selector-label)} "A"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :hue
:max-value 360
:value hue
:on-change (handle-change-slider :h)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "S"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :saturation
:type :opacity
:max-value 1
:value saturation
:on-change (handle-change-slider :s)
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "V"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :value
:reverse? false
:max-value 255
:value value
:on-change (handle-change-slider :v)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]]
(when (not disable-opacity)
[:div {:class (stl/css :hsva-row)}
[:span {:class (stl/css :hsva-selector-label)} "A"]
[:& slider-selector
{:class (stl/css :hsva-bar)
:type :opacity
:max-value 1
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]])]
[:div.hsva-selector
[:span.hsva-selector-label "H"]
[:& slider-selector
{:class "hue"
:max-value 360
:value hue
:on-change (handle-change-slider :h)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:span.hsva-selector-label "S"]
[:& slider-selector
{:class "saturation"
:max-value 1
:value saturation
:on-change (handle-change-slider :s)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:span.hsva-selector-label "V"]
[:& slider-selector
{:class "value"
:reverse? false
:max-value 255
:value value
:on-change (handle-change-slider :v)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[:*
[:span.hsva-selector-label "A"]
[:& slider-selector
{:class "opacity"
:max-value 1
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]])])
))
:on-finish-drag on-finish-drag}]])]))

View file

@ -11,18 +11,21 @@
padding: $s-4;
grid-row-gap: $s-8;
margin-bottom: $s-8;
.hsva-row {
display: flex;
align-items: center;
.hsva-selector-label {
@include tabTitleTipography;
display: flex;
align-items: center;
justify-content: flex-start;
width: $s-32;
}
.hsva-bar {
width: $s-228;
}
}
}
.hsva-row {
display: flex;
align-items: center;
}
.hsva-selector-label {
@include tabTitleTipography;
display: flex;
align-items: center;
justify-content: flex-start;
width: $s-32;
}
.hsva-bar {
width: $s-228;
}

View file

@ -14,10 +14,8 @@
[app.main.data.workspace.colors :as mdc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.color-bullet :refer [color-bullet]]
[app.main.ui.components.color-bullet-new :as cb]
[app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i]
@ -28,8 +26,7 @@
(mf/defc libraries
[{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity disable-image]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent)
(let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent)
current-colors (mf/use-state [])
shared-libs (mf/deref refs/workspace-libraries)
@ -40,14 +37,11 @@
on-library-change
(mf/use-fn
(fn [event]
(let [val (if new-css-system
event
(dom/get-target-val event))]
(reset! selected
(if (or (= val "recent")
(= val "file"))
(keyword val)
(parse-uuid val))))))
(reset! selected
(if (or (= event "recent")
(= event "file"))
(keyword event)
(parse-uuid event)))))
check-valid-color?
(fn [color]
@ -103,59 +97,26 @@
(let [colors (vals file-colors)]
(reset! current-colors (into [] (filter check-valid-color?) colors)))))
(if new-css-system
[:div {:class (stl/css :libraries)}
[:div {:class (stl/css :select-wrapper)}
[:& select
{:class (stl/css :shadow-type-select)
:default-value (or (name @selected) "recent")
:options options
:on-change on-library-change}]]
[:div {:class (stl/css :libraries)}
[:div {:class (stl/css :select-wrapper)}
[:& select
{:class (stl/css :shadow-type-select)
:default-value (or (name @selected) "recent")
:options options
:on-change on-library-change}]]
[:div {:class (stl/css :selected-colors)}
(when (= @selected :file)
[:button {:class (stl/css :add-color-btn)
:on-click on-add-library-color}
i/add-refactor])
[:div {:class (stl/css :selected-colors)}
(when (= @selected :file)
[:button {:class (stl/css :add-color-btn)
:on-click on-add-library-color}
i/add-refactor])
[:button {:class (stl/css :palette-btn)
:on-click toggle-palette}
i/swatches-refactor]
[:button {:class (stl/css :palette-btn)
:on-click toggle-palette}
i/swatches-refactor]
(for [[idx color] (map-indexed vector @current-colors)]
[:& cb/color-bullet
{:key (dm/str "color-" idx)
:color color
:on-click on-color-click}])]]
[:div.libraries
[:select {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element
:on-change on-library-change
:value (name @selected)}
[:option {:value "recent"} (tr "workspace.libraries.colors.recent-colors")]
[:option {:value "file"} (tr "workspace.libraries.colors.file-library")]
(for [[_ {:keys [name id]}] shared-libs]
[:option {:key id :value id} name])]
[:div.selected-colors
(when (= @selected :file)
[:div.color-bullet.button.plus-button {:style {:background-color "var(--color-white)"}
:on-click on-add-library-color}
i/plus])
[:div.color-bullet.button {:style {:background-color "var(--color-white)"}
:on-click (fn []
(r/set-resize-type! :bottom)
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
(ts/schedule 300 #(st/emit! (dw/remove-layout-flag :textpalette)
(-> (dw/toggle-layout-flag :colorpalette)
(vary-meta assoc ::ev/origin "workspace-colorpicker")))))}
i/palette]
(for [[idx color] (map-indexed vector @current-colors)]
[:& color-bullet
{:key (dm/str "color-" idx)
:color color
:on-click on-color-click}])]])))
(for [[idx color] (map-indexed vector @current-colors)]
[:& cb/color-bullet
{:key (dm/str "color-" idx)
:color color
:on-click on-color-click}])]]))

View file

@ -9,32 +9,34 @@
.libraries {
margin-top: $s-8;
width: 100%;
}
.selected-colors {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: $s-4;
justify-content: space-between;
overflow: auto;
margin-top: $s-8;
.add-color-btn,
.palette-btn {
@extend .button-secondary;
height: $s-24;
width: $s-24;
border-radius: $br-circle;
padding: 0;
svg {
@extend .button-icon;
}
}
}
.selected-colors::after {
content: "";
flex: auto;
}
.selected-colors {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: $s-4;
justify-content: space-between;
overflow: auto;
margin-top: $s-8;
}
.select-wrapper {
overflow: initial;
.add-color-btn,
.palette-btn {
@extend .button-secondary;
height: $s-24;
width: $s-24;
border-radius: $br-circle;
padding: 0;
svg {
@extend .button-icon;
}
}
.selected-colors::after {
content: "";
flex: auto;
}
.select-wrapper {
overflow: initial;
}

View file

@ -9,16 +9,13 @@
(:require
[app.common.colors :as cc]
[app.common.math :as mth]
[app.main.ui.components.color-bullet :refer [color-bullet]]
[app.main.ui.components.color-bullet-new :as cb]
[app.main.ui.context :as ctx]
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(mf/defc value-saturation-selector [{:keys [saturation value on-change on-start-drag on-finish-drag]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
dragging? (mf/use-state false)
(let [dragging? (mf/use-state false)
calculate-pos
(fn [ev]
(let [{:keys [left right top bottom]} (-> ev dom/get-target dom/get-bounding-rect)
@ -42,32 +39,20 @@
(dom/release-pointer event)
(reset! dragging? false)
(on-finish-drag)))]
(if new-css-system
[:div {:class (stl/css :value-saturation-selector)
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
[:div {:class (stl/css :handler)
:style {:pointer-events "none"
:left (str (* 100 saturation) "%")
:top (str (* 100 (- 1 (/ value 255))) "%")}}]]
[:div.value-saturation-selector
{:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
[:div.handler {:style {:pointer-events "none"
:left (str (* 100 saturation) "%")
:top (str (* 100 (- 1 (/ value 255))) "%")}}]])))
[:div {:class (stl/css :value-saturation-selector)
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
[:div {:class (stl/css :handler)
:style {:pointer-events "none"
:left (str (* 100 saturation) "%")
:top (str (* 100 (- 1 (/ value 255))) "%")}}]]))
(mf/defc ramp-selector [{:keys [color disable-opacity on-change on-start-drag on-finish-drag]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
{hex :hex
(let [{hex :hex
hue :h saturation :s value :v alpha :alpha} color
on-change-value-saturation
@ -90,60 +75,32 @@
on-change-opacity
(fn [new-opacity]
(on-change {:alpha new-opacity}))]
(if new-css-system
[:*
[:& value-saturation-selector
{:hue hue
:saturation saturation
:value value
:on-change on-change-value-saturation
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:*
[:& value-saturation-selector
{:hue hue
:saturation saturation
:value value
:on-change on-change-value-saturation
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:div {:class (stl/css new-css-system :shade-selector)
:style #js {"--bullet-size" "52px"}}
[:& cb/color-bullet {:color {:color hex
:opacity alpha}
:area true}]
[:div {:class (stl/css :sliders-wrapper)}
[:& slider-selector {:type :hue
:max-value 360
:value hue
:on-change on-change-hue
[:div {:class (stl/css :shade-selector)
:style #js {"--bullet-size" "52px"}}
[:& cb/color-bullet {:color {:color hex
:opacity alpha}
:area true}]
[:div {:class (stl/css :sliders-wrapper)}
[:& slider-selector {:type :hue
:max-value 360
:value hue
:on-change on-change-hue
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[:& slider-selector {:type :opacity
:max-value 1
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[:& slider-selector {:type :opacity
:max-value 1
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]]]
[:*
[:& value-saturation-selector
{:hue hue
:saturation saturation
:value value
:on-change on-change-value-saturation
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:div.shade-selector
[:& color-bullet {:color {:color hex
:opacity alpha}}]
[:& slider-selector {:class "hue"
:max-value 360
:value hue
:on-change on-change-hue
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
(when (not disable-opacity)
[:& slider-selector {:class "opacity"
:max-value 1
:value alpha
:on-change on-change-opacity
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}])]])))
:on-finish-drag on-finish-drag}])]]]))

View file

@ -15,13 +15,6 @@
margin-bottom: $s-12;
cursor: pointer;
.handler {
@extend .colorpicker-handler;
height: $s-16;
width: $s-16;
border: $s-2 solid var(--colorpicker-handlers-color);
}
&::before {
content: "";
position: absolute;
@ -38,12 +31,21 @@
background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}
}
.handler {
@extend .colorpicker-handler;
height: $s-16;
width: $s-16;
border: $s-2 solid var(--colorpicker-handlers-color);
}
.shade-selector {
display: flex;
gap: $s-4;
height: $s-52;
cursor: pointer;
}
.sliders-wrapper {
@include flexColumn;
}

View file

@ -9,15 +9,13 @@
(:require
[app.common.data.macros :as dm]
[app.common.math :as mth]
[app.main.ui.context :as ctx]
[app.util.dom :as dom]
[app.util.object :as obj]
[rumext.v2 :as mf]))
(mf/defc slider-selector
[{:keys [value class min-value max-value vertical? reverse? on-change on-start-drag on-finish-drag type]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
min-value (or min-value 0)
(let [min-value (or min-value 0)
max-value (or max-value 1)
dragging? (mf/use-state false)
@ -53,49 +51,27 @@
value (+ min-value (* unit-value (- max-value min-value)))]
(on-change value))))]
(if new-css-system
[:div {:class (stl/css-case :opacity-wrapper (= type :opacity))}
[:div {:class (dm/str class (stl/css-case :vertical vertical?
:slider-selector true
:hue (= type :hue)
:opacity (= type :opacity)
:value (= type :value)))
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
(let [value-percent (* (/ (- value min-value)
(- max-value min-value)) 100)
[:div {:class (stl/css-case :opacity-wrapper (= type :opacity))}
[:div {:class (dm/str class (stl/css-case :vertical vertical?
:slider-selector true
:hue (= type :hue)
:opacity (= type :opacity)
:value (= type :value)))
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
(let [value-percent (* (/ (- value min-value)
(- max-value min-value)) 100)
value-percent (if reverse?
(mth/abs (- value-percent 100))
value-percent)
value-percent-str (str value-percent "%")
value-percent (if reverse?
(mth/abs (- value-percent 100))
value-percent)
value-percent-str (str value-percent "%")
style-common #js {:pointerEvents "none"}
style-horizontal (obj/merge! #js {:left value-percent-str} style-common)
style-vertical (obj/merge! #js {:bottom value-percent-str} style-common)]
[:div {:class (stl/css :handler)
:style (if vertical? style-vertical style-horizontal)}])]]
[:div.slider-selector
{:class (str (if vertical? "vertical " "") class)
:on-pointer-down handle-start-drag
:on-pointer-up handle-stop-drag
:on-lost-pointer-capture handle-stop-drag
:on-click calculate-pos
:on-pointer-move #(when @dragging? (calculate-pos %))}
(let [value-percent (* (/ (- value min-value)
(- max-value min-value)) 100)
value-percent (if reverse?
(mth/abs (- value-percent 100))
value-percent)
value-percent-str (str value-percent "%")
style-common #js {:pointerEvents "none"}
style-horizontal (obj/merge! #js {:left value-percent-str} style-common)
style-vertical (obj/merge! #js {:bottom value-percent-str} style-common)]
[:div.handler {:style (if vertical? style-vertical style-horizontal)}])])))
style-common #js {:pointerEvents "none"}
style-horizontal (obj/merge! #js {:left value-percent-str} style-common)
style-vertical (obj/merge! #js {:bottom value-percent-str} style-common)]
[:div {:class (stl/css :handler)
:style (if vertical? style-vertical style-horizontal)}])]]))