mirror of
https://github.com/penpot/penpot.git
synced 2025-04-13 07:21:40 -05:00
Merge pull request #5766 from penpot/niwinz-tokens-changes
✨ Several changes to tokens
This commit is contained in:
commit
054efb3435
15 changed files with 440 additions and 330 deletions
|
@ -312,7 +312,7 @@
|
|||
(ptk/reify ::set-token-type-section-open
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-tokens :open-status token-type] open?))))
|
||||
(assoc-in state [:workspace-local :token-type-open-status token-type] open?))))
|
||||
|
||||
;; === Token Context Menu
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
(ns app.main.data.workspace.tokens.common
|
||||
(:require
|
||||
[app.main.data.helpers :as dsh]))
|
||||
|
||||
(defn get-workspace-tokens-lib
|
||||
[state]
|
||||
(-> (dsh/lookup-file-data state)
|
||||
(get :tokens-lib)))
|
|
@ -1,24 +1,29 @@
|
|||
;; 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.data.workspace.tokens.selected-set
|
||||
"The user selected token set in the ui, stored by the `:name` of the set.
|
||||
Will default to the first set."
|
||||
(:require
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.workspace.tokens.common :as dwtc]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn assoc-selected-token-set-name [state set-name]
|
||||
(assoc-in state [:workspace-local :selected-token-set-name] set-name))
|
||||
|
||||
(defn get-selected-token-set-name [state]
|
||||
(or (get-in state [:workspace-local :selected-token-set-name])
|
||||
(some-> (dwtc/get-workspace-tokens-lib state)
|
||||
(some-> (dsh/lookup-file-data state)
|
||||
(get :tokens-lib)
|
||||
(ctob/get-sets)
|
||||
(first)
|
||||
:name)))
|
||||
|
||||
(defn get-selected-token-set [state]
|
||||
(when-let [set-name (get-selected-token-set-name state)]
|
||||
(some-> (dwtc/get-workspace-tokens-lib state)
|
||||
(some-> (dsh/lookup-file-data state)
|
||||
(get :tokens-lib)
|
||||
(ctob/get-set set-name))))
|
||||
|
||||
(defn get-selected-token-set-token [state token-name]
|
||||
|
@ -30,8 +35,8 @@
|
|||
:tokens))
|
||||
|
||||
(defn set-selected-token-set-name
|
||||
[set-name]
|
||||
[name]
|
||||
(ptk/reify ::set-selected-token-set-path-from-name
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-selected-token-set-name state set-name))))
|
||||
(update state :workspace-local assoc :selected-token-set-name name))))
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
(l/derived
|
||||
(fn [{:keys [objects selected]}]
|
||||
(dsh/process-selected-shapes objects selected))
|
||||
selected-shapes-data))
|
||||
selected-shapes-data =))
|
||||
|
||||
(defn make-selected-ref
|
||||
[id]
|
||||
|
@ -479,6 +479,7 @@
|
|||
(def workspace-active-set-names
|
||||
(l/derived (d/nilf ctob/get-active-themes-set-names) tokens-lib))
|
||||
|
||||
;; FIXME: deprecated, it should not be implemented with ref
|
||||
(def workspace-active-theme-sets-tokens
|
||||
(l/derived #(or (some-> % ctob/get-active-themes-set-tokens) {}) tokens-lib))
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[app.main.ui.workspace.sidebar.shortcuts :refer [shortcuts-container]]
|
||||
[app.main.ui.workspace.sidebar.sitemap :refer [sitemap]]
|
||||
[app.main.ui.workspace.sidebar.versions :refer [versions-toolbox*]]
|
||||
[app.main.ui.workspace.tokens.sidebar :refer [tokens-sidebar-tab]]
|
||||
[app.main.ui.workspace.tokens.sidebar :refer [tokens-sidebar-tab*]]
|
||||
[app.util.debug :as dbg]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[potok.v2.core :as ptk]
|
||||
|
@ -120,7 +120,7 @@
|
|||
|
||||
tokens-tab
|
||||
(when design-tokens?
|
||||
(mf/html [:& tokens-sidebar-tab]))
|
||||
(mf/html [:> tokens-sidebar-tab*]))
|
||||
|
||||
tabs
|
||||
(if ^boolean mode-inspect?
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
(ns app.main.ui.workspace.tokens.changes
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.types.token :as ctt]
|
||||
|
@ -26,6 +28,8 @@
|
|||
[clojure.set :as set]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare token-properties)
|
||||
|
||||
;; Token Updates ---------------------------------------------------------------
|
||||
|
||||
(defn apply-token
|
||||
|
@ -76,12 +80,16 @@
|
|||
(update shape :applied-tokens remove-token))))))))
|
||||
|
||||
(defn toggle-token
|
||||
[{:keys [token-type-props token shapes] :as _props}]
|
||||
[{:keys [token shapes]}]
|
||||
(ptk/reify ::on-toggle-token
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [{:keys [attributes all-attributes on-update-shape]} token-type-props
|
||||
unapply-tokens? (wtt/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
(let [{:keys [attributes all-attributes on-update-shape]}
|
||||
(get token-properties (:type token))
|
||||
|
||||
unapply-tokens?
|
||||
(wtt/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
|
||||
shape-ids (map :id shapes)]
|
||||
(if unapply-tokens?
|
||||
(rx/of
|
||||
|
@ -272,3 +280,88 @@
|
|||
(select-keys attributes))]
|
||||
(dwsl/update-layout-child shape-ids props {:ignore-touched true
|
||||
:page-id page-id}))))))
|
||||
|
||||
;; Token Types -----------------------------------------------------------------
|
||||
|
||||
;; FIXME: the values should be lazy evaluated, probably a function,
|
||||
;; becasue on future we will need to translate that labels and that
|
||||
;; can not be done statically
|
||||
|
||||
(def token-properties
|
||||
"A map of default properties by token type"
|
||||
(d/ordered-map
|
||||
:border-radius
|
||||
{:title "Border Radius"
|
||||
:attributes ctt/border-radius-keys
|
||||
:on-update-shape update-shape-radius-all
|
||||
:modal {:key :tokens/border-radius
|
||||
:fields [{:label "Border Radius"
|
||||
:key :border-radius}]}}
|
||||
|
||||
:color
|
||||
{:title "Color"
|
||||
:attributes #{:fill}
|
||||
:all-attributes ctt/color-keys
|
||||
:on-update-shape update-fill-stroke
|
||||
:modal {:key :tokens/color
|
||||
:fields [{:label "Color" :key :color}]}}
|
||||
|
||||
:stroke-width
|
||||
{:title "Stroke Width"
|
||||
:attributes ctt/stroke-width-keys
|
||||
:on-update-shape update-stroke-width
|
||||
:modal {:key :tokens/stroke-width
|
||||
:fields [{:label "Stroke Width"
|
||||
:key :stroke-width}]}}
|
||||
|
||||
:sizing
|
||||
{:title "Sizing"
|
||||
:attributes #{:width :height}
|
||||
:all-attributes ctt/sizing-keys
|
||||
:on-update-shape update-shape-dimensions
|
||||
:modal {:key :tokens/sizing
|
||||
:fields [{:label "Sizing"
|
||||
:key :sizing}]}}
|
||||
:dimensions
|
||||
{:title "Dimensions"
|
||||
:attributes #{:width :height}
|
||||
:all-attributes (set/union
|
||||
ctt/spacing-keys
|
||||
ctt/sizing-keys
|
||||
ctt/border-radius-keys
|
||||
ctt/stroke-width-keys)
|
||||
:on-update-shape update-shape-dimensions
|
||||
:modal {:key :tokens/dimensions
|
||||
:fields [{:label "Dimensions"
|
||||
:key :dimensions}]}}
|
||||
|
||||
:opacity
|
||||
{:title "Opacity"
|
||||
:attributes ctt/opacity-keys
|
||||
:on-update-shape update-opacity
|
||||
:modal {:key :tokens/opacity
|
||||
:fields [{:label "Opacity"
|
||||
:key :opacity}]}}
|
||||
|
||||
:rotation
|
||||
{:title "Rotation"
|
||||
:attributes ctt/rotation-keys
|
||||
:on-update-shape update-rotation
|
||||
:modal {:key :tokens/rotation
|
||||
:fields [{:label "Rotation"
|
||||
:key :rotation}]}}
|
||||
:spacing
|
||||
{:title "Spacing"
|
||||
:attributes #{:column-gap :row-gap}
|
||||
:all-attributes ctt/spacing-keys
|
||||
:on-update-shape update-layout-spacing
|
||||
:modal {:key :tokens/spacing
|
||||
:fields [{:label "Spacing"
|
||||
:key :spacing}]}}))
|
||||
|
||||
(defn get-token-properties [token]
|
||||
(get token-properties (:type token)))
|
||||
|
||||
(defn token-attributes [token-type]
|
||||
(dm/get-in token-properties [token-type :attributes]))
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.timers :as timers]
|
||||
|
@ -38,7 +37,7 @@
|
|||
|
||||
(defn generic-attribute-actions [attributes title {:keys [token selected-shapes on-update-shape]}]
|
||||
(let [on-update-shape-fn (or on-update-shape
|
||||
(-> (wtty/get-token-properties token)
|
||||
(-> (wtch/get-token-properties token)
|
||||
(:on-update-shape)))
|
||||
{:keys [selected-pred shape-ids]} (attribute-actions token selected-shapes attributes)]
|
||||
(map (fn [attribute]
|
||||
|
@ -236,7 +235,7 @@
|
|||
(generic-attribute-actions #{:y} "Y" (assoc context-data :on-update-shape wtch/update-shape-position))))}))
|
||||
|
||||
(defn default-actions [{:keys [token selected-token-set-name]}]
|
||||
(let [{:keys [modal]} (wtty/get-token-properties token)]
|
||||
(let [{:keys [modal]} (wtch/get-token-properties token)]
|
||||
[{:title (tr "workspace.token.edit")
|
||||
:no-selectable true
|
||||
:action (fn [event]
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
[app.main.ui.notifications.context-notification :refer [context-notification]]
|
||||
[app.main.ui.workspace.colorpicker :as colorpicker]
|
||||
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.components.controls.input-token-color-bullet :refer [input-token-color-bullet*]]
|
||||
[app.main.ui.workspace.tokens.components.controls.input-tokens :refer [input-tokens*]]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.main.ui.workspace.tokens.warnings :as wtw]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -223,7 +223,7 @@
|
|||
[{:keys [token token-type action selected-token-set-name on-display-colorpicker]}]
|
||||
(let [create? (not (instance? ctob/Token token))
|
||||
token (or token {:type token-type})
|
||||
token-properties (wtty/get-token-properties token)
|
||||
token-properties (wtch/get-token-properties token)
|
||||
color? (wtt/color-token? token)
|
||||
selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens)
|
||||
active-theme-tokens (mf/deref refs/workspace-active-theme-sets-tokens)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
|
@ -18,6 +19,7 @@
|
|||
[app.main.ui.components.dropdown-menu :refer [dropdown-menu
|
||||
dropdown-menu-item*]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||
|
@ -32,9 +34,8 @@
|
|||
[app.main.ui.workspace.tokens.sets-context-menu :refer [sets-context-menu]]
|
||||
[app.main.ui.workspace.tokens.style-dictionary :as sd]
|
||||
[app.main.ui.workspace.tokens.theme-select :refer [theme-select]]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.token-pill :refer [token-pill]]
|
||||
[app.main.ui.workspace.tokens.token-types :as wtty]
|
||||
[app.main.ui.workspace.tokens.token-pill :refer [token-pill*]]
|
||||
[app.util.array :as array]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.webapi :as wapi]
|
||||
|
@ -44,8 +45,8 @@
|
|||
[rumext.v2 :as mf]
|
||||
[shadow.resource]))
|
||||
|
||||
(def lens:token-type-open-status
|
||||
(l/derived (l/in [:workspace-tokens :open-status]) st/state))
|
||||
(def ref:token-type-open-status
|
||||
(l/derived #(dm/get-in % [:workspace-local :token-type-open-status]) st/state))
|
||||
|
||||
;; Components ------------------------------------------------------------------
|
||||
|
||||
|
@ -65,62 +66,64 @@
|
|||
:sizing "expand"
|
||||
"add"))
|
||||
|
||||
(defn attribute-actions [token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} (map :id selected-shapes))]
|
||||
{:all-selected? (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)
|
||||
:shape-ids shape-ids
|
||||
:selected-pred #(seq (% ids-by-attributes))}))
|
||||
(mf/defc token-group*
|
||||
{::mf/private true}
|
||||
[{:keys [type tokens selected-shapes active-theme-tokens is-open]}]
|
||||
(let [{:keys [modal title]}
|
||||
(get wtch/token-properties type)
|
||||
|
||||
(mf/defc token-component
|
||||
[{:keys [type tokens selected-shapes token-type-props active-theme-tokens]}]
|
||||
(let [open? (mf/deref (-> (l/key type)
|
||||
(l/derived lens:token-type-open-status)))
|
||||
{:keys [modal attributes all-attributes title]} token-type-props
|
||||
tokens
|
||||
(mf/with-memo [tokens]
|
||||
(vec (sort-by :name tokens)))
|
||||
|
||||
on-context-menu (mf/use-fn
|
||||
(fn [event token]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/show-token-context-menu
|
||||
{:type :token
|
||||
:position (dom/get-client-position event)
|
||||
:errors (:errors token)
|
||||
:token-name (:name token)}))))
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(fn [event token]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/show-token-context-menu
|
||||
{:type :token
|
||||
:position (dom/get-client-position event)
|
||||
:errors (:errors token)
|
||||
:token-name (:name token)}))))
|
||||
|
||||
on-toggle-open-click (mf/use-fn
|
||||
(mf/deps open? tokens)
|
||||
#(st/emit! (dt/set-token-type-section-open type (not open?))))
|
||||
on-popover-open-click (mf/use-fn
|
||||
(fn [event]
|
||||
(mf/deps type title)
|
||||
(let [{:keys [key fields]} modal]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/set-token-type-section-open type true))
|
||||
(modal/show! key {:x (.-clientX ^js event)
|
||||
:y (.-clientY ^js event)
|
||||
:position :right
|
||||
:fields fields
|
||||
:title title
|
||||
:action "create"
|
||||
:token-type type}))))
|
||||
on-toggle-open-click
|
||||
(mf/use-fn
|
||||
(mf/deps is-open type)
|
||||
#(st/emit! (dt/set-token-type-section-open type (not is-open))))
|
||||
|
||||
on-token-pill-click (mf/use-fn
|
||||
(mf/deps selected-shapes token-type-props)
|
||||
(fn [event token]
|
||||
(dom/stop-propagation event)
|
||||
(when (seq selected-shapes)
|
||||
(st/emit!
|
||||
(wtch/toggle-token {:token token
|
||||
:shapes selected-shapes
|
||||
:token-type-props token-type-props})))))
|
||||
on-popover-open-click
|
||||
(mf/use-fn
|
||||
(mf/deps type title modal)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dt/set-token-type-section-open type true)
|
||||
;; FIXME: use dom/get-client-position
|
||||
(modal/show (:key modal)
|
||||
{:x (.-clientX ^js event)
|
||||
:y (.-clientY ^js event)
|
||||
:position :right
|
||||
:fields (:fields modal)
|
||||
:title title
|
||||
:action "create"
|
||||
:token-type type}))))
|
||||
|
||||
on-token-pill-click
|
||||
(mf/use-fn
|
||||
(mf/deps selected-shapes)
|
||||
(fn [event token]
|
||||
(dom/stop-propagation event)
|
||||
(when (seq selected-shapes)
|
||||
(st/emit! (wtch/toggle-token {:token token
|
||||
:shapes selected-shapes})))))
|
||||
tokens-count (count tokens)
|
||||
can-edit? (:can-edit (deref refs/permissions))]
|
||||
|
||||
[:div {:on-click on-toggle-open-click}
|
||||
[:& cmm/asset-section {:icon (token-section-icon type)
|
||||
:title title
|
||||
:assets-count tokens-count
|
||||
:open? open?}
|
||||
:open? is-open}
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when can-edit?
|
||||
[:> icon-button* {:on-click on-popover-open-click
|
||||
|
@ -128,56 +131,55 @@
|
|||
:icon "add"
|
||||
;; TODO: This needs translation
|
||||
:aria-label (str "Add token: " title)}])]
|
||||
(when open?
|
||||
(when is-open
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:div {:class (stl/css :token-pills-wrapper)}
|
||||
(for [token (sort-by :name tokens)]
|
||||
(let [theme-token (get active-theme-tokens (wtt/token-identifier token))
|
||||
multiple-selection (< 1 (count selected-shapes))
|
||||
full-applied (:all-selected? (attribute-actions token selected-shapes (or all-attributes attributes)))
|
||||
applied (wtt/shapes-token-applied? token selected-shapes (or all-attributes attributes))
|
||||
on-token-click (fn [e]
|
||||
(on-token-pill-click e token))
|
||||
on-context-menu (fn [e] (on-context-menu e token))]
|
||||
[:& token-pill
|
||||
{:key (:name token)
|
||||
:token-type-props token-type-props
|
||||
:token token
|
||||
:selected-shapes selected-shapes
|
||||
:active-theme-tokens active-theme-tokens
|
||||
:theme-token theme-token
|
||||
:half-applied (or (and applied multiple-selection)
|
||||
(and applied (not full-applied)))
|
||||
:full-applied (if multiple-selection
|
||||
false
|
||||
applied)
|
||||
:on-click on-token-click
|
||||
:on-context-menu on-context-menu}]))]])]]))
|
||||
(for [token tokens]
|
||||
[:> token-pill*
|
||||
{:key (:name token)
|
||||
:token token
|
||||
:selected-shapes selected-shapes
|
||||
:active-theme-tokens active-theme-tokens
|
||||
:on-click on-token-pill-click
|
||||
:on-context-menu on-context-menu}])]])]]))
|
||||
|
||||
(defn sorted-token-groups
|
||||
"Separate token-types into groups of `:empty` or `:filled` depending if tokens exist for that type.
|
||||
Sort each group alphabetically (by their `:token-key`)."
|
||||
[tokens]
|
||||
(let [tokens-by-type (ctob/group-by-type tokens)
|
||||
{:keys [empty filled]} (->> wtty/token-types
|
||||
(map (fn [[token-key token-type-props]]
|
||||
{:token-key token-key
|
||||
:token-type-props token-type-props
|
||||
:tokens (get tokens-by-type token-key [])}))
|
||||
(group-by (fn [{:keys [tokens]}]
|
||||
(if (empty? tokens) :empty :filled))))]
|
||||
{:empty (sort-by :token-key empty)
|
||||
:filled (sort-by :token-key filled)}))
|
||||
(defn- get-sorted-token-groups
|
||||
"Separate token-types into groups of `empty` or `filled` depending if
|
||||
tokens exist for that type. Sort each group alphabetically (by
|
||||
their type)."
|
||||
[tokens-by-type]
|
||||
(loop [empty #js []
|
||||
filled #js []
|
||||
types (-> wtch/token-properties keys seq)]
|
||||
(if-let [type (first types)]
|
||||
(if (not-empty (get tokens-by-type type))
|
||||
(recur empty
|
||||
(array/conj! filled type)
|
||||
(rest types))
|
||||
(recur (array/conj! empty type)
|
||||
filled
|
||||
(rest types)))
|
||||
[(seq (array/sort! empty))
|
||||
(seq (array/sort! filled))])))
|
||||
|
||||
(mf/defc themes-header*
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [ordered-themes
|
||||
(mf/deref refs/workspace-token-themes-no-hidden)
|
||||
|
||||
permissions
|
||||
(mf/use-ctx ctx/permissions)
|
||||
|
||||
can-edit?
|
||||
(get permissions :can-edit)
|
||||
|
||||
(mf/defc themes-header
|
||||
[_props]
|
||||
(let [ordered-themes (mf/deref refs/workspace-token-themes-no-hidden)
|
||||
can-edit? (:can-edit (deref refs/permissions))
|
||||
open-modal
|
||||
(mf/use-fn
|
||||
(fn [e]
|
||||
(dom/stop-propagation e)
|
||||
(modal/show! :tokens/themes {})))]
|
||||
|
||||
[:div {:class (stl/css :themes-wrapper)}
|
||||
[:span {:class (stl/css :themes-header)} (tr "labels.themes")]
|
||||
(if (empty? ordered-themes)
|
||||
|
@ -199,13 +201,24 @@
|
|||
(tr "workspace.token.no-permission-themes"))}
|
||||
[:& theme-select]]))]))
|
||||
|
||||
(mf/defc add-set-button
|
||||
[{:keys [on-open style]}]
|
||||
(let [{:keys [on-create new-path]} (sets-context/use-context)
|
||||
on-click #(do
|
||||
(on-open)
|
||||
(on-create []))
|
||||
can-edit? (:can-edit (deref refs/permissions))]
|
||||
(mf/defc add-set-button*
|
||||
{::mf/private true}
|
||||
[{:keys [style]}]
|
||||
(let [{:keys [on-create new-path]}
|
||||
(sets-context/use-context)
|
||||
|
||||
permissions
|
||||
(mf/use-ctx ctx/permissions)
|
||||
|
||||
can-edit?
|
||||
(get permissions :can-edit)
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps on-create)
|
||||
(fn []
|
||||
(on-create [])))]
|
||||
|
||||
(if (= style "inline")
|
||||
(when-not new-path
|
||||
(if can-edit?
|
||||
|
@ -224,67 +237,96 @@
|
|||
:on-click on-click
|
||||
:aria-label (tr "workspace.token.add set")}]))))
|
||||
|
||||
(mf/defc theme-sets-list
|
||||
[{:keys [on-open]}]
|
||||
(mf/defc theme-sets-list*
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [token-sets (mf/deref refs/workspace-ordered-token-sets)
|
||||
{:keys [new-path] :as ctx} (sets-context/use-context)]
|
||||
(if (and (empty? token-sets)
|
||||
(not new-path))
|
||||
[:& add-set-button {:on-open on-open
|
||||
:style "inline"}]
|
||||
[:> add-set-button* {:style "inline"}]
|
||||
[:& h/sortable-container {}
|
||||
[:& sets-list]])))
|
||||
|
||||
(mf/defc themes-sets-tab
|
||||
(mf/defc themes-sets-tab*
|
||||
{::mf/private true}
|
||||
[{:keys [resize-height]}]
|
||||
(let [open? (mf/use-state true)
|
||||
on-open (mf/use-fn #(reset! open? true))
|
||||
can-edit? (:can-edit (deref refs/permissions))]
|
||||
(let [permissions
|
||||
(mf/use-ctx ctx/permissions)
|
||||
|
||||
can-edit?
|
||||
(get permissions :can-edit)]
|
||||
|
||||
[:& sets-context/provider {}
|
||||
[:& sets-context-menu]
|
||||
[:article {:data-testid "token-themes-sets-sidebar"
|
||||
:class (stl/css :sets-section-wrapper)
|
||||
:style {"--resize-height" (str resize-height "px")}}
|
||||
[:div {:class (stl/css :sets-sidebar)}
|
||||
[:& themes-header]
|
||||
[:> themes-header*]
|
||||
[:div {:class (stl/css :sidebar-header)}
|
||||
[:& title-bar {:title (tr "labels.sets")}
|
||||
(when can-edit?
|
||||
[:& add-set-button {:on-open on-open
|
||||
:style "header"}])]]
|
||||
[:& theme-sets-list {:on-open on-open}]]]]))
|
||||
[:> add-set-button* {:style "header"}])]]
|
||||
|
||||
(mf/defc tokens-tab
|
||||
[_props]
|
||||
(let [objects (mf/deref refs/workspace-page-objects)
|
||||
[:> theme-sets-list* {}]]]]))
|
||||
|
||||
selected (mf/deref refs/selected-shapes)
|
||||
selected-shapes (into [] (keep (d/getf objects)) selected)
|
||||
(mf/defc tokens-tab*
|
||||
[]
|
||||
(let [objects (mf/deref refs/workspace-page-objects)
|
||||
selected (mf/deref refs/selected-shapes)
|
||||
open-status (mf/deref ref:token-type-open-status)
|
||||
|
||||
active-theme-tokens (sd/use-active-theme-sets-tokens)
|
||||
selected-shapes
|
||||
(mf/with-memo [selected objects]
|
||||
(into [] (keep (d/getf objects)) selected))
|
||||
|
||||
tokens (sd/use-resolved-workspace-tokens)
|
||||
active-theme-tokens
|
||||
(sd/use-active-theme-tokens)
|
||||
|
||||
selected-token-set-tokens (mf/deref refs/workspace-selected-token-set-tokens)
|
||||
tokens
|
||||
(sd/use-resolved-workspace-tokens)
|
||||
|
||||
selected-token-set-name (mf/deref refs/workspace-selected-token-set-name)
|
||||
selected-token-set-tokens
|
||||
(mf/deref refs/workspace-selected-token-set-tokens)
|
||||
|
||||
selected-token-set-name
|
||||
(mf/deref refs/workspace-selected-token-set-name)
|
||||
|
||||
tokens-by-type
|
||||
(mf/with-memo [tokens selected-token-set-tokens]
|
||||
(let [tokens (reduce-kv (fn [tokens k _]
|
||||
(if (contains? selected-token-set-tokens k)
|
||||
tokens
|
||||
(dissoc tokens k)))
|
||||
tokens
|
||||
tokens)]
|
||||
(ctob/group-by-type tokens)))
|
||||
|
||||
[empty-group filled-group]
|
||||
(mf/with-memo [tokens-by-type]
|
||||
(get-sorted-token-groups tokens-by-type))]
|
||||
|
||||
token-groups (mf/with-memo [tokens selected-token-set-tokens]
|
||||
(-> (select-keys tokens (keys selected-token-set-tokens))
|
||||
(sorted-token-groups)))]
|
||||
[:*
|
||||
[:& token-context-menu]
|
||||
[:& title-bar {:all-clickable true
|
||||
:title (tr "workspace.token.tokens-section-title" selected-token-set-name)}]
|
||||
|
||||
(for [{:keys [token-key token-type-props tokens]} (concat (:filled token-groups)
|
||||
(:empty token-groups))]
|
||||
[:& token-component {:key token-key
|
||||
:type token-key
|
||||
:selected-shapes selected-shapes
|
||||
:active-theme-tokens active-theme-tokens
|
||||
:tokens tokens
|
||||
:token-type-props token-type-props}])]))
|
||||
(for [type filled-group]
|
||||
(let [tokens (get tokens-by-type type)]
|
||||
[:> token-group* {:key (name type)
|
||||
:is-open (get open-status type false)
|
||||
:type type
|
||||
:selected-shapes selected-shapes
|
||||
:active-theme-tokens active-theme-tokens
|
||||
:tokens tokens}]))
|
||||
|
||||
(for [type empty-group]
|
||||
[:> token-group* {:key (name type)
|
||||
:type type
|
||||
:selected-shapes selected-shapes
|
||||
:active-theme-tokens active-theme-tokens
|
||||
:tokens []}])]))
|
||||
|
||||
(mf/defc import-export-button
|
||||
{::mf/wrap-props false}
|
||||
|
@ -357,22 +399,21 @@
|
|||
:on-click on-export}
|
||||
(tr "labels.export")]]]))
|
||||
|
||||
(mf/defc tokens-sidebar-tab
|
||||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
[_props]
|
||||
(mf/defc tokens-sidebar-tab*
|
||||
{::mf/wrap [mf/memo]}
|
||||
[]
|
||||
(let [{on-pointer-down-pages :on-pointer-down
|
||||
on-lost-pointer-capture-pages :on-lost-pointer-capture
|
||||
on-pointer-move-pages :on-pointer-move
|
||||
size-pages-opened :size}
|
||||
(use-resize-hook :tokens 200 38 "0.6" :y false nil)]
|
||||
[:div {:class (stl/css :sidebar-wrapper)}
|
||||
[:& themes-sets-tab {:resize-height size-pages-opened}]
|
||||
[:> themes-sets-tab* {:resize-height size-pages-opened}]
|
||||
[:article {:class (stl/css :tokens-section-wrapper)
|
||||
:data-testid "tokens-sidebar"}
|
||||
[:div {:class (stl/css :resize-area-horiz)
|
||||
:on-pointer-down on-pointer-down-pages
|
||||
:on-lost-pointer-capture on-lost-pointer-capture-pages
|
||||
:on-pointer-move on-pointer-move-pages}]
|
||||
[:& tokens-tab]]
|
||||
[:> tokens-tab*]]
|
||||
[:& import-export-button]]))
|
||||
|
|
|
@ -295,6 +295,8 @@
|
|||
prefer-selected-token-set-tokens (merge active-theme-tokens selected-token-set-tokens)]
|
||||
(use-resolved-tokens prefer-selected-token-set-tokens)))
|
||||
|
||||
(defn use-active-theme-sets-tokens []
|
||||
(defn use-active-theme-tokens
|
||||
"A hook that returns active tokens for the current active theme"
|
||||
[]
|
||||
(-> (mf/deref refs/workspace-active-theme-sets-tokens)
|
||||
(use-resolved-tokens {:cache-atom !theme-tokens-cache})))
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
is-open? (:is-open? state)
|
||||
|
||||
;; Dropdown
|
||||
dropdown-element* (mf/use-ref nil)
|
||||
on-close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false))
|
||||
|
||||
on-open-dropdown
|
||||
|
@ -118,8 +117,7 @@
|
|||
current-label]
|
||||
[:> icon* {:icon-id i/arrow-down :class (stl/css :dropdown-button) :aria-hidden true}]
|
||||
[:& dropdown {:show is-open?
|
||||
:on-close on-close-dropdown
|
||||
:ref dropdown-element*}
|
||||
:on-close on-close-dropdown}
|
||||
[:& theme-options {:active-theme-paths active-theme-paths
|
||||
:themes themes
|
||||
:on-close on-close-dropdown}]]]))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns app.main.ui.workspace.tokens.token
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
|
@ -21,7 +22,9 @@
|
|||
{:value parsed-value
|
||||
:unit unit}))))
|
||||
|
||||
(defn token-identifier [{:keys [name] :as _token}]
|
||||
;; FIXME: looks very redundant function
|
||||
(defn token-identifier
|
||||
[{:keys [name] :as _token}]
|
||||
name)
|
||||
|
||||
(defn attributes-map
|
||||
|
@ -43,7 +46,7 @@
|
|||
(defn token-attribute-applied?
|
||||
"Test if `token` is applied to a `shape` on single `token-attribute`."
|
||||
[token shape token-attribute]
|
||||
(when-let [id (get-in shape [:applied-tokens token-attribute])]
|
||||
(when-let [id (dm/get-in shape [:applied-tokens token-attribute])]
|
||||
(= (token-identifier token) id)))
|
||||
|
||||
(defn token-applied?
|
||||
|
@ -56,15 +59,18 @@
|
|||
[token shapes token-attributes]
|
||||
(some #(token-applied? token % token-attributes) shapes))
|
||||
|
||||
(defn shapes-ids-by-applied-attributes [token shapes token-attributes]
|
||||
(reduce (fn [acc shape]
|
||||
(let [applied-ids-by-attribute (->> (map #(when (token-attribute-applied? token shape %)
|
||||
[% #{(:id shape)}])
|
||||
token-attributes)
|
||||
(filter some?)
|
||||
(into {}))]
|
||||
(merge-with into acc applied-ids-by-attribute)))
|
||||
{} shapes))
|
||||
(defn shapes-ids-by-applied-attributes
|
||||
[token shapes token-attributes]
|
||||
(let [conj* (fnil conj #{})]
|
||||
(reduce (fn [result shape]
|
||||
(let [shape-id (dm/get-prop shape :id)]
|
||||
(->> token-attributes
|
||||
(filter #(token-attribute-applied? token shape %))
|
||||
(reduce (fn [result attr]
|
||||
(update result attr conj* shape-id))
|
||||
result))))
|
||||
{}
|
||||
shapes)))
|
||||
|
||||
(defn shapes-applied-all? [ids-by-attributes shape-ids attributes]
|
||||
(every? #(set/superset? (get ids-by-attributes %) shape-ids) attributes))
|
||||
|
@ -122,6 +128,11 @@
|
|||
(defn color-token? [token]
|
||||
(= (:type token) :color))
|
||||
|
||||
|
||||
;; FIXME: this should be precalculated ?
|
||||
(defn is-reference? [token]
|
||||
(str/includes? (:value token) "{"))
|
||||
|
||||
(defn color-bullet-color [token-color-value]
|
||||
(when-let [tc (tinycolor/valid-color token-color-value)]
|
||||
(if (tinycolor/alpha tc)
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
;; 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.token-pill
|
||||
(:require-macros
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
|
@ -75,9 +82,8 @@
|
|||
;; Helper functions
|
||||
(defn partially-applied-attr
|
||||
"Translates partially applied attributes based on the dictionary."
|
||||
[app-token-keys is-applied token-type-props]
|
||||
(let [{:keys [attributes all-attributes]} token-type-props
|
||||
filtered-keys (if all-attributes
|
||||
[app-token-keys is-applied {:keys [attributes all-attributes]}]
|
||||
(let [filtered-keys (if all-attributes
|
||||
(filter #(contains? all-attributes %) app-token-keys)
|
||||
(filter #(contains? attributes %) app-token-keys))]
|
||||
(when is-applied
|
||||
|
@ -94,11 +100,11 @@
|
|||
(str/join ", " (map attribute-dictionary values)) ".")))
|
||||
grouped-values)))
|
||||
|
||||
(defn token-pill-tooltip
|
||||
"Generates a tooltip for a given token."
|
||||
[is-viewer shape token-type-props token half-applied no-valid-value ref-not-in-active-set]
|
||||
(defn- generate-tooltip
|
||||
"Generates a tooltip for a given token"
|
||||
[is-viewer shape token half-applied no-valid-value ref-not-in-active-set]
|
||||
(let [{:keys [name value resolved-value type]} token
|
||||
{:keys [title]} token-type-props
|
||||
{:keys [title] :as token-props} (wtch/get-token-properties token)
|
||||
applied-tokens (:applied-tokens shape)
|
||||
app-token-vals (set (vals applied-tokens))
|
||||
app-token-keys (keys applied-tokens)
|
||||
|
@ -106,7 +112,7 @@
|
|||
|
||||
|
||||
applied-to (if half-applied
|
||||
(partially-applied-attr app-token-keys is-applied? token-type-props)
|
||||
(partially-applied-attr app-token-keys is-applied? token-props)
|
||||
(tr "labels.all"))
|
||||
grouped-values (group-by dimensions-dictionary app-token-keys)
|
||||
|
||||
|
@ -134,54 +140,94 @@
|
|||
;; Otherwise only show the base title
|
||||
:else base-title)))
|
||||
|
||||
;; FIXME: the token thould already have precalculated references, so
|
||||
;; we don't need to perform this regex operation on each rerender
|
||||
(defn contains-reference-value?
|
||||
"Extracts the value between `{}` in a string and checks if it's in the provided vector."
|
||||
[text values]
|
||||
[text active-tokens]
|
||||
(let [match (second (re-find #"\{([^}]+)\}" text))]
|
||||
(boolean (some #(= % match) values))))
|
||||
(contains? active-tokens match)))
|
||||
|
||||
(mf/defc token-pill
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-click token theme-token full-applied on-context-menu half-applied selected-shapes token-type-props active-theme-tokens]}]
|
||||
(def ^:private
|
||||
xf:map-id
|
||||
(map :id))
|
||||
|
||||
(defn- applied-all-attributes?
|
||||
[token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} xf:map-id selected-shapes)]
|
||||
(wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)))
|
||||
|
||||
(mf/defc token-pill*
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [on-click token on-context-menu selected-shapes active-theme-tokens]}]
|
||||
(let [{:keys [name value errors]} token
|
||||
is-reference (some #(= % "{") value)
|
||||
|
||||
has-selected? (pos? (count selected-shapes))
|
||||
is-reference? (wtt/is-reference? token)
|
||||
contains-path? (str/includes? name ".")
|
||||
|
||||
{:keys [attributes all-attributes]}
|
||||
(get wtch/token-properties (:type token))
|
||||
|
||||
full-applied?
|
||||
(if has-selected?
|
||||
(applied-all-attributes? token selected-shapes (d/nilv all-attributes attributes))
|
||||
true)
|
||||
|
||||
applied?
|
||||
(if has-selected?
|
||||
(wtt/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes))
|
||||
false)
|
||||
|
||||
half-applied?
|
||||
(and applied? (not full-applied?))
|
||||
|
||||
;; FIXME: move to context or props
|
||||
can-edit? (:can-edit (deref refs/permissions))
|
||||
|
||||
is-viewer (not can-edit?)
|
||||
ref-not-in-active-set (and is-reference
|
||||
(not (contains-reference-value? value (keys active-theme-tokens))))
|
||||
is-viewer? (not can-edit?)
|
||||
|
||||
ref-not-in-active-set
|
||||
(and is-reference?
|
||||
(not (contains-reference-value? value active-theme-tokens)))
|
||||
|
||||
no-valid-value (seq errors)
|
||||
errors? (or ref-not-in-active-set
|
||||
no-valid-value)
|
||||
color (when (seq (ctob/find-token-value-references value))
|
||||
(wtt/resolved-token-bullet-color theme-token))
|
||||
contains-path? (str/includes? name ".")
|
||||
splitted-name (cfh/split-by-last-period name)
|
||||
color (or color (wtt/resolved-token-bullet-color token))
|
||||
|
||||
errors?
|
||||
(or ref-not-in-active-set
|
||||
no-valid-value)
|
||||
|
||||
color
|
||||
(when (wtt/color-token? token)
|
||||
(let [theme-token (get active-theme-tokens (:name token))]
|
||||
(or (wtt/resolved-token-bullet-color theme-token)
|
||||
(wtt/resolved-token-bullet-color token))))
|
||||
|
||||
on-click
|
||||
(mf/use-callback
|
||||
(mf/deps errors? on-click)
|
||||
(mf/use-fn
|
||||
(mf/deps errors? on-click token)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(when (and (not (seq errors)) on-click)
|
||||
(on-click event))))
|
||||
(on-click event token))))
|
||||
|
||||
token-status-id (cond
|
||||
half-applied
|
||||
"token-status-partial"
|
||||
full-applied
|
||||
"token-status-full"
|
||||
:else
|
||||
"token-status-non-applied")
|
||||
token-status-id
|
||||
(cond
|
||||
half-applied?
|
||||
"token-status-partial"
|
||||
full-applied?
|
||||
"token-status-full"
|
||||
:else
|
||||
"token-status-non-applied")
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps can-edit? on-context-menu)
|
||||
(mf/deps can-edit? on-context-menu token)
|
||||
(fn [e]
|
||||
(dom/stop-propagation e)
|
||||
(when can-edit?
|
||||
(on-context-menu e))))
|
||||
(on-context-menu e token))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
|
@ -191,26 +237,29 @@
|
|||
(when (and can-edit? (not (seq errors)) on-click)
|
||||
(on-click event))))
|
||||
|
||||
;; FIXME: missing deps
|
||||
on-hover
|
||||
(mf/use-fn
|
||||
(mf/deps selected-shapes is-viewer)
|
||||
(mf/deps selected-shapes is-viewer?)
|
||||
(fn [event]
|
||||
(let [node (dom/get-current-target event)
|
||||
title (token-pill-tooltip is-viewer (first selected-shapes) token-type-props token half-applied no-valid-value ref-not-in-active-set)]
|
||||
(let [node (dom/get-current-target event)
|
||||
title (generate-tooltip is-viewer? (first selected-shapes) token
|
||||
half-applied? no-valid-value ref-not-in-active-set)]
|
||||
(dom/set-attribute! node "title" title))))]
|
||||
|
||||
[:button {:class (stl/css-case :token-pill true
|
||||
:token-pill-default can-edit?
|
||||
:token-pill-applied (and can-edit? (or half-applied full-applied))
|
||||
:token-pill-invalid (and can-edit? errors?)
|
||||
:token-pill-invalid-applied (and full-applied errors? can-edit?)
|
||||
:token-pill-viewer is-viewer
|
||||
:token-pill-applied-viewer (and is-viewer
|
||||
(or half-applied full-applied))
|
||||
:token-pill-invalid-viewer (and is-viewer
|
||||
errors?)
|
||||
:token-pill-invalid-applied-viewer (and is-viewer
|
||||
(and full-applied errors?)))
|
||||
[:button {:class (stl/css-case
|
||||
:token-pill true
|
||||
:token-pill-default can-edit?
|
||||
:token-pill-applied (and can-edit? has-selected? (or half-applied? full-applied?))
|
||||
:token-pill-invalid (and can-edit? errors?)
|
||||
:token-pill-invalid-applied (and full-applied? errors? can-edit?)
|
||||
:token-pill-viewer is-viewer?
|
||||
:token-pill-applied-viewer (and is-viewer? has-selected?
|
||||
(or half-applied? full-applied?))
|
||||
:token-pill-invalid-viewer (and is-viewer?
|
||||
errors?)
|
||||
:token-pill-invalid-applied-viewer (and is-viewer?
|
||||
(and full-applied? errors?)))
|
||||
:type "button"
|
||||
:on-click on-click
|
||||
:on-mouse-enter on-hover
|
||||
|
@ -220,6 +269,7 @@
|
|||
[:> icon*
|
||||
{:icon-id "broken-link"
|
||||
:class (stl/css :token-pill-icon)}]
|
||||
|
||||
color
|
||||
[:& color-bullet {:color color
|
||||
:mini true}]
|
||||
|
@ -227,13 +277,13 @@
|
|||
[:> token-status-icon*
|
||||
{:icon-id token-status-id
|
||||
:class (stl/css :token-pill-icon)}])
|
||||
|
||||
(if contains-path?
|
||||
[:span {:class (stl/css :divided-name-wrapper)
|
||||
:aria-label name}
|
||||
[:span {:class (stl/css :first-name-wrapper)}
|
||||
(first splitted-name)]
|
||||
[:span {:class (stl/css :last-name-wrapper)}
|
||||
(last splitted-name)]]
|
||||
(let [[first-part last-part] (cfh/split-by-last-period name)]
|
||||
[:span {:class (stl/css :divided-name-wrapper)
|
||||
:aria-label name}
|
||||
[:span {:class (stl/css :first-name-wrapper)} first-part]
|
||||
[:span {:class (stl/css :last-name-wrapper)} last-part]])
|
||||
[:span {:class (stl/css :name-wrapper)
|
||||
:aria-label name}
|
||||
name])]))
|
||||
name])]))
|
||||
|
|
|
@ -1,89 +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
|
||||
|
||||
(ns app.main.ui.workspace.tokens.token-types
|
||||
(:require
|
||||
[app.common.data :as d :refer [ordered-map]]
|
||||
[app.common.types.token :as ctt]
|
||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||
[clojure.set :as set]))
|
||||
|
||||
(def token-types
|
||||
(ordered-map
|
||||
:border-radius
|
||||
{:title "Border Radius"
|
||||
:attributes ctt/border-radius-keys
|
||||
:on-update-shape wtch/update-shape-radius-all
|
||||
:modal {:key :tokens/border-radius
|
||||
:fields [{:label "Border Radius"
|
||||
:key :border-radius}]}}
|
||||
|
||||
:color
|
||||
{:title "Color"
|
||||
:attributes #{:fill}
|
||||
:all-attributes ctt/color-keys
|
||||
:on-update-shape wtch/update-fill-stroke
|
||||
:modal {:key :tokens/color
|
||||
:fields [{:label "Color" :key :color}]}}
|
||||
|
||||
:stroke-width
|
||||
{:title "Stroke Width"
|
||||
:attributes ctt/stroke-width-keys
|
||||
:on-update-shape wtch/update-stroke-width
|
||||
:modal {:key :tokens/stroke-width
|
||||
:fields [{:label "Stroke Width"
|
||||
:key :stroke-width}]}}
|
||||
|
||||
:sizing
|
||||
{:title "Sizing"
|
||||
:attributes #{:width :height}
|
||||
:all-attributes ctt/sizing-keys
|
||||
:on-update-shape wtch/update-shape-dimensions
|
||||
:modal {:key :tokens/sizing
|
||||
:fields [{:label "Sizing"
|
||||
:key :sizing}]}}
|
||||
:dimensions
|
||||
{:title "Dimensions"
|
||||
:attributes #{:width :height}
|
||||
:all-attributes (set/union
|
||||
ctt/spacing-keys
|
||||
ctt/sizing-keys
|
||||
ctt/border-radius-keys
|
||||
ctt/stroke-width-keys)
|
||||
:on-update-shape wtch/update-shape-dimensions
|
||||
:modal {:key :tokens/dimensions
|
||||
:fields [{:label "Dimensions"
|
||||
:key :dimensions}]}}
|
||||
|
||||
:opacity
|
||||
{:title "Opacity"
|
||||
:attributes ctt/opacity-keys
|
||||
:on-update-shape wtch/update-opacity
|
||||
:modal {:key :tokens/opacity
|
||||
:fields [{:label "Opacity"
|
||||
:key :opacity}]}}
|
||||
|
||||
:rotation
|
||||
{:title "Rotation"
|
||||
:attributes ctt/rotation-keys
|
||||
:on-update-shape wtch/update-rotation
|
||||
:modal {:key :tokens/rotation
|
||||
:fields [{:label "Rotation"
|
||||
:key :rotation}]}}
|
||||
:spacing
|
||||
{:title "Spacing"
|
||||
:attributes #{:column-gap :row-gap}
|
||||
:all-attributes ctt/spacing-keys
|
||||
:on-update-shape wtch/update-layout-spacing
|
||||
:modal {:key :tokens/spacing
|
||||
:fields [{:label "Spacing"
|
||||
:key :spacing}]}}))
|
||||
|
||||
(defn get-token-properties [token]
|
||||
(get token-types (:type token)))
|
||||
|
||||
(defn token-attributes [token-type]
|
||||
(get-in token-types [token-type :attributes]))
|
|
@ -6,9 +6,10 @@
|
|||
|
||||
(ns app.util.array
|
||||
"A collection of helpers for work with javascript arrays."
|
||||
(:refer-clojure :exclude [conj! conj filter map reduce find])
|
||||
(:refer-clojure :exclude [conj! conj filter map reduce find sort])
|
||||
(:require
|
||||
[cljs.core :as c]))
|
||||
[cljs.core :as c]
|
||||
[goog.array :as garray]))
|
||||
|
||||
(defn conj
|
||||
"A conj like function for js arrays."
|
||||
|
@ -67,3 +68,9 @@
|
|||
(defn find
|
||||
[f v]
|
||||
(.find ^js/Array v f))
|
||||
|
||||
(defn sort!
|
||||
[a]
|
||||
(garray/sort a compare)
|
||||
a)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue