mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
commit
93ce6b6eb3
4 changed files with 283 additions and 8 deletions
101
frontend/src/app/main/ui/workspace/tokens/sets.cljs
Normal file
101
frontend/src/app/main/ui/workspace/tokens/sets.cljs
Normal file
|
@ -0,0 +1,101 @@
|
|||
;; 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
|
||||
|
||||
(ns app.main.ui.workspace.tokens.sets
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def active-sets #{#uuid "2858b330-828e-4131-86ed-e4d1c0f4b3e3"
|
||||
#uuid "d608877b-842a-473b-83ca-b5f8305caf83"})
|
||||
|
||||
(def sets-root-order [#uuid "2858b330-828e-4131-86ed-e4d1c0f4b3e3"
|
||||
#uuid "9c5108aa-bdb4-409c-a3c8-c3dfce2f8bf8"
|
||||
#uuid "0381446e-1f1d-423f-912c-ab577d61b79b"])
|
||||
|
||||
(def sets {#uuid "9c5108aa-bdb4-409c-a3c8-c3dfce2f8bf8" {:type :group
|
||||
:name "Group A"
|
||||
:children [#uuid "d1754e56-3510-493f-8287-5ef3417d4141"
|
||||
#uuid "d608877b-842a-473b-83ca-b5f8305caf83"]}
|
||||
#uuid "d608877b-842a-473b-83ca-b5f8305caf83" {:type :set
|
||||
:name "Set A / 1"}
|
||||
#uuid "d1754e56-3510-493f-8287-5ef3417d4141" {:type :group
|
||||
:name "Group A / B"
|
||||
:children [#uuid "f608877b-842a-473b-83ca-b5f8305caf83"
|
||||
#uuid "7cc05389-9391-426e-bc0e-ba5cb8f425eb"]}
|
||||
#uuid "f608877b-842a-473b-83ca-b5f8305caf83" {:type :set
|
||||
:name "Set A / B / 1"}
|
||||
#uuid "7cc05389-9391-426e-bc0e-ba5cb8f425eb" {:type :set
|
||||
:name "Set A / B / 2"}
|
||||
#uuid "2858b330-828e-4131-86ed-e4d1c0f4b3e3" {:type :set
|
||||
:name "Set Root 1"}
|
||||
#uuid "0381446e-1f1d-423f-912c-ab577d61b79b" {:type :set
|
||||
:name "Set Root 2"}})
|
||||
|
||||
(def ^:private chevron-icon
|
||||
(i/icon-xref :arrow (stl/css :chevron-icon)))
|
||||
|
||||
(defn set-selected-set
|
||||
[set-id]
|
||||
(dm/assert! (uuid? set-id))
|
||||
(ptk/reify ::set-selected-set
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state :selected-set-id set-id))))
|
||||
|
||||
(mf/defc sets-tree
|
||||
[{:keys [selected-set-id set-id]}]
|
||||
(let [set (get sets set-id)]
|
||||
(when set
|
||||
(let [{:keys [type name children]} set
|
||||
visible? (mf/use-state (contains? active-sets set-id))
|
||||
collapsed? (mf/use-state false)
|
||||
icon (if (= type :set) i/document i/group)
|
||||
selected? (mf/use-state (= set-id selected-set-id))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps type set-id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (set-selected-set set-id))))]
|
||||
[:div {:class (stl/css :set-item-container)
|
||||
:on-click on-click}
|
||||
[:div {:class (stl/css-case :set-item-group (= type :group)
|
||||
:set-item-set (= type :set)
|
||||
:selected-set (and (= type :set) @selected?))}
|
||||
(when (= type :group)
|
||||
[:span {:class (stl/css-case
|
||||
:collapsabled-icon true
|
||||
:collapsed @collapsed?)
|
||||
:on-click #(when (= type :group) (swap! collapsed? not))}
|
||||
chevron-icon])
|
||||
[:span {:class (stl/css :icon)} icon]
|
||||
[:div {:class (stl/css :set-name)} name]
|
||||
(when (= type :set)
|
||||
[:span {:class (stl/css :action-btn)
|
||||
:on-click #(swap! visible? not)}
|
||||
(if @visible?
|
||||
i/shown
|
||||
i/hide)])]
|
||||
(when (and children (not @collapsed?))
|
||||
[:div {:class (stl/css :set-children)}
|
||||
(for [child-id children]
|
||||
[:& sets-tree {:key child-id :set-id child-id :selected-set-id selected-set-id}])])]))))
|
||||
|
||||
(mf/defc sets-list
|
||||
[{:keys [selected-set-id]}]
|
||||
[:ul {:class (stl/css :sets-list)}
|
||||
(for [set-id sets-root-order]
|
||||
[:& sets-tree {:key set-id
|
||||
:set-id set-id
|
||||
:selected-set-id selected-set-id}])])
|
101
frontend/src/app/main/ui/workspace/tokens/sets.scss
Normal file
101
frontend/src/app/main/ui/workspace/tokens/sets.scss
Normal file
|
@ -0,0 +1,101 @@
|
|||
// 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";
|
||||
|
||||
.sets-list {
|
||||
width: 100%;
|
||||
margin-bottom: $s-12;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.set-item-container {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
color: var(--layer-row-foreground-color);
|
||||
padding-left: $s-20;
|
||||
}
|
||||
|
||||
.set-item-set,
|
||||
.set-item-group {
|
||||
@include bodySmallTypography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: $s-32;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
color: var(--layer-row-foreground-color);
|
||||
.set-name {
|
||||
@include textEllipsis;
|
||||
flex-grow: 1;
|
||||
padding-left: $s-2;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: $s-20;
|
||||
height: $s-20;
|
||||
padding-right: $s-4;
|
||||
|
||||
svg {
|
||||
height: $s-20;
|
||||
width: $s-20;
|
||||
color: white;
|
||||
fill: none;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.set-item-set {
|
||||
&:hover {
|
||||
background-color: var(--layer-row-background-color-hover);
|
||||
color: var(--layer-row-foreground-color-hover);
|
||||
box-shadow: -100px 0 0 0 var(--layer-row-background-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.selected-set {
|
||||
background-color: var(--layer-row-background-color-selected);
|
||||
color: var(--layer-row-foreground-color-selected);
|
||||
box-shadow: -100px 0 0 0 var(--layer-row-background-color-selected);
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-28;
|
||||
width: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.collapsabled-icon {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
height: $s-24;
|
||||
border-radius: $br-8;
|
||||
|
||||
--chevron-icon-rotation: 90deg;
|
||||
|
||||
&.collapsed {
|
||||
--chevron-icon-rotation: 0deg;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
--chevron-icon-color: var(--title-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.chevron-icon {
|
||||
@extend .button-icon-small;
|
||||
margin-right: $s-6;
|
||||
transform: rotate(var(--chevron-icon-rotation));
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
|
@ -12,11 +12,13 @@
|
|||
[app.main.data.tokens :as dt]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.context-menu :refer [token-context-menu]]
|
||||
[app.main.ui.workspace.tokens.core :as wtc]
|
||||
[app.main.ui.workspace.tokens.sets :refer [sets-list]]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||
|
@ -32,6 +34,9 @@
|
|||
(def ^:private download-icon
|
||||
(i/icon-xref :download (stl/css :download-icon)))
|
||||
|
||||
(def selected-set-id
|
||||
(l/derived :selected-set-id st/state))
|
||||
|
||||
(mf/defc token-pill
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-click token highlighted? on-context-menu]}]
|
||||
|
@ -166,13 +171,35 @@
|
|||
:tokens tokens
|
||||
:token-type-props token-type-props}])]]))
|
||||
|
||||
(mf/defc sets-sidebar
|
||||
[]
|
||||
(let [selected-set-id (mf/deref selected-set-id)
|
||||
open? (mf/use-state true)]
|
||||
[:div {:class (stl/css :sets-sidebar)}
|
||||
[:div {:class (stl/css :sidebar-header)}
|
||||
[:& title-bar {:collapsable true
|
||||
:collapsed (not @open?)
|
||||
:all-clickable true
|
||||
:title "SETS"
|
||||
:on-collapsed #(swap! open? not)}]
|
||||
[:button {:class (stl/css :add-set)
|
||||
:on-click #(println "Add Set")}
|
||||
i/add]]
|
||||
(when @open?
|
||||
[:& sets-list {:selected-set-id selected-set-id}])]))
|
||||
|
||||
(mf/defc tokens-sidebar-tab
|
||||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
[_props]
|
||||
[:div {:class (stl/css :sidebar-tab-wrapper)}
|
||||
[:& tokens-explorer]
|
||||
[:button {:class (stl/css :download-json-button)
|
||||
:on-click wtc/download-tokens-as-json}
|
||||
download-icon
|
||||
"Export JSON"]])
|
||||
(let [show-sets-section? false] ;; temporarily added this variable to see/hide the sets section till we have it working end to end
|
||||
[:div {:class (stl/css :sidebar-tab-wrapper)}
|
||||
(when show-sets-section?
|
||||
[:div {:class (stl/css :sets-section-wrapper)}
|
||||
[:& sets-sidebar]])
|
||||
[:div {:class (stl/css :tokens-section-wrapper)}
|
||||
[:& tokens-explorer]]
|
||||
[:button {:class (stl/css :download-json-button)
|
||||
:on-click wtc/download-tokens-as-json}
|
||||
download-icon
|
||||
"Export JSON"]]))
|
||||
|
|
|
@ -5,11 +5,57 @@
|
|||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
@import "./common.scss";
|
||||
|
||||
.sidebar-tab-wrapper {
|
||||
padding: $s-12;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sets-section-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: $s-8;
|
||||
}
|
||||
|
||||
.sets-sidebar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-left: $s-8;
|
||||
padding-top: $s-12;
|
||||
color: var(--layer-row-foreground-color);
|
||||
}
|
||||
|
||||
.add-set {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
padding: 0;
|
||||
margin-right: $s-12;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.tokens-section-wrapper {
|
||||
flex: 1;
|
||||
padding-top: $s-12;
|
||||
padding-left: $s-12;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// TODO Remove once sets are available to public
|
||||
.sets-section-wrapper + .tokens-section-wrapper {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.token-pills-wrapper {
|
||||
|
|
Loading…
Add table
Reference in a new issue