Update code to use design system icon (#7145)

This commit is contained in:
Xaviju
2025-08-22 14:27:11 +02:00
committed by GitHub
parent c0c2c9489c
commit ee86a3943d
12 changed files with 166 additions and 189 deletions

View File

@@ -42,19 +42,19 @@ const findVariant = async (workspacePage, num_variant) => {
const container = await workspacePage.layers const container = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Rectangle") }) .filter({ has: workspacePage.page.getByText("Rectangle") })
.filter({ has: workspacePage.page.locator(".icon-component") }) .filter({ has: workspacePage.page.getByTestId("icon-component") })
.nth(num_variant); .nth(num_variant);
const variant1 = await workspacePage.layers const variant1 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Value 1") }) .filter({ has: workspacePage.page.getByText("Value 1") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.nth(num_variant); .nth(num_variant);
const variant2 = await workspacePage.layers const variant2 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Value 2") }) .filter({ has: workspacePage.page.getByText("Value 2") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.nth(num_variant); .nth(num_variant);
return { return {
@@ -99,7 +99,7 @@ test("User creates a variant", async ({ page }) => {
const variants = await workspacePage.layers const variants = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.all(); .all();
// There are exactly two variants // There are exactly two variants
@@ -241,7 +241,7 @@ test("User copy paste a variant", async ({ page }) => {
const copy = await workspacePage.layers const copy = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Rectangle") }) .filter({ has: workspacePage.page.getByText("Rectangle") })
.filter({ has: workspacePage.page.locator(".icon-component-copy") }); .filter({ has: workspacePage.page.getByTestId("icon-component-copy") });
//The copy exists and is visible //The copy exists and is visible
await expect(copy).toBeVisible(); await expect(copy).toBeVisible();
@@ -266,7 +266,7 @@ test("User cut paste a variant outside the container", async ({ page }) => {
const component = await workspacePage.layers const component = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Rectangle / Value 1") }) .filter({ has: workspacePage.page.getByText("Rectangle / Value 1") })
.filter({ has: workspacePage.page.locator(".icon-component") }); .filter({ has: workspacePage.page.getByTestId("icon-component") });
//The component exists and is visible //The component exists and is visible
await expect(component).toBeVisible(); await expect(component).toBeVisible();
@@ -284,7 +284,7 @@ test("User drag and drop a variant outside the container", async ({ page }) => {
const component = await workspacePage.layers const component = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Rectangle / Value 1") }) .filter({ has: workspacePage.page.getByText("Rectangle / Value 1") })
.filter({ has: workspacePage.page.locator(".icon-component") }); .filter({ has: workspacePage.page.getByTestId("icon-component") });
//The component exists and is visible //The component exists and is visible
await expect(component).toBeVisible(); await expect(component).toBeVisible();
@@ -312,7 +312,7 @@ test("User cut paste a component inside a variant", async ({ page }) => {
const variant3 = await workspacePage.layers const variant3 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Ellipse") }) .filter({ has: workspacePage.page.getByText("Ellipse") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.first(); .first();
//The new variant exists and is visible //The new variant exists and is visible
@@ -351,7 +351,7 @@ test("User cut paste a component with path inside a variant", async ({
const variant3 = await workspacePage.layers const variant3 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("button, hover") }) .filter({ has: workspacePage.page.getByText("button, hover") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.first(); .first();
//The new variant exists and is visible //The new variant exists and is visible
@@ -386,7 +386,7 @@ test("User drag and drop a component with path inside a variant", async ({
const variant3 = await workspacePage.layers const variant3 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("button, hover") }) .filter({ has: workspacePage.page.getByText("button, hover") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.first(); .first();
//The new variant exists and is visible //The new variant exists and is visible
@@ -420,7 +420,7 @@ test("User cut paste a variant into another container", async ({ page }) => {
const variant3 = await workspacePage.layers const variant3 = await workspacePage.layers
.getByTestId("layer-row") .getByTestId("layer-row")
.filter({ has: workspacePage.page.getByText("Value 1, rectangle") }) .filter({ has: workspacePage.page.getByText("Value 1, rectangle") })
.filter({ has: workspacePage.page.locator(".icon-variant") }) .filter({ has: workspacePage.page.getByTestId("icon-variant") })
.first(); .first();
//The new variant exists and is visible //The new variant exists and is visible

View File

@@ -1,70 +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.components.shape-icon
(:require
[app.common.types.component :as ctk]
[app.common.types.shape :as cts]
[app.common.types.shape.layout :as ctl]
[app.main.ui.icons :as i]
[rumext.v2 :as mf]))
(mf/defc element-icon
{::mf/wrap-props false}
[{:keys [shape main-instance?]}]
(if (ctk/instance-head? shape)
(if main-instance?
(if (ctk/is-variant? shape)
i/variant
i/component)
i/component-copy)
(case (:type shape)
:frame (cond
(ctk/is-variant-container? shape)
i/component
(and (ctl/flex-layout? shape) (ctl/col? shape))
i/flex-horizontal
(and (ctl/flex-layout? shape) (ctl/row? shape))
i/flex-vertical
(ctl/grid-layout? shape)
i/flex-grid
:else
i/board)
;; TODO -> THUMBNAIL ICON
:image i/img
:line (if (cts/has-images? shape) i/img i/path)
:circle (if (cts/has-images? shape) i/img i/elipse)
:path (if (cts/has-images? shape) i/img i/path)
:rect (if (cts/has-images? shape) i/img i/rectangle)
:text i/text
:group (if (:masked-group shape)
i/mask
i/group)
:bool (case (:bool-type shape)
:difference i/boolean-difference
:exclude i/boolean-exclude
:intersection i/boolean-intersection
#_:default i/boolean-union)
:svg-raw i/img
nil)))
(mf/defc element-icon-by-type
[{:keys [type main-instance?] :as props}]
(if main-instance?
i/component
(case type
:frame i/board
:image i/img
:shape i/path
:text i/text
:mask i/mask
:group i/group
nil)))

View File

@@ -285,6 +285,7 @@
(def ^:icon-id tree "tree") (def ^:icon-id tree "tree")
(def ^:icon-id unlock "unlock") (def ^:icon-id unlock "unlock")
(def ^:icon-id user "user") (def ^:icon-id user "user")
(def ^:icon-id variant "variant")
(def ^:icon-id vertical-align-items-center "vertical-align-items-center") (def ^:icon-id vertical-align-items-center "vertical-align-items-center")
(def ^:icon-id vertical-align-items-end "vertical-align-items-end") (def ^:icon-id vertical-align-items-end "vertical-align-items-end")
(def ^:icon-id vertical-align-items-start "vertical-align-items-start") (def ^:icon-id vertical-align-items-start "vertical-align-items-start")

View File

@@ -41,9 +41,8 @@
(for [property properties] (for [property properties]
(let [property-name (cmm/get-css-rule-humanized property) (let [property-name (cmm/get-css-rule-humanized property)
property-value (css/get-css-value objects stroke property)] property-value (css/get-css-value objects stroke property)]
[:div {:class (stl/css :stroke-row)} [:div {:class (stl/css :stroke-row) :key (str "stroke-" (:id shape) "-" property)}
[:div {:class (stl/css :global/attr-label) [:div {:class (stl/css :global/attr-label)}
:key (str "stroke-" (:id shape) "-" property)}
property-name] property-name]
[:div {:class (stl/css :global/attr-value)} [:div {:class (stl/css :global/attr-value)}

View File

@@ -11,7 +11,7 @@
[app.main.data.event :as ev] [app.main.data.event :as ev]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.shape-icon :as sir] [app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.inspect.attributes :refer [attributes]] [app.main.ui.inspect.attributes :refer [attributes]]
@@ -19,6 +19,7 @@
[app.main.ui.inspect.selection-feedback :refer [resolve-shapes]] [app.main.ui.inspect.selection-feedback :refer [resolve-shapes]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.shape-icon :as usi]
[potok.v2.core :as ptk] [potok.v2.core :as ptk]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@@ -100,14 +101,16 @@
:viewer-code (= from :viewer))} :viewer-code (= from :viewer))}
(if (seq shapes) (if (seq shapes)
[:div {:class (stl/css :tool-windows)} [:div {:class (stl/css :tool-windows)}
[:div {:class (stl/css-case :shape-row true :shape-row-subtitle (some? subtitle))} [:div {:class (stl/css-case :shape-info true :shape-info-subtitle (some? subtitle))}
(if (> (count shapes) 1) (if (> (count shapes) 1)
[:* [:*
[:span {:class (stl/css :layers-icon)} i/layers] [:div {:class (stl/css :layers-icon)}
[:> icon* {:icon-id "layers" :size "s"}]]
[:span {:class (stl/css :layer-title)} (tr "inspect.tabs.code.selected.multiple" (count shapes))]] [:span {:class (stl/css :layer-title)} (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
[:* [:*
[:span {:class (stl/css :shape-icon)} [:div {:class (stl/css :shape-icon)}
[:& sir/element-icon {:shape first-shape :main-instance? main-instance?}]] ;; Use the shape icon utility to get the correct icon for the first shape
[:> icon* {:icon-id (usi/get-shape-icon first-shape) :size "s"}]]
;; Execution time translation strings: ;; Execution time translation strings:
;; (tr "inspect.tabs.code.selected.circle") ;; (tr "inspect.tabs.code.selected.circle")
;; (tr "inspect.tabs.code.selected.component") ;; (tr "inspect.tabs.code.selected.component")
@@ -120,12 +123,14 @@
;; (tr "inspect.tabs.code.selected.rect") ;; (tr "inspect.tabs.code.selected.rect")
;; (tr "inspect.tabs.code.selected.svg-raw") ;; (tr "inspect.tabs.code.selected.svg-raw")
;; (tr "inspect.tabs.code.selected.text") ;; (tr "inspect.tabs.code.selected.text")
[:div [:div
(if (some? subtitle) (if (some? subtitle)
[:* [:*
[:div {:class (stl/css :layer-title :layer-title-with-subtitle)} (:name first-shape)] [:div {:class (stl/css :layer-title :layer-title-with-subtitle)} (:name first-shape)]
[:div {:class (stl/css :layer-subtitle)} subtitle]] [:div {:class (stl/css :layer-subtitle)} subtitle]]
[:div {:class (stl/css :layer-title)} (:name first-shape)])]])] [:div
[:div {:class (stl/css :layer-title)} (:name first-shape)]])]])]
[:div {:class (stl/css :inspect-content)} [:div {:class (stl/css :inspect-content)}

View File

@@ -33,7 +33,7 @@
padding-left: var(--sp-m); padding-left: var(--sp-m);
} }
.shape-row { .shape-info {
display: grid; display: grid;
grid-template-columns: auto minmax(0, 1fr); grid-template-columns: auto minmax(0, 1fr);
gap: $s-8; gap: $s-8;
@@ -41,7 +41,7 @@
height: $s-32; height: $s-32;
} }
.shape-row-subtitle { .shape-info-subtitle {
height: fit-content; height: fit-content;
align-items: flex-start; align-items: flex-start;
} }
@@ -50,11 +50,6 @@
.shape-icon { .shape-icon {
@include flexCenter; @include flexCenter;
height: $s-32; height: $s-32;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
} }
.layer-title { .layer-title {

View File

@@ -31,12 +31,12 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.shape-icon :as sic]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr] :as i18n] [app.util.i18n :refer [tr] :as i18n]
[app.util.shape-icon :as usi]
[app.util.timers :as timers] [app.util.timers :as timers]
[app.util.webapi :as wapi] [app.util.webapi :as wapi]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
@@ -110,9 +110,10 @@
[:span [:span
{:class (stl/css :icon-wrapper)} {:class (stl/css :icon-wrapper)}
(if is-selected [:span {:class (stl/css :selected-icon)} (if is-selected [:span {:class (stl/css :selected-icon)}
i/tick] [:> icon* {:icon-id "tick" :size "s"}]]
[:span {:class (stl/css :selected-icon)}]) [:span {:class (stl/css :selected-icon)}])
[:span {:class (stl/css :shape-icon)} icon]] [:span {:class (stl/css :shape-icon)}
[:> icon* {:icon-id icon :size "s"}]]]
[:span {:class (stl/css :title)} title]] [:span {:class (stl/css :title)} title]]
[:li {:class (stl/css :context-menu-item) [:li {:class (stl/css :context-menu-item)
:disabled disabled :disabled disabled
@@ -129,7 +130,8 @@
:class (stl/css :shortcut-key)} sc])]) :class (stl/css :shortcut-key)} sc])])
(when (> (count children) 1) (when (> (count children) 1)
[:span {:class (stl/css :submenu-icon)} i/arrow]) [:span {:class (stl/css :submenu-icon)}
[:> icon* {:icon-id "arrow" :size "s"}]])
(when (> (count children) 1) (when (> (count children) 1)
[:ul {:class (stl/css :workspace-context-submenu) [:ul {:class (stl/css :workspace-context-submenu)
@@ -266,7 +268,7 @@
:on-pointer-enter (on-pointer-enter (:id object)) :on-pointer-enter (on-pointer-enter (:id object))
:on-pointer-leave (on-pointer-leave (:id object)) :on-pointer-leave (on-pointer-leave (:id object))
:on-unmount (on-unmount (:id object)) :on-unmount (on-unmount (:id object))
:icon (sic/element-icon {:shape object})}])]) :icon (usi/get-shape-icon object)}])])
[:> menu-entry* {:title (tr "workspace.shape.menu.forward") [:> menu-entry* {:title (tr "workspace.shape.menu.forward")
:shortcut (sc/get-tooltip :bring-forward) :shortcut (sc/get-tooltip :bring-forward)
:on-click do-bring-forward}] :on-click do-bring-forward}]

View File

@@ -20,14 +20,15 @@
[app.main.features :as features] [app.main.features :as features]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.shape-icon :as sic]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.layer-name :refer [layer-name*]] [app.main.ui.workspace.sidebar.layer-name :refer [layer-name*]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.shape-icon :as usi]
[app.util.timers :as ts] [app.util.timers :as ts]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[okulary.core :as l] [okulary.core :as l]
@@ -54,7 +55,6 @@
parent-board? (and (cfh/frame-shape? item) parent-board? (and (cfh/frame-shape? item)
(= uuid/zero (:parent-id item))) (= uuid/zero (:parent-id item)))
absolute? (ctl/item-absolute? item) absolute? (ctl/item-absolute? item)
main-instance? (:main-instance item)
variants? (features/use-feature "variants/v1") variants? (features/use-feature "variants/v1")
is-variant? (when variants? (ctk/is-variant? item)) is-variant? (when variants? (ctk/is-variant? item))
@@ -65,7 +65,8 @@
data (deref refs/workspace-data) data (deref refs/workspace-data)
component (ctkl/get-component data (:component-id item)) component (ctkl/get-component data (:component-id item))
variant-properties (:variant-properties component)] variant-properties (:variant-properties component)
icon-shape (usi/get-shape-icon item)]
[:* [:*
[:div {:id id [:div {:id id
:ref dref :ref dref
@@ -113,10 +114,7 @@
:on-double-click on-zoom-to-selected} :on-double-click on-zoom-to-selected}
(when absolute? (when absolute?
[:div {:class (stl/css :absolute)}]) [:div {:class (stl/css :absolute)}])
[:> icon* {:icon-id icon-shape :size "s" :data-testid (str "icon-" icon-shape)}]]]
[:& sic/element-icon
{:shape item
:main-instance? main-instance?}]]]
[:div {:class (stl/css :button-content)} [:div {:class (stl/css :button-content)}
(when (not ^boolean filtered?) (when (not ^boolean filtered?)
@@ -125,9 +123,7 @@
:on-double-click on-zoom-to-selected} :on-double-click on-zoom-to-selected}
(when ^boolean absolute? (when ^boolean absolute?
[:div {:class (stl/css :absolute)}]) [:div {:class (stl/css :absolute)}])
[:& sic/element-icon [:> icon* {:icon-id icon-shape :size "s" :data-testid (str "icon-" icon-shape)}]]])
{:shape item
:main-instance? main-instance?}]]])
[:> layer-name* {:ref name-ref [:> layer-name* {:ref name-ref
:shape-id id :shape-id id

View File

@@ -117,16 +117,12 @@
height: 100%; height: 100%;
width: $s-24; width: $s-24;
padding-inline-start: $s-4; padding-inline-start: $s-4;
svg { color: var(--icon-foreground);
@extend .button-icon-small; .layer-row.selected & {
stroke: var(--icon-foreground); color: var(--layer-row-foreground-color-selected);
}
.layer-row.selected & { .layer-row.type-comp & {
stroke: var(--layer-row-foreground-color-selected); color: var(--layer-row-component-foreground-color);
}
.layer-row.type-comp & {
stroke: var(--layer-row-component-foreground-color);
}
} }
.inverse & { .inverse & {
transform: rotate(-90deg); transform: rotate(-90deg);

View File

@@ -16,9 +16,9 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.search-bar :refer [search-bar]] [app.main.ui.components.search-bar :refer [search-bar]]
[app.main.ui.components.shape-icon :as sic]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.notifications.badge :refer [badge-notification]] [app.main.ui.notifications.badge :refer [badge-notification]]
@@ -28,11 +28,13 @@
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.rxops :refer [throttle-fn]] [app.util.rxops :refer [throttle-fn]]
[app.util.shape-icon :as usi]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[cuerdas.core :as str] [cuerdas.core :as str]
[goog.events :as events] [goog.events :as events]
[rumext.v2 :as mf]) [rumext.v2 :as mf])
(:import goog.events.EventType)) (:import
goog.events.EventType))
;; This components is a piece for sharding equality check between top ;; This components is a piece for sharding equality check between top
;; level frames and try to avoid rerender frames that are does not ;; level frames and try to avoid rerender frames that are does not
@@ -295,7 +297,7 @@
:filter-button true :filter-button true
:opened show-menu? :opened show-menu?
:active active?)} :active active?)}
i/filter-icon]] [:> icon* {:icon-id "filter"}]]]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "labels.close") :aria-label (tr "labels.close")
@@ -305,6 +307,7 @@
[:div {:class (stl/css :active-filters)} [:div {:class (stl/css :active-filters)}
(for [fkey current-filters] (for [fkey current-filters]
(let [fname (d/name fkey) (let [fname (d/name fkey)
name (case fkey name (case fkey
:frame (tr "workspace.sidebar.layers.frames") :frame (tr "workspace.sidebar.layers.frames")
:group (tr "workspace.sidebar.layers.groups") :group (tr "workspace.sidebar.layers.groups")
@@ -313,21 +316,17 @@
:text (tr "workspace.sidebar.layers.texts") :text (tr "workspace.sidebar.layers.texts")
:image (tr "workspace.sidebar.layers.images") :image (tr "workspace.sidebar.layers.images")
:shape (tr "workspace.sidebar.layers.shapes") :shape (tr "workspace.sidebar.layers.shapes")
(tr fkey))] (tr fkey))
filter-icon (usi/get-shape-icon-by-type fkey)]
[:button {:class (stl/css :layer-filter) [:button {:class (stl/css :layer-filter)
:key fname :key fname
:data-filter fname :data-filter fname
:on-click remove-filter} :on-click remove-filter}
[:> icon* {:icon-id filter-icon :size "s" :class (stl/css :layer-filter-icon)}]
[:span {:class (stl/css :layer-filter-icon)}
[:& sic/element-icon-by-type
{:type fkey
:main-instance? (= fkey :component)}]]
[:span {:class (stl/css :layer-filter-name)} [:span {:class (stl/css :layer-filter-name)}
name] name]
[:span {:class (stl/css :layer-filter-close)} [:> icon* {:icon-id "close-small" :class (stl/css :layer-filter-close)}]]))]
i/close-small]]))]
(when ^boolean show-menu? (when ^boolean show-menu?
[:ul {:class (stl/css :filters-container)} [:ul {:class (stl/css :filters-container)}
@@ -336,98 +335,84 @@
:data-filter "frame" :data-filter "frame"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "board" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/board]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.frames")]] (tr "workspace.sidebar.layers.frames")]]
(when (contains? current-filters :frame) (when (contains? current-filters :frame)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :group)) :selected (contains? current-filters :group))
:data-filter "group" :data-filter "group"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "group" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/group]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.groups")]] (tr "workspace.sidebar.layers.groups")]]
(when (contains? current-filters :group) (when (contains? current-filters :group)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :mask)) :selected (contains? current-filters :mask))
:data-filter "mask" :data-filter "mask"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "mask" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/mask]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.masks")]] (tr "workspace.sidebar.layers.masks")]]
(when (contains? current-filters :mask) (when (contains? current-filters :mask)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :component)) :selected (contains? current-filters :component))
:data-filter "component" :data-filter "component"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "component" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/component]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.components")]] (tr "workspace.sidebar.layers.components")]]
(when (contains? current-filters :component) (when (contains? current-filters :component)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :text)) :selected (contains? current-filters :text))
:data-filter "text" :data-filter "text"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "text" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/text]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.texts")]] (tr "workspace.sidebar.layers.texts")]]
(when (contains? current-filters :text) (when (contains? current-filters :text)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :image)) :selected (contains? current-filters :image))
:data-filter "image" :data-filter "image"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "img" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/img]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.images")]] (tr "workspace.sidebar.layers.images")]]
(when (contains? current-filters :image) (when (contains? current-filters :image)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]
i/tick])]
[:li {:class (stl/css-case :filter-menu-item true [:li {:class (stl/css-case :filter-menu-item true
:selected (contains? current-filters :shape)) :selected (contains? current-filters :shape))
:data-filter "shape" :data-filter "shape"
:on-click add-filter} :on-click add-filter}
[:div {:class (stl/css :filter-menu-item-name-wrapper)} [:div {:class (stl/css :filter-menu-item-name-wrapper)}
[:span {:class (stl/css :filter-menu-item-icon)} [:> icon* {:icon-id "path" :size "s" :class (stl/css :filter-menu-item-icon)}]
i/path]
[:span {:class (stl/css :filter-menu-item-name)} [:span {:class (stl/css :filter-menu-item-name)}
(tr "workspace.sidebar.layers.shapes")]] (tr "workspace.sidebar.layers.shapes")]]
(when (contains? current-filters :shape) (when (contains? current-filters :shape)
[:span {:class (stl/css :filter-menu-item-tick)} [:> icon* {:icon-id "tick" :size "s" :class (stl/css :filter-menu-item-tick)}])]])]
i/tick])]])]
[:div {:class (stl/css :tool-window-bar)} [:div {:class (stl/css :tool-window-bar)}
[:> title-bar* {:collapsable false [:> title-bar* {:collapsable false
@@ -519,7 +504,7 @@
[:button {:class (stl/css :focus-title) [:button {:class (stl/css :focus-title)
:on-click toogle-focus-mode} :on-click toogle-focus-mode}
[:span {:class (stl/css :back-button)} [:span {:class (stl/css :back-button)}
i/arrow] [:> icon* {:icon-id "arrow"}]]
[:div {:class (stl/css :focus-name)} [:div {:class (stl/css :focus-name)}
(or title (tr "workspace.sidebar.layers"))] (or title (tr "workspace.sidebar.layers"))]

View File

@@ -127,12 +127,7 @@
.layer-filter-icon, .layer-filter-icon,
.layer-filter-close { .layer-filter-close {
@extend .button-icon-small; color: var(--pill-foreground-color);
stroke: var(--pill-foreground-color);
svg {
height: $s-12;
width: $s-12;
}
} }
.layer-filter-name { .layer-filter-name {
@@ -164,10 +159,7 @@
align-items: center; align-items: center;
gap: $s-8; gap: $s-8;
.filter-menu-item-icon { .filter-menu-item-icon {
svg { color: var(--menu-foreground-color);
@extend .button-icon-small;
stroke: var(--menu-foreground-color);
}
} }
.filter-menu-item-name { .filter-menu-item-name {
padding-top: $s-2; padding-top: $s-2;
@@ -175,28 +167,21 @@
} }
} }
.filter-menu-item-tick { .filter-menu-item-tick {
svg { color: var(--menu-foreground-color);
@extend .button-icon-small;
stroke: var(--menu-foreground-color);
}
} }
&.selected { &.selected {
background-color: var(--menu-background-color-selected); background-color: var(--menu-background-color-selected);
.filter-menu-item-name-wrapper { .filter-menu-item-name-wrapper {
.filter-menu-item-icon { .filter-menu-item-icon {
svg { color: var(--menu-foreground-color);
stroke: var(--menu-foreground-color);
}
} }
.filter-menu-item-name { .filter-menu-item-name {
color: var(--menu-foreground-color); color: var(--menu-foreground-color);
} }
} }
.filter-menu-item-tick { .filter-menu-item-tick {
svg { color: var(--menu-foreground-color);
stroke: var(--menu-foreground-color);
}
} }
} }
@@ -204,18 +189,14 @@
background-color: var(--menu-background-color-hover); background-color: var(--menu-background-color-hover);
.filter-menu-item-name-wrapper { .filter-menu-item-name-wrapper {
.filter-menu-item-icon { .filter-menu-item-icon {
svg { color: var(--menu-foreground-color-hover);
stroke: var(--menu-foreground-color-hover);
}
} }
.filter-menu-item-name { .filter-menu-item-name {
color: var(--menu-foreground-color-hover); color: var(--menu-foreground-color-hover);
} }
} }
.filter-menu-item-tick { .filter-menu-item-tick {
svg { color: var(--menu-foreground-color-hover);
stroke: var(--menu-foreground-color-hover);
}
} }
} }
} }

View File

@@ -0,0 +1,87 @@
;; 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.util.shape-icon
(:require
[app.common.data.macros :as dm]
[app.common.types.component :as ctk]
[app.common.types.shape :as cts]
[app.common.types.shape.layout :as ctl]))
(defn- get-bool-icon
"Returns the icon for a boolean shape"
[shape]
(case (:bool-type shape)
:difference "boolean-difference"
:exclude "boolean-exclude"
:intersection "boolean-intersection"
nil))
(defn- get-frame-icon
"Returns the icon for a frame shape"
[shape]
(cond
(ctk/is-variant-container? shape)
"component"
(and (ctl/flex-layout? shape) (ctl/col? shape))
"flex-horizontal"
(and (ctl/flex-layout? shape) (ctl/row? shape))
"flex-vertical"
(ctl/grid-layout? shape)
"flex-grid"
:else
"board"))
(defn get-shape-icon
"Returns the icon for a shape based on its type and properties"
[shape]
(if (ctk/instance-head? shape)
(if (ctk/main-instance? shape)
(if (ctk/is-variant? shape)
"variant"
"component")
"component-copy")
(case (dm/get-prop shape :type)
:frame (get-frame-icon shape)
:image "img"
:line (if (cts/has-images? shape)
"img"
"rectangle")
:circle (if (cts/has-images? shape)
"img"
"elipse")
:path (if (cts/has-images? shape)
"img"
"rectangle")
:rect (if (cts/has-images? shape)
"img"
"rectangle")
:text "text"
:group (if (:masked-group shape)
"mask"
"group")
:bool (get-bool-icon shape)
:svg-raw "img"
nil)))
(defn get-shape-icon-by-type
"Returns the icon for a shape based on its type"
[type]
(if (= type :component)
"component"
(case type
:frame "board"
:image "img"
:shape "path"
:text "text"
:mask "mask"
:group "group"
nil)))