Merge branch 'staging' into staging-render

This commit is contained in:
Andrey Antukh 2026-02-17 21:54:23 +01:00
commit 2b130c7e52
95 changed files with 3692 additions and 2558 deletions

View File

@ -5,7 +5,8 @@ ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \
NODE_VERSION=v22.22.0 \ NODE_VERSION=v22.22.0 \
DEBIAN_FRONTEND=noninteractive \ DEBIAN_FRONTEND=noninteractive \
PATH=/opt/node/bin:/opt/imagick/bin:$PATH PATH=/opt/node/bin:/opt/imagick/bin:$PATH \
PLAYWRIGHT_BROWSERS_PATH=/opt/penpot/browsers
RUN set -ex; \ RUN set -ex; \
useradd -U -M -u 1001 -s /bin/false -d /opt/penpot penpot; \ useradd -U -M -u 1001 -s /bin/false -d /opt/penpot penpot; \

View File

@ -15,6 +15,7 @@ pnpm run build;
cp pnpm-lock.yaml target/; cp pnpm-lock.yaml target/;
cp package.json target/; cp package.json target/;
touch target/pnpm-workspace.yaml;
cat <<EOF | tee target/setup cat <<EOF | tee target/setup
#/usr/bin/env bash #/usr/bin/env bash
@ -22,7 +23,7 @@ set -e;
corepack enable; corepack enable;
corepack install; corepack install;
pnpm install pnpm install
pnpx playwright install chromium; pnpm exec playwright install chromium;
EOF EOF
chmod +x target/setup; chmod +x target/setup;

View File

@ -162,10 +162,10 @@ export class WorkspacePage extends BaseWebSocketPage {
`[id="shape-00000000-0000-0000-0000-000000000000"]`, `[id="shape-00000000-0000-0000-0000-000000000000"]`,
); );
this.toolbarOptions = page.getByTestId("toolbar-options"); this.toolbarOptions = page.getByTestId("toolbar-options");
this.rectShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Rectangle" }); this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
this.ellipseShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Ellipse" }); this.ellipseShapeButton = page.getByRole("button", { name: "Ellipse (E)" });
this.moveButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Move" }); this.moveButton = page.getByRole("button", { name: "Move (V)" });
this.boardButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Board" }); this.boardButton = page.getByRole("button", { name: "Board (B)" });
this.toggleToolbarButton = page.getByRole("button", { this.toggleToolbarButton = page.getByRole("button", {
name: "Toggle toolbar", name: "Toggle toolbar",
}); });

View File

@ -189,8 +189,8 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({
await workspacePage.clickLeafLayer("Flex Board"); await workspacePage.clickLeafLayer("Flex Board");
// Move the first board into the second // Move the first board into the second
const hAuto = await workspacePage.page.getByTestId("behaviour-h-auto"); const hAuto = await workspacePage.page.getByTitle("Fit content (Horizontal)");
const vAuto = await workspacePage.page.getByTestId("behaviour-v-auto"); const vAuto = await workspacePage.page.getByTitle("Fit content (Vertical)");
await expect(vAuto.locator("input")).toBeChecked(); await expect(vAuto.locator("input")).toBeChecked();
await expect(hAuto.locator("input")).toBeChecked(); await expect(hAuto.locator("input")).toBeChecked();

View File

@ -1493,10 +1493,8 @@ test.describe("Tokens - creation", () => {
const nameField = tokensUpdateCreateModal.getByLabel("Name"); const nameField = tokensUpdateCreateModal.getByLabel("Name");
await nameField.fill(newTokenTitle); await nameField.fill(newTokenTitle);
const referenceTabButton = tokensUpdateCreateModal.getByRole("button", { const referenceTabButton = tokensUpdateCreateModal.getByTestId("reference-opt");
name: "Use a reference", await referenceTabButton.click();
});
referenceTabButton.click();
const referenceField = tokensUpdateCreateModal.getByRole("textbox", { const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
name: "Reference", name: "Reference",

View File

@ -353,33 +353,24 @@ test("Copy/paste properties", async ({ page, context }) => {
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page await page.getByText("Rectangle").first().click({ button: "right" });
.getByTestId("layer-item") await page.getByText("Copy/Paste as").hover();
.getByText("Rectangle") await page.getByText("Paste properties").click();
.first()
.click({ button: "right" }); await page.getByText("Board").nth(2).click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page await page
.getByTestId("layer-item") .getByTestId("layer-item")
.getByText("Board") .locator("div")
.filter({ hasText: "Path" })
.nth(1) .nth(1)
.click({ button: "right" }); .click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page await page.getByText("Ellipse").click({ button: "right" });
.getByTestId("layer-item")
.getByText("Path")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page
.getByTestId("layer-item")
.getByText("Ellipse")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
}); });

View File

@ -244,6 +244,13 @@
--assets-component-second-border-selected: var(--color-background-primary); --assets-component-second-border-selected: var(--color-background-primary);
--assets-component-hightlight: var(--color-accent-secondary); --assets-component-hightlight: var(--color-accent-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-quaternary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-quaternary);
--library-name-foreground-color: var(--color-foreground-primary); --library-name-foreground-color: var(--color-foreground-primary);
--library-content-foreground-color: var(--color-foreground-secondary); --library-content-foreground-color: var(--color-foreground-secondary);
@ -416,6 +423,13 @@
--tab-border-color: var(--color-background-tertiary); --tab-border-color: var(--color-background-tertiary);
--tab-border-color-selected: var(--color-background-secondary); --tab-border-color-selected: var(--color-background-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-primary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-secondary);
--button-icon-background-color-selected: var(--color-background-primary); --button-icon-background-color-selected: var(--color-background-primary);
--button-icon-border-color-selected: var(--color-background-secondary); --button-icon-border-color-selected: var(--color-background-secondary);

View File

@ -10,9 +10,9 @@
[app.util.dom :as dom] [app.util.dom :as dom]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc file-uploader* (mf/defc file-uploader
{::mf/forward-ref true} {::mf/forward-ref true}
[{:keys [accept multi label-text label-class input-id on-selected data-testid]} input-ref] [{:keys [accept multi label-text label-class input-id on-selected data-testid] :as props} input-ref]
(let [opt-pick-one #(if multi % (first %)) (let [opt-pick-one #(if multi % (first %))
on-files-selected on-files-selected

View File

@ -0,0 +1,107 @@
;; 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.radio-buttons
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.formats :as fmt]
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(def context
(mf/create-context nil))
(mf/defc radio-button
{::mf/props :obj}
[{:keys [icon id value disabled title icon-class type]}]
(let [context (mf/use-ctx context)
allow-empty (unchecked-get context "allow-empty")
type (if ^boolean type
type
(if ^boolean allow-empty
"checkbox"
"radio"))
on-change (unchecked-get context "on-change")
selected (unchecked-get context "selected")
name (unchecked-get context "name")
encode-fn (unchecked-get context "encode-fn")
checked? (= selected value)
value (encode-fn value)]
[:label {:html-for id
:data-testid id
:title title
:class (stl/css-case
:radio-icon true
:checked checked?
:disabled disabled)}
(if (some? icon)
[:> icon* {:icon-id icon :class icon-class :aria-hidden true}]
[:span {:class (stl/css :title-name)} value])
[:input {:id id
:on-change on-change
:type type
:name name
:disabled disabled
:value value
:default-checked checked?}]]))
(mf/defc radio-buttons
{::mf/props :obj}
[{:keys [name children on-change selected class wide encode-fn decode-fn allow-empty] :as props}]
(let [encode-fn (d/nilv encode-fn identity)
decode-fn (d/nilv decode-fn identity)
nitems (if (array? children)
(count (keep identity children))
1)
;; FIXME: we should handle this with CSS
width (mf/with-memo [nitems]
(if (= wide true)
"unset"
(fmt/format-pixels
(+ (* 4 (- nitems 1))
(* 32 nitems)))))
on-change'
(mf/use-fn
(mf/deps selected on-change)
(fn [event]
(let [input (dom/get-target event)
value (dom/get-target-val event)
;; Only allow null values when the "allow-empty" prop is true
value (when (or (not allow-empty)
(not= value selected)) value)]
(when (fn? on-change)
(on-change (decode-fn value) event))
(dom/blur! input))))
context-value
(mf/spread-object props
;; We pass a special metadata for disable
;; key casing transformation in this
;; concrete case, because this component
;; uses legacy mode and props are in
;; kebab-case style
^{::mf/transform false}
{:on-change on-change'
:encode-fn encode-fn
:decode-fn decode-fn})]
[:& (mf/provider context) {:value context-value}
[:div {:class (dm/str class " " (stl/css :radio-btn-wrapper))
:style {:width width}
:key (dm/str name "-" selected)}
children]]))

View File

@ -0,0 +1,79 @@
// 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
@use "refactor/common-refactor.scss" as deprecated;
.radio-btn-wrapper {
@include deprecated.flexCenter;
border-radius: deprecated.$br-8;
height: deprecated.$s-32;
background-color: var(--input-background-color);
gap: deprecated.$s-4;
}
.radio-icon {
--radio-icon-border-color: var(--radio-btn-border-color);
@include deprecated.buttonStyle;
@include deprecated.flexCenter;
@include deprecated.focusRadio;
height: deprecated.$s-32;
flex-grow: 1;
border-radius: deprecated.$s-8;
box-sizing: border-box;
border: deprecated.$br-2 solid var(--radio-icon-border-color);
input {
display: none;
}
svg {
@extend .button-icon;
stroke: var(--radio-btn-foreground-color);
}
.title-name {
@include deprecated.uppercaseTitleTipography;
color: var(--radio-btn-foreground-color);
}
&:hover {
svg {
stroke: var(--radio-btn-foreground-color-selected);
}
}
}
.checked {
--radio-icon-border-color: var(--radio-btn-border-color-selected);
background-color: var(--radio-btn-background-color-selected);
svg {
stroke: var(--radio-btn-foreground-color-selected);
}
.title-name {
color: var(--radio-btn-foreground-color-selected);
}
}
.disabled {
cursor: default;
background-color: transparent;
border: deprecated.$s-2 solid transparent;
svg {
stroke: var(--button-foreground-color-disabled);
}
.title-name {
color: var(--button-foreground-color-disabled);
}
&:hover {
background-color: transparent;
border: deprecated.$s-2 solid transparent;
svg {
stroke: var(--button-foreground-color-disabled);
}
.title-name {
color: var(--button-foreground-color-disabled);
}
}
}

View File

@ -17,7 +17,7 @@
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.context-menu-a11y :refer [context-menu*]] [app.main.ui.components.context-menu-a11y :refer [context-menu*]]
[app.main.ui.components.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]] [app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.notifications.context-notification :refer [context-notification]] [app.main.ui.notifications.context-notification :refer [context-notification]]
@ -184,11 +184,11 @@
:on-click on-click :on-click on-click
:tab-index "0"} :tab-index "0"}
[:span (tr "labels.add-custom-font")] [:span (tr "labels.add-custom-font")]
[:> file-uploader* {:input-id "font-upload" [:& file-uploader {:input-id "font-upload"
:accept accept-font-types :accept accept-font-types
:multi true :multi true
:ref input-ref :ref input-ref
:on-selected on-selected}]] :on-selected on-selected}]]
(when-let [url cf/terms-of-service-uri] (when-let [url cf/terms-of-service-uri]
[:& context-notification {:content (tr "dashboard.fonts.hero-text2" url) [:& context-notification {:content (tr "dashboard.fonts.hero-text2" url)

View File

@ -16,7 +16,7 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.notifications :as ntf] [app.main.data.notifications :as ntf]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.ds.product.loader :refer [loader*]] [app.main.ui.ds.product.loader :refer [loader*]]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.notifications.context-notification :refer [context-notification]] [app.main.ui.notifications.context-notification :refer [context-notification]]
@ -58,10 +58,10 @@
[{:keys [project-id on-finish-import]} external-ref] [{:keys [project-id on-finish-import]} external-ref]
(let [on-file-selected (use-import-file project-id on-finish-import)] (let [on-file-selected (use-import-file project-id on-finish-import)]
[:form.import-file {:aria-hidden "true"} [:form.import-file {:aria-hidden "true"}
[:> file-uploader* {:accept ".penpot,.zip" [:& file-uploader {:accept ".penpot,.zip"
:multi true :multi true
:ref external-ref :ref external-ref
:on-selected on-file-selected}]])) :on-selected on-file-selected}]]))
(defn- update-entry-name (defn- update-entry-name
[entries file-id new-name] [entries file-id new-name]

View File

@ -19,7 +19,7 @@
[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.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.main.ui.dashboard.change-owner] [app.main.ui.dashboard.change-owner]
[app.main.ui.dashboard.subscription :refer [members-cta* [app.main.ui.dashboard.subscription :refer [members-cta*
@ -1315,10 +1315,10 @@
[:img {:class (stl/css :team-image) [:img {:class (stl/css :team-image)
:src (cfg/resolve-team-photo-url team)}] :src (cfg/resolve-team-photo-url team)}]
(when can-edit (when can-edit
[:> file-uploader* {:accept "image/jpeg,image/png" [:& file-uploader {:accept "image/jpeg,image/png"
:multi false :multi false
:ref finput :ref finput
:on-selected on-file-selected}])] :on-selected on-file-selected}])]
[:div {:class (stl/css :block-label)} [:div {:class (stl/css :block-label)}
(tr "dashboard.team-info")] (tr "dashboard.team-info")]
[:div {:class (stl/css :block-text)} [:div {:class (stl/css :block-text)}

View File

@ -11,10 +11,8 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]] [app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
[app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as k] [app.util.keyboard :as k]
@ -99,11 +97,8 @@
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)} [:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title)} title] [:h2 {:class (stl/css :modal-title)} title]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :modal-close-btn)
:class (stl/css :modal-close-btn) :on-click cancel-fn} deprecated-icon/close]]
:icon i/close
:aria-label (tr "labels.close")
:on-click cancel-fn}]]
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
(when (and (string? subtitle) (not= subtitle "")) (when (and (string? subtitle) (not= subtitle ""))
@ -129,10 +124,14 @@
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)} [:div {:class (stl/css :action-buttons)}
(when-not (= cancel-label :omit) (when-not (= cancel-label :omit)
[:> button* {:variant "secondary" [:input {:class (stl/css :cancel-button)
:on-click cancel-fn} :type "button"
cancel-label]) :value cancel-label
:on-click cancel-fn}])
[:> button* {:variant (if (= accept-style :danger) "destructive" "primary") [:input {:class (stl/css-case :accept-btn true
:on-click accept-fn} :danger (= accept-style :danger)
accept-label]]]]])) :primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]))

View File

@ -33,9 +33,7 @@
} }
.modal-close-btn { .modal-close-btn {
position: absolute; @extend .modal-close-btn-base;
top: var(--sp-s);
right: var(--sp-s);
} }
.modal-content { .modal-content {
@ -55,6 +53,17 @@
@extend .modal-action-btns; @extend .modal-action-btns;
} }
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
.modal-scd-msg { .modal-scd-msg {
margin-block: 0; margin-block: 0;
} }

View File

@ -15,7 +15,6 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center;
column-gap: var(--sp-xs); column-gap: var(--sp-xs);
} }

View File

@ -208,7 +208,7 @@
;; FIXME: deprecated, should be refactored in two components and use ;; FIXME: deprecated, should be refactored in two components and use
;; the generic progress reporter ;; the generic progress reporter
(mf/defc progress-widget* (mf/defc progress-widget
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[] []
(let [state (mf/deref refs/export) (let [state (mf/deref refs/export)

View File

@ -19,10 +19,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.code-block :refer [code-block]] [app.main.ui.components.code-block :refer [code-block]]
[app.main.ui.components.copy-button :refer [copy-button*]] [app.main.ui.components.copy-button :refer [copy-button*]]
[app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.shapes.text.fontfaces :refer [shapes->fonts]] [app.main.ui.shapes.text.fontfaces :refer [shapes->fonts]]
@ -263,9 +260,8 @@
[:div {:class (stl/css-case :element-options true [:div {:class (stl/css-case :element-options true
:viewer-code-block (= :viewer from))} :viewer-code-block (= :viewer from))}
[:div {:class (stl/css :attributes-block)} [:div {:class (stl/css :attributes-block)}
[:> button* {:variant "secondary" [:button {:class (stl/css :download-button)
:class (stl/css :download-button) :on-click handle-copy-all-code}
:on-click handle-copy-all-code}
"Copy all code"]] "Copy all code"]]
#_[:div.attributes-block #_[:div.attributes-block
@ -292,10 +288,10 @@
;; :options [{:label "CSS" :value "css"}]}] ;; :options [{:label "CSS" :value "css"}]}]
[:div {:class (stl/css :action-btns)} [:div {:class (stl/css :action-btns)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :expand-button)
:aria-label "Expand" :on-click on-expand}
:on-click on-expand deprecated-icon/code]
:icon i/code}]
[:> copy-button* {:data copy-css-fn [:> copy-button* {:data copy-css-fn
:class (stl/css :css-copy-btn) :class (stl/css :css-copy-btn)
:on-copied on-style-copied}]]] :on-copied on-style-copied}]]]
@ -322,21 +318,21 @@
:rotated collapsed-markup?)} :rotated collapsed-markup?)}
deprecated-icon/arrow]] deprecated-icon/arrow]]
[:> radio-buttons* {:selected markup-type [:& radio-buttons {:selected markup-type
:on-change set-markup :on-change set-markup
:name "listing-style" :class (stl/css :code-lang-options)
:options [{:id "html" :wide true
:label "HTML" :name "listing-style"}
:value "html"} [:& radio-button {:value "html"
{:id "svg" :id :html}]
:label "SVG" [:& radio-button {:value "svg"
:value "svg"}]}] :id :svg}]]
[:div {:class (stl/css :action-btns)} [:div {:class (stl/css :action-btns)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :expand-button)
:aria-label "Expand" :on-click on-expand}
:on-click on-expand deprecated-icon/code]
:icon i/code}]
[:> copy-button* {:data copy-html-fn [:> copy-button* {:data copy-html-fn
:class (stl/css :html-copy-btn) :class (stl/css :html-copy-btn)
:on-copied on-markup-copied}]]] :on-copied on-markup-copied}]]]

View File

@ -17,18 +17,16 @@
padding-inline: var(--sp-m); padding-inline: var(--sp-m);
} }
.attributes-block {
display: flex;
flex-direction: column;
row-gap: 12px;
}
.viewer-code-block { .viewer-code-block {
height: calc(100vh - #{deprecated.$s-108}); // TODO: Fix this hardcoded value height: calc(100vh - #{deprecated.$s-108}); // TODO: Fix this hardcoded value
} }
.download-button { .download-button {
margin: var(--sp-s) 0; @extend .button-secondary;
@include deprecated.uppercaseTitleTipography;
height: deprecated.$s-32;
width: 100%;
margin: deprecated.$s-8 0;
} }
.code-block { .code-block {
@ -75,6 +73,7 @@
gap: deprecated.$s-4; gap: deprecated.$s-4;
} }
.expand-button,
.css-copy-btn, .css-copy-btn,
.html-copy-btn { .html-copy-btn {
@extend .button-tertiary; @extend .button-tertiary;
@ -86,6 +85,9 @@
} }
} }
.code-lang-options {
max-width: deprecated.$s-108;
}
.code-lang-select { .code-lang-select {
@include deprecated.uppercaseTitleTipography; @include deprecated.uppercaseTitleTipography;
width: deprecated.$s-72; width: deprecated.$s-72;

View File

@ -14,7 +14,7 @@
[app.main.data.profile :as du] [app.main.data.profile :as du]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -110,11 +110,11 @@
[:span {:class (stl/css :update-overlay) [:span {:class (stl/css :update-overlay)
:on-click on-image-click} (tr "labels.update")] :on-click on-image-click} (tr "labels.update")]
[:img {:src photo}] [:img {:src photo}]
[:> file-uploader* {:accept "image/jpeg,image/png" [:& file-uploader {:accept "image/jpeg,image/png"
:multi false :multi false
:ref input-ref :ref input-ref
:on-selected on-file-selected :on-selected on-file-selected
:data-testid "profile-image-input"}]]])) :data-testid "profile-image-input"}]]]))
;; --- Profile Page ;; --- Profile Page

View File

@ -27,8 +27,9 @@
[okulary.core :as l] [okulary.core :as l]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc comments-menu* (mf/defc comments-menu
{::mf/memo true} {::mf/props :obj
::mf/memo true}
[] []
(let [state (mf/deref refs/comments-local) (let [state (mf/deref refs/comments-local)
cmode (:mode state) cmode (:mode state)

View File

@ -14,13 +14,10 @@
[app.main.data.viewer.shortcuts :as sc] [app.main.data.viewer.shortcuts :as sc]
[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.ds.buttons.button :refer [button*]] [app.main.ui.exports.assets :refer [progress-widget]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.exports.assets :refer [progress-widget*]]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.viewer.comments :refer [comments-menu*]] [app.main.ui.viewer.comments :refer [comments-menu]]
[app.main.ui.viewer.interactions :refer [flows-menu* interactions-menu*]] [app.main.ui.viewer.interactions :refer [flows-menu* interactions-menu*]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
@ -36,12 +33,20 @@
[] []
(modal/show! :login-register {})) (modal/show! :login-register {}))
(mf/defc zoom-widget* (mf/defc zoom-widget
{::mf/memo true} {::mf/memo true
[{:keys [zoom on-increase on-decrease on-zoom-reset on-fullscreen on-zoom-fit on-zoom-fill]}] ::mf/props :obj}
(let [open* (mf/use-state false) [{:keys [zoom
open? (deref open*) on-increase
on-decrease
on-zoom-reset
on-fullscreen
on-zoom-fit
on-zoom-fill]
:as props}]
(let [open* (mf/use-state false)
open? (deref open*)
open-dropdown open-dropdown
(mf/use-fn (mf/use-fn
(fn [event] (fn [event]
@ -70,7 +75,7 @@
[:div {:class (stl/css-case :zoom-widget true [:div {:class (stl/css-case :zoom-widget true
:selected open?) :selected open?)
:on-click (if open? close-dropdown open-dropdown) :on-click open-dropdown
:title (tr "workspace.header.zoom")} :title (tr "workspace.header.zoom")}
[:span {:class (stl/css :label)} (fmt/format-percent zoom)] [:span {:class (stl/css :label)} (fmt/format-percent zoom)]
[:& dropdown {:show open? [:& dropdown {:show open?
@ -78,18 +83,18 @@
[:ul {:class (stl/css :dropdown)} [:ul {:class (stl/css :dropdown)}
[:li {:class (stl/css :basic-zoom-bar)} [:li {:class (stl/css :basic-zoom-bar)}
[:span {:class (stl/css :zoom-btns)} [:span {:class (stl/css :zoom-btns)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :zoom-btn)
:aria-label (tr "shortcuts.decrease-zoom") :on-click on-decrease}
:on-click on-decrease [:span {:class (stl/css :zoom-icon)}
:icon i/remove}] deprecated-icon/remove-icon]]
[:p {:class (stl/css :zoom-text)} [:p {:class (stl/css :zoom-text)}
(fmt/format-percent zoom)] (fmt/format-percent zoom)]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :zoom-btn)
:aria-label (tr "shortcuts.increase-zoom") :on-click on-increase}
:on-click on-increase [:span {:class (stl/css :zoom-icon)}
:icon i/add}]] deprecated-icon/add]]]
[:> button* {:variant "ghost" [:button {:class (stl/css :reset-btn)
:on-click on-zoom-reset} :on-click on-zoom-reset}
(tr "workspace.header.reset-zoom")]] (tr "workspace.header.reset-zoom")]]
[:li {:class (stl/css :zoom-option) [:li {:class (stl/css :zoom-option)
@ -114,7 +119,7 @@
[:span {:class (stl/css :shortcut-key) [:span {:class (stl/css :shortcut-key)
:key (dm/str "zoom-fullscreen-" sc)} sc])]]]]])) :key (dm/str "zoom-fullscreen-" sc)} sc])]]]]]))
(mf/defc header-options* (mf/defc header-options
[{:keys [section zoom page file index permissions interactions-mode share]}] [{:keys [section zoom page file index permissions interactions-mode share]}]
(let [fullscreen? (mf/deref fullscreen-ref) (let [fullscreen? (mf/deref fullscreen-ref)
@ -154,7 +159,6 @@
handle-zoom-fit handle-zoom-fit
(mf/use-fn (mf/use-fn
#(st/emit! dv/zoom-to-fit))] #(st/emit! dv/zoom-to-fit))]
(mf/with-effect [permissions share] (mf/with-effect [permissions share]
(when (and (when (and
(:in-team permissions) (:in-team permissions)
@ -163,7 +167,7 @@
(open-share-dialog))) (open-share-dialog)))
[:div {:class (stl/css :options-zone)} [:div {:class (stl/css :options-zone)}
[:> progress-widget*] [:& progress-widget]
(case section (case section
:interactions [:* :interactions [:*
@ -171,41 +175,40 @@
[:> flows-menu* {:page page :index index}]) [:> flows-menu* {:page page :index index}])
[:> interactions-menu* [:> interactions-menu*
{:interactions-mode interactions-mode}]] {:interactions-mode interactions-mode}]]
:comments [:> comments-menu*] :comments [:& comments-menu]
[:div {:class (stl/css :view-options)}]) [:div {:class (stl/css :view-options)}])
[:> zoom-widget* {:zoom zoom [:& zoom-widget
:on-increase handle-increase {:zoom zoom
:on-decrease handle-decrease :on-increase handle-increase
:on-zoom-reset handle-zoom-reset :on-decrease handle-decrease
:on-zoom-fill handle-zoom-fill :on-zoom-reset handle-zoom-reset
:on-zoom-fit handle-zoom-fit :on-zoom-fill handle-zoom-fill
:on-fullscreen toggle-fullscreen}] :on-zoom-fit handle-zoom-fit
:on-fullscreen toggle-fullscreen}]
(when (:in-team permissions) (when (:in-team permissions)
[:> icon-button* {:variant "ghost" [:span {:on-click go-to-workspace
:aria-label (tr "viewer.header.edit-in-workspace") :class (stl/css :edit-btn)}
:on-click go-to-workspace deprecated-icon/curve])
:icon i/curve}])
[:> icon-button* {:variant "ghost" [:span {:title (tr "viewer.header.fullscreen")
:aria-pressed fullscreen? :class (stl/css-case :fullscreen-btn true
:aria-label (tr "viewer.header.fullscreen") :selected fullscreen?)
:on-click toggle-fullscreen :on-click toggle-fullscreen}
:icon i/expand}] deprecated-icon/expand]
(when (:in-team permissions) (when (:in-team permissions)
[:> button* {:variant "primary" [:button {:on-click open-share-dialog
:class (stl/css :share-btn) :class (stl/css :share-btn)}
:on-click open-share-dialog}
(tr "labels.share")]) (tr "labels.share")])
(when-not (:is-logged permissions) (when-not (:is-logged permissions)
[:span {:on-click open-login-dialog [:span {:on-click open-login-dialog
:class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])])) :class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])]))
(mf/defc header-sitemap* (mf/defc header-sitemap
[{:keys [project file page frame toggle-thumbnails]}] [{:keys [project file page frame toggle-thumbnails] :as props}]
(let [project-name (:name project) (let [project-name (:name project)
file-name (:name file) file-name (:name file)
page-name (:name page) page-name (:name page)
@ -314,44 +317,44 @@
:pointer-events (when-not (:in-team permissions) "none")}} :pointer-events (when-not (:in-team permissions) "none")}}
penpot-logo-icon] penpot-logo-icon]
[:> header-sitemap* {:project project [:& header-sitemap {:project project
:file file :file file
:page page :page page
:frame frame :frame frame
:toggle-thumbnails toggle-thumbnails :toggle-thumbnails toggle-thumbnails
:index index}]] :index index}]]
[:div {:class (stl/css :mode-zone)} [:div {:class (stl/css :mode-zone)}
[:> icon-button* {:variant "ghost" [:button {:on-click navigate
:aria-pressed (= section :interactions) :data-value "interactions"
:aria-label (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions)) :class (stl/css-case :mode-zone-btn true
:data-value "interactions" :selected (= section :interactions))
:on-click navigate :title (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
:icon i/play}] deprecated-icon/play]
(when (or (:in-team permissions) (when (or (:in-team permissions)
(= (:who-comment permissions) "all")) (= (:who-comment permissions) "all"))
[:> icon-button* {:variant "ghost" [:button {:on-click navigate
:aria-pressed (= section :comments) :data-value "comments"
:aria-label (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments)) :class (stl/css-case :mode-zone-btn true
:data-value "comments" :selected (= section :comments))
:on-click navigate :title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
:icon i/comments}]) deprecated-icon/comments])
(when (or (:in-team permissions) (when (or (:in-team permissions)
(and (= (:type permissions) :share-link) (and (= (:type permissions) :share-link)
(= (:who-inspect permissions) "all"))) (= (:who-inspect permissions) "all")))
[:> icon-button* {:variant "ghost" [:button {:on-click go-to-inspect
:aria-pressed (= section :inspect) :class (stl/css-case :mode-zone-btn true
:aria-label (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect)) :selected (= section :inspect))
:on-click go-to-inspect :title (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
:icon i/code}])] deprecated-icon/code])]
[:> header-options* {:section section [:& header-options {:section section
:permissions permissions :permissions permissions
:page page :page page
:file file :file file
:index index :index index
:zoom zoom :zoom zoom
:interactions-mode interactions-mode :interactions-mode interactions-mode
:share share}]])) :share share}]]))

View File

@ -12,7 +12,7 @@
grid-column: 1 / span 1; grid-column: 1 / span 1;
grid-row: 1 / span 1; grid-row: 1 / span 1;
display: grid; display: grid;
grid-template-columns: 1fr auto 1fr; grid-template-columns: 1fr deprecated.$s-92 1fr;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
height: deprecated.$s-48; height: deprecated.$s-48;
@ -130,9 +130,23 @@
// SECTION BUTTONS // SECTION BUTTONS
.mode-zone { .mode-zone {
display: flex; @include deprecated.flexRow;
flex-direction: row; height: 100%;
gap: var(--sp-xs); }
.mode-zone-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
padding: 0;
svg {
@extend .button-icon;
}
}
.selected {
@extend .button-icon-selected;
} }
// OPTION AREA // OPTION AREA
@ -151,8 +165,33 @@
cursor: pointer; cursor: pointer;
} }
.fullscreen-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
.share-btn { .share-btn {
margin-left: var(--sp-xs); @extend .button-primary;
height: deprecated.$s-32;
min-width: deprecated.$s-72;
margin-left: deprecated.$s-4;
}
.edit-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
} }
.go-log-btn { .go-log-btn {
@ -206,15 +245,43 @@
display: flex; display: flex;
} }
.zoom-btn {
@extend .button-tertiary;
height: deprecated.$s-28;
width: deprecated.$s-28;
border-radius: deprecated.$br-8;
.zoom-icon {
@include deprecated.flexCenter;
width: deprecated.$s-24;
height: deprecated.$s-32;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
&:hover {
.zoom-icon svg {
stroke: var(--button-tertiary-foreground-color-hover);
}
}
}
.zoom-text { .zoom-text {
@include deprecated.flexCenter; @include deprecated.flexCenter;
height: 100%; height: 100%;
min-width: deprecated.$s-48; min-width: deprecated.$s-64;
padding: 0; padding: 0;
margin: 0 deprecated.$s-2; margin: 0 deprecated.$s-2;
color: var(--modal-title-foreground-color); color: var(--modal-title-foreground-color);
} }
.reset-btn {
@extend .button-tertiary;
color: var(--button-tertiary-foreground-color-hover);
height: deprecated.$s-28;
border-radius: deprecated.$br-8;
}
.zoom-option { .zoom-option {
@extend .menu-item-base; @extend .menu-item-base;
.shortcuts { .shortcuts {

View File

@ -20,9 +20,6 @@
[app.main.router :as rt] [app.main.router :as rt]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.util.clipboard :as clipboard] [app.util.clipboard :as clipboard]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -174,11 +171,10 @@
[:div {:class (stl/css :share-link-header)} [:div {:class (stl/css :share-link-header)}
[:h2 {:class (stl/css :share-link-title)} [:h2 {:class (stl/css :share-link-title)}
(tr "common.share-link.title")] (tr "common.share-link.title")]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :modal-close-button)
:class (stl/css :modal-close-button) :on-click on-close
:aria-label (tr "labels.close") :title (tr "labels.close")}
:on-click on-close deprecated-icon/close]]
:icon i/close}]]
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :share-link-section)} [:div {:class (stl/css :share-link-section)}
(when (and (not confirm?) (some? current-link)) (when (and (not confirm?) (some? current-link))
@ -189,10 +185,10 @@
:placeholder (tr "common.share-link.placeholder") :placeholder (tr "common.share-link.placeholder")
:read-only true}] :read-only true}]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :copy-button)
:aria-label (tr "viewer.header.share.copy-link") :title (tr "viewer.header.share.copy-link")
:on-click copy-link :on-click copy-link}
:icon i/clipboard}]]) deprecated-icon/clipboard]])
[:div {:class (stl/css :hint-wrapper)} [:div {:class (stl/css :hint-wrapper)}
(when (not ^boolean confirm?) (when (not ^boolean confirm?)
@ -203,22 +199,28 @@
[:div {:class (stl/css :description)} [:div {:class (stl/css :description)}
(tr "common.share-link.confirm-deletion-link-description")] (tr "common.share-link.confirm-deletion-link-description")]
[:div {:class (stl/css :actions)} [:div {:class (stl/css :actions)}
[:> button* {:variant "secondary" [:input {:type "button"
:on-click #(reset! confirm* false)} :class (stl/css :button-cancel)
(tr "labels.cancel")] :on-click #(reset! confirm* false)
[:> button* {:variant "destructive" :value (tr "labels.cancel")}]
:on-click delete-link} [:input {:type "button"
(tr "common.share-link.destroy-link")]]] :class (stl/css :button-danger)
:on-click delete-link
:value (tr "common.share-link.destroy-link")}]]]
(some? current-link) (some? current-link)
[:> button* {:variant "destructive" [:input
:on-click try-delete-link} {:type "button"
(tr "common.share-link.destroy-link")] :class (stl/css :button-danger)
:on-click try-delete-link
:value (tr "common.share-link.destroy-link")}]
:else :else
[:> button* {:variant "primary" [:input
:on-click create-link} {:type "button"
(tr "common.share-link.get-link")])]] :class (stl/css :button-active)
:on-click create-link
:value (tr "common.share-link.get-link")}])]]
(when (not ^boolean confirm?) (when (not ^boolean confirm?)
@ -303,7 +305,6 @@
:options [{:value "team" :label (tr "common.share-link.team-members")} :options [{:value "team" :label (tr "common.share-link.team-members")}
{:value "all" :label (tr "common.share-link.all-users")}] {:value "all" :label (tr "common.share-link.all-users")}]
:on-change on-comment-change}]]] :on-change on-comment-change}]]]
[:div {:class (stl/css :inspect-mode)} [:div {:class (stl/css :inspect-mode)}
[:div {:class (stl/css :subtitle)} [:div {:class (stl/css :subtitle)}
(tr "common.share-link.permissions-can-inspect")] (tr "common.share-link.permissions-can-inspect")]
@ -314,3 +315,6 @@
:options [{:value "team" :label (tr "common.share-link.team-members")} :options [{:value "team" :label (tr "common.share-link.team-members")}
{:value "all" :label (tr "common.share-link.all-users")}] {:value "all" :label (tr "common.share-link.all-users")}]
:on-change on-inspect-change}]]]])])]]])) :on-change on-inspect-change}]]]])])]]]))

View File

@ -30,9 +30,7 @@
} }
.modal-close-button { .modal-close-button {
position: absolute; @extend .modal-close-btn-base;
top: var(--sp-s);
right: var(--sp-s);
} }
.modal-content { .modal-content {
@ -76,6 +74,18 @@
} }
} }
.copy-button {
@extend .button-secondary;
@include deprecated.flexRow;
gap: deprecated.$s-8;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground-hover);
}
}
.description { .description {
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;
color: var(--modal-text-foreground-color); color: var(--modal-text-foreground-color);
@ -87,6 +97,18 @@
justify-content: flex-end; justify-content: flex-end;
} }
.button-active {
@extend .modal-accept-btn;
}
.button-cancel {
@extend .modal-cancel-btn;
}
.button-danger {
@extend .modal-danger-btn;
}
.permissions-section { .permissions-section {
@include deprecated.flexColumn; @include deprecated.flexColumn;
gap: deprecated.$s-8; gap: deprecated.$s-8;

View File

@ -25,11 +25,10 @@
[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.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-buttons radio-button]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
@ -416,25 +415,24 @@
:on-change handle-change-mode}]]) :on-change handle-change-mode}]])
(when (and (= origin :sidebar) show-tokens? token-color) (when (and (= origin :sidebar) show-tokens? token-color)
[:> radio-buttons* {:selected color-style [:& radio-buttons {:selected color-style
:on-change toggle-token-color :on-change toggle-token-color
:name "color-style" :name "color-style"}
:options [{:id "swap-opt-list" [:& radio-button {:icon i/swatches
:icon i/swatches :value :direct-color
:label (tr "labels.color") :title (tr "labels.color")
:value :direct-color} :id "opt-color"}]
{:id "swap-opt-grid" [:& radio-button {:icon i/tokens
:icon i/tokens :value :token-color
:label (tr "workspace.colorpicker.color-tokens") :title (tr "workspace.colorpicker.color-tokens")
:value :token-color}]}])] :id "opt-token-color"}]])]
(when (and (not= selected-mode :image) (when (and (not= selected-mode :image)
(= color-style :direct-color)) (= color-style :direct-color))
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :picker-btn true
:aria-label (tr "workspace.colorpicker.get-color") :selected picking-color?)
:aria-pressed picking-color? :on-click handle-click-picker}
:on-click handle-click-picker deprecated-icon/picker])
:icon i/picker}])
(when (= color-style :token-color) (when (= color-style :token-color)
[:div {:class (stl/css :token-color-title)} [:div {:class (stl/css :token-color-title)}
@ -485,11 +483,12 @@
:aria-label (tr "media.choose-image") :aria-label (tr "media.choose-image")
:on-click on-fill-image-click} :on-click on-fill-image-click}
(tr "media.choose-image") (tr "media.choose-image")
[:> file-uploader* {:input-id "fill-image-upload" [:& file-uploader
:accept "image/jpeg,image/png" {:input-id "fill-image-upload"
:multi false :accept "image/jpeg,image/png"
:ref fill-image-ref :multi false
:on-selected on-fill-image-selected}]]]) :ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:* [:*
[:div {:class (stl/css :colorpicker-tabs)} [:div {:class (stl/css :colorpicker-tabs)}

View File

@ -46,6 +46,52 @@
width: px2rem(68); width: px2rem(68);
} }
// TODO: change to DS button component
.picker-btn {
display: flex;
justify-content: center;
align-items: center;
border: none;
background: none;
cursor: pointer;
border-radius: $br-8;
background-color: transparent;
border: $b-1 solid transparent;
height: var(--sp-xl);
width: var(--sp-xl);
border-radius: $br-4;
padding: 0;
margin-top: var(--sp-xs);
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: $b-1 solid transparent;
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
&.selected {
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.gradient-buttons { .gradient-buttons {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -30,7 +30,6 @@
[app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.context :as ctx] [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.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
@ -45,6 +44,12 @@
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def ^:private close-icon
(deprecated-icon/icon-xref :close (stl/css :close-icon)))
(def ^:private add-icon
(deprecated-icon/icon-xref :add (stl/css :add-icon)))
(defn- get-library-summary (defn- get-library-summary
"Given a library data return a summary representation of this library" "Given a library data return a summary representation of this library"
[data] [data]
@ -163,10 +168,12 @@
[:div {:class (stl/css :sample-library-item) [:div {:class (stl/css :sample-library-item)
:key (dm/str id)} :key (dm/str id)}
[:div {:class (stl/css :sample-library-item-name)} (:name library)] [:div {:class (stl/css :sample-library-item-name)} (:name library)]
[:> button* {:variant "secondary" [:input {:class (stl/css-case :sample-library-button true
:on-click import-library :sample-library-add (nil? importing?)
:disabled (some? importing?)} :sample-library-adding (some? importing?))
(if (= importing? id) (tr "labels.adding") (tr "labels.add"))]])) :type "button"
:value (if (= importing? id) (tr "labels.adding") (tr "labels.add"))
:on-click import-library}]]))
(defn- empty-library? (defn- empty-library?
"Check if currentt library summary has elements or not" "Check if currentt library summary has elements or not"
@ -315,12 +322,14 @@
[:> library-description* {:summary summary}]]] [:> library-description* {:summary summary}]]]
(if ^boolean is-shared (if ^boolean is-shared
[:> button* {:variant "secondary" [:input {:class (stl/css :item-unpublish)
:on-click unpublish} :type "button"
(tr "common.unpublish")] :value (tr "common.unpublish")
[:> button* {:variant "primary" :on-click unpublish}]
:on-click publish} [:input {:class (stl/css :item-publish)
(tr "common.publish")])] :type "button"
:value (tr "common.publish")
:on-click publish}])]
(for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries] (for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries]
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)] (let [disabled? (some #(contains? linked-libraries-ids %) connected-to)]
@ -368,11 +377,12 @@
(let [summary (-> (:library-summary library) (let [summary (-> (:library-summary library)
(adapt-backend-summary))] (adapt-backend-summary))]
[:> library-description* {:summary summary}])]] [:> library-description* {:summary summary}])]]
[:> icon-button* {:variant "secondary"
:aria-label (tr "workspace.libraries.shared-library-btn") [:button {:class (stl/css :item-button-shared)
:icon i/add :data-library-id (dm/str id)
:data-library-id (dm/str id) :title (tr "workspace.libraries.shared-library-btn")
:on-click link-library}]])] :on-click link-library}
add-icon]])]
(when (empty? shared-libraries) (when (empty? shared-libraries)
[:div {:class (stl/css :section-list-empty)} [:div {:class (stl/css :section-list-empty)}
@ -637,13 +647,11 @@
:on-click close-dialog-outside :on-click close-dialog-outside
:data-testid "libraries-modal"} :data-testid "libraries-modal"}
[:div {:class (stl/css :modal-dialog)} [:div {:class (stl/css :modal-dialog)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css :close-btn)
:class (stl/css :close-btn) :on-click close-dialog
:icon i/close :aria-label (tr "labels.close")
:aria-label (tr "labels.close") :data-testid "close-libraries"}
:data-testid "close-libraries" close-icon]
:on-click close-dialog}]
[:div {:class (stl/css :modal-title)} [:div {:class (stl/css :modal-title)}
(tr "workspace.libraries.libraries")] (tr "workspace.libraries.libraries")]

View File

@ -33,7 +33,7 @@
background-color: var(--modal-background-color); background-color: var(--modal-background-color);
border: $b-2 solid var(--modal-border-color); border: $b-2 solid var(--modal-border-color);
display: grid; display: grid;
grid-template-rows: 0 auto 1fr; grid-template-rows: auto 1fr;
min-width: $sz-364; min-width: $sz-364;
min-height: $sz-192; min-height: $sz-192;
height: $sz-520; height: $sz-520;
@ -42,10 +42,21 @@
max-width: $sz-712; max-width: $sz-712;
} }
// TODO: Remove this extended creating modal component
.close-btn { .close-btn {
position: absolute; @extend .modal-close-btn-base;
top: var(--sp-s); }
right: var(--sp-s);
.close-icon {
display: flex;
justify-content: center;
align-items: center;
height: $sz-16;
width: $sz-16;
color: transparent;
fill: none;
stroke-width: $b-1;
stroke: var(--icon-foreground);
} }
.modal-title { .modal-title {
@ -109,6 +120,46 @@
height: fit-content; height: fit-content;
} }
.item-publish,
.item-unpublish {
// TODO: remove this extended by using DS button component
@extend .button-primary;
@include t.use-typography("headline-small");
height: $sz-32;
min-width: px2rem(92);
padding: var(--sp-s) var(--sp-xxl);
margin: 0;
border-radius: $br-8;
}
.item-unpublish {
// TODO: remove this extended by using DS button component
@extend .button-secondary;
}
.item-button,
.item-button-shared {
// TODO: remove this extended by using DS button component
@extend .button-secondary;
height: $sz-32;
width: $sz-32;
margin-inline-start: var(--sp-xxs);
padding: var(--sp-s);
}
.detach-icon,
.add-icon {
display: flex;
justify-content: center;
align-items: center;
height: $sz-16;
width: $sz-16;
color: transparent;
fill: none;
stroke-width: $b-1;
stroke: var(--icon-foreground);
}
.section-list-shared { .section-list-shared {
max-height: px2rem(272); max-height: px2rem(272);
} }
@ -119,6 +170,26 @@
color: var(--title-foreground-color); color: var(--title-foreground-color);
} }
.search-icon {
display: flex;
justify-content: center;
align-items: center;
width: px2rem(20);
padding: 0 0 0 var(--sp-s);
svg {
display: flex;
justify-content: center;
align-items: center;
color: transparent;
fill: none;
height: px2rem(12);
width: px2rem(12);
stroke-width: 1.33px;
stroke: var(--icon-foreground);
}
}
// empty state // empty state
.section-list-empty { .section-list-empty {
display: grid; display: grid;
@ -357,3 +428,24 @@
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: px2rem(232); max-width: px2rem(232);
} }
// TODO: Remove this extended using a DS component
.sample-library-add {
@extend .button-secondary;
}
// TODO: Remove this extended using a DS component
.sample-library-adding {
@extend .button-disabled;
}
.sample-library-button {
@include t.use-typography("headline-small");
height: $sz-32;
width: px2rem(80);
margin: 0;
border-radius: $br-8;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View File

@ -853,9 +853,8 @@
[:* [:*
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-pressed show-menu?
:aria-label (tr "shortcut-subsection.main-menu") :aria-label (tr "shortcut-subsection.main-menu")
:on-click (if show-menu? close-all-menus open-menu) :on-click open-menu
:icon i/menu}] :icon i/menu}]
[:> dropdown-menu* {:show show-menu? [:> dropdown-menu* {:show show-menu?

View File

@ -18,10 +18,9 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.color-palette :refer [color-palette*]] [app.main.ui.workspace.color-palette :refer [color-palette*]]
[app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]] [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]]
[app.main.ui.workspace.text-palette :refer [text-palette]] [app.main.ui.workspace.text-palette :refer [text-palette]]
@ -179,27 +178,27 @@
[:ul {:class (dm/str size-classname " " (stl/css-case :palette-btn-list true [:ul {:class (dm/str size-classname " " (stl/css-case :palette-btn-list true
:hidden-bts hide-palettes?))} :hidden-bts hide-palettes?))}
[:li {:class (stl/css :palette-item)} [:li {:class (stl/css :palette-item)}
[:> icon-button* {:variant "ghost" [:button {:title (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:aria-pressed (some? color-palette?) :aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) :class (stl/css-case :palette-btn true
:on-click on-select-color-palette :selected color-palette?)
:icon i/drop}]] :on-click on-select-color-palette}
deprecated-icon/drop-icon]]
[:li {:class (stl/css :palette-item)} [:li {:class (stl/css :palette-item)}
[:> icon-button* {:variant "ghost" [:button {:title (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:aria-pressed (some? text-palette?) :aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) :class (stl/css-case :palette-btn true
:on-click on-select-text-palette :selected text-palette?)
:icon i/text-palette}]]] :on-click on-select-text-palette}
deprecated-icon/text-palette]]]
(if any-palette? (if any-palette?
[:* [:*
[:div {:class (stl/css :menu-btn)} [:button {:class (stl/css :palette-actions)
[:> icon-button* {:variant "ghost" :on-click #(swap! state* update :show-menu not)}
:aria-pressed show-menu? deprecated-icon/menu]
:aria-label (tr "labels.options")
:on-click #(swap! state* update :show-menu not)
:icon i/menu}]]
[:div {:class (stl/css :palette) [:div {:class (stl/css :palette)
:ref container} :ref container}
(when text-palette? (when text-palette?

View File

@ -49,6 +49,7 @@
&.wide { &.wide {
width: 100%; width: 100%;
} }
.resize-area { .resize-area {
grid-area: resize; grid-area: resize;
height: deprecated.$s-8; height: deprecated.$s-8;
@ -71,22 +72,49 @@
&.small-palette { &.small-palette {
display: flex; display: flex;
} }
.palette-item {
@include deprecated.flexCenter;
border-radius: deprecated.$br-8;
opacity: deprecated.$op-10;
transition: opacity 1s ease;
.palette-btn {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
border-radius: deprecated.$br-8;
background-clip: padding-box;
padding: 0;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
&.selected {
@extend .button-icon-selected;
}
}
}
}
.palette-actions {
@extend .button-tertiary;
grid-area: actions;
height: calc(var(--height) - deprecated.$s-16);
width: deprecated.$s-32;
padding: 0;
margin-left: deprecated.$s-4;
border-radius: deprecated.$br-8;
background-color: var(--palette-background-color);
z-index: deprecated.$z-index-2;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
} }
.palette { .palette {
grid-area: palette; grid-area: palette;
width: 100%; width: 100%;
min-width: 0; min-width: 0;
} }
.palette-item {
display: flex;
align-items: center;
}
}
.menu-btn {
display: flex;
align-items: center;
margin-left: var(--sp-s);
} }
.handler { .handler {

View File

@ -29,7 +29,7 @@
:style {:background-color color} :style {:background-color color}
:src (cfg/resolve-profile-photo-url profile)}]])) :src (cfg/resolve-profile-photo-url profile)}]]))
(mf/defc active-sessions* (mf/defc active-sessions
{::mf/memo true} {::mf/memo true}
[] []
(let [profiles (mf/deref refs/profiles) (let [profiles (mf/deref refs/profiles)

View File

@ -20,19 +20,23 @@
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.dashboard.team] [app.main.ui.dashboard.team]
[app.main.ui.ds.buttons.button :refer [button*]]
[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 :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.exports.assets :refer [progress-widget*]] [app.main.ui.exports.assets :refer [progress-widget]]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.workspace.presence :refer [active-sessions*]] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.presence :refer [active-sessions]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def ref:persistence-status
(l/derived :status refs/persistence))
;; --- Zoom Widget ;; --- Zoom Widget
(mf/defc zoom-widget-workspace* (mf/defc zoom-widget-workspace
{::mf/wrap [mf/memo] {::mf/wrap [mf/memo]
::mf/wrap-props false} ::mf/wrap-props false}
[{:keys [zoom on-increase on-decrease on-zoom-reset on-zoom-fit on-zoom-selected]}] [{:keys [zoom on-increase on-decrease on-zoom-reset on-zoom-fit on-zoom-selected]}]
@ -68,12 +72,11 @@
zoom (fmt/format-percent zoom {:precision 0})] zoom (fmt/format-percent zoom {:precision 0})]
[:* [:*
[:div {:on-click (if open? close-dropdown open-dropdown) [:div {:on-click open-dropdown
:class (stl/css-case :zoom-widget true :class (stl/css-case :zoom-widget true
:selected open?) :selected open?)
:title (tr "workspace.header.zoom")} :title (tr "workspace.header.zoom")}
[:span {:class (stl/css :label)} zoom]] [:span {:class (stl/css :label)} zoom]]
[:& dropdown {:show open? :on-close close-dropdown} [:& dropdown {:show open? :on-close close-dropdown}
[:ul {:class (stl/css :dropdown)} [:ul {:class (stl/css :dropdown)}
[:li {:class (stl/css :basic-zoom-bar)} [:li {:class (stl/css :basic-zoom-bar)}
@ -87,10 +90,9 @@
:aria-label (tr "shortcuts.increase-zoom") :aria-label (tr "shortcuts.increase-zoom")
:on-click on-increase :on-click on-increase
:icon i/add}]] :icon i/add}]]
[:> button* {:variant "ghost" [:button {:class (stl/css :reset-btn)
:on-click on-zoom-reset} :on-click on-zoom-reset}
(tr "workspace.header.reset-zoom")]] (tr "workspace.header.reset-zoom")]]
[:li {:class (stl/css :zoom-option) [:li {:class (stl/css :zoom-option)
:on-click on-zoom-fit} :on-click on-zoom-fit}
(tr "workspace.header.zoom-fit-all") (tr "workspace.header.zoom-fit-all")
@ -98,7 +100,6 @@
(for [sc (scd/split-sc (sc/get-tooltip :fit-all))] (for [sc (scd/split-sc (sc/get-tooltip :fit-all))]
[:span {:class (stl/css :shortcut-key) [:span {:class (stl/css :shortcut-key)
:key (str "zoom-fit-" sc)} sc])]] :key (str "zoom-fit-" sc)} sc])]]
[:li {:class (stl/css :zoom-option) [:li {:class (stl/css :zoom-option)
:on-click on-zoom-selected} :on-click on-zoom-selected}
(tr "workspace.header.zoom-selected") (tr "workspace.header.zoom-selected")
@ -197,43 +198,51 @@
[:div {:class (stl/css :workspace-header-right)} [:div {:class (stl/css :workspace-header-right)}
[:div {:class (stl/css :users-section)} [:div {:class (stl/css :users-section)}
[:> active-sessions*]] [:& active-sessions]]
[:> progress-widget*] [:& progress-widget]
[:div {:class (stl/css :separator)}] [:div {:class (stl/css :separator)}]
[:div {:class (stl/css :zoom-section)} [:div {:class (stl/css :zoom-section)}
[:> zoom-widget-workspace* {:zoom zoom [:& zoom-widget-workspace
:on-increase on-increase {:zoom zoom
:on-decrease on-decrease :on-increase on-increase
:on-zoom-reset on-zoom-reset :on-decrease on-decrease
:on-zoom-fit on-zoom-fit :on-zoom-reset on-zoom-reset
:on-zoom-selected on-zoom-selected}]] :on-zoom-fit on-zoom-fit
:on-zoom-selected on-zoom-selected}]]
[:div {:class (stl/css :comments-button-wrapper)} [:div {:class (stl/css :comments-section)}
[:> icon-button* {:variant "ghost" [:button {:title (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
:aria-pressed (= selected-drawtool :comments) :aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
:aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment)) :class (stl/css-case :comments-btn true
:on-click toggle-comments :selected (= selected-drawtool :comments))
:icon i/comments}] :on-click toggle-comments
(when ^boolean has-unread-comments? :data-tool "comments"
[:div {:class (stl/css :unread)}])] :style {:position "relative"}}
deprecated-icon/comments
(when ^boolean has-unread-comments?
[:div {:class (stl/css :unread)}])]]
(when-not ^boolean read-only? (when-not ^boolean read-only?
[:> icon-button* {:variant "ghost" [:div {:class (stl/css :history-section)}
:aria-pressed (contains? layout :document-history) [:button
:aria-label (tr "workspace.sidebar.history") {:title (tr "workspace.sidebar.history")
:on-click toggle-history :aria-label (tr "workspace.sidebar.history")
:icon i/history}]) :class (stl/css-case :selected (contains? layout :document-history)
:history-button true)
:on-click toggle-history}
deprecated-icon/history]])
(when display-share-button? (when display-share-button?
[:> icon-button* {:variant "ghost" [:a {:class (stl/css :viewer-btn)
:aria-label (tr "workspace.header.share") :title (tr "workspace.header.share")
:on-click open-share-dialog :on-click open-share-dialog}
:icon i/to-corner}]) deprecated-icon/share])
[:a {:class (stl/css :viewer-btn)
:title (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer))
:on-click nav-to-viewer}
deprecated-icon/play]]))
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer))
:on-click nav-to-viewer
:icon i/play}]]))

View File

@ -11,8 +11,8 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
min-width: deprecated.$s-256; min-width: deprecated.$s-256;
padding: deprecated.$s-8 deprecated.$s-12; padding: deprecated.$s-8;
gap: deprecated.$s-4; gap: deprecated.$s-8;
background-color: var(--panel-background-color); background-color: var(--panel-background-color);
} }
@ -28,14 +28,19 @@
} }
.zoom-widget { .zoom-widget {
@include deprecated.buttonStyle;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: deprecated.$s-28;
max-width: deprecated.$s-48;
width: deprecated.$s-48; width: deprecated.$s-48;
height: deprecated.$s-32; border-radius: deprecated.$br-8;
.label { .label {
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;
height: 100%;
padding: deprecated.$s-8 0;
color: var(--button-tertiary-foreground-color-rest); color: var(--button-tertiary-foreground-color-rest);
} }
@ -79,6 +84,13 @@
color: var(--modal-title-foreground-color); color: var(--modal-title-foreground-color);
} }
.reset-btn {
@extend .button-tertiary;
color: var(--button-tertiary-foreground-color-hover);
height: deprecated.$s-28;
border-radius: deprecated.$br-8;
}
.zoom-option { .zoom-option {
@extend .menu-item-base; @extend .menu-item-base;
@ -101,11 +113,127 @@
} }
} }
.comments-button-wrapper { .comments-btn {
position: relative; @extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
height: deprecated.$s-28;
width: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
height: deprecated.$s-16;
width: deprecated.$s-16;
}
&:hover {
background-color: transparent;
border: none;
}
&.selected {
background-color: var(--button-tertiary-background-color-selected);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
} }
.comments-button-unread { .history-button {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
height: deprecated.$s-28;
width: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
height: deprecated.$s-16;
width: deprecated.$s-16;
}
&:hover {
background-color: transparent;
border: none;
}
&.selected {
background-color: var(--button-tertiary-background-color-selected);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.persistence-status-widget {
@include deprecated.flexCenter;
width: deprecated.$s-28;
height: deprecated.$s-28;
}
.status-icon {
@include deprecated.flexCenter;
width: deprecated.$s-24;
height: deprecated.$s-24;
margin: 0;
border-radius: deprecated.$br-circle;
svg {
@extend .button-icon;
stroke: var(--status-widget-icon-foreground-color);
}
}
.pending-status {
background-color: var(--status-widget-background-color-warning);
}
.saving-status {
background-color: var(--status-widget-background-color-pending);
svg {
animation: spin-animation 1s infinite;
animation-timing-function: linear;
}
}
.saved-status {
background-color: var(--status-widget-background-color-success);
}
.error-status {
background-color: var(--status-widget-background-color-error);
}
.share-btn,
.viewer-btn {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
width: deprecated.$s-28;
height: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:hover {
background-color: transparent;
border: none;
}
}
.unread {
position: absolute; position: absolute;
width: 8px; width: 8px;
height: 8px; height: 8px;

View File

@ -17,9 +17,8 @@
[app.main.ui.components.context-menu-a11y :refer [context-menu*]] [app.main.ui.components.context-menu-a11y :refer [context-menu*]]
[app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.context :as ctx] [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.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.sidebar.assets.file-library :refer [file-library*]] [app.main.ui.workspace.sidebar.assets.file-library :refer [file-library*]]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -162,40 +161,43 @@
:id "typographies" :id "typographies"
:handler on-section-filter-change}])] :handler on-section-filter-change}])]
[:article {:class (stl/css :assets-bar)} [:article {:class (stl/css :assets-bar)}
[:div {:class (stl/css :assets-header)} [:div {:class (stl/css :assets-header)}
(when-not ^boolean read-only? (when-not ^boolean read-only?
(if (and (= num-libs 1) (empty? components)) (if (and (= num-libs 1) (empty? components))
[:> button* {:variant "primary" [:button {:class (stl/css :add-library-button)
:on-click show-libraries-dialog :on-click show-libraries-dialog
:data-testid "libraries"} :data-testid "libraries"}
(tr "workspace.assets.add-library")] (tr "workspace.assets.add-library")]
[:> button* {:variant "secondary"
:on-click show-libraries-dialog [:button {:class (stl/css :libraries-button)
:data-testid "libraries"} :on-click show-libraries-dialog
:data-testid "libraries"}
(tr "workspace.assets.manage-library")])) (tr "workspace.assets.manage-library")]))
[:div {:class (stl/css :search-wrapper)} [:div {:class (stl/css :search-wrapper)}
[:> search-bar* {:on-change on-search-term-change [:> search-bar* {:on-change on-search-term-change
:value term :value term
:placeholder (tr "workspace.assets.search")} :placeholder (tr "workspace.assets.search")}
[:> icon-button* {:variant "secondary" [:button
:icon i/filter {:on-click on-open-menu
:class (stl/css :filter-button) :title (tr "workspace.assets.filter")
:aria-pressed menu-open? :class (stl/css-case :section-button true
:aria-label (tr "workspace.assets.filter") :opened menu-open?)}
:on-click on-open-menu}]] deprecated-icon/filter-icon]]
[:> context-menu* {:on-close on-menu-close [:> context-menu*
:selectable true {:on-close on-menu-close
:selected section :selectable true
:show menu-open? :selected section
:fixed true :show menu-open?
:min-width true :fixed true
:width size :min-width true
:top 158 :width size
:left 18 :top 158
:options options}] :left 18
:options options}]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.sort") :aria-label (tr "workspace.assets.sort")

View File

@ -17,14 +17,89 @@
padding-top: deprecated.$s-8; padding-top: deprecated.$s-8;
} }
.assets-header { .libraries-button {
display: flex; @extend .button-secondary;
flex-direction: column; @include deprecated.uppercaseTitleTipography;
gap: var(--sp-xxs); gap: deprecated.$s-2;
height: deprecated.$s-32;
width: 100%;
margin-bottom: deprecated.$s-4;
border-radius: deprecated.$s-8;
&:hover {
background-color: var(--button-secondary-background-color-hover);
color: var(--button-secondary-foreground-color-hover);
border: deprecated.$s-1 solid var(--button-secondary-border-color-hover);
}
&:focus {
background-color: var(--button-secondary-background-color-focus);
color: var(--button-secondary-foreground-color-focus);
border: deprecated.$s-1 solid var(--button-secondary-border-color-focus);
}
} }
.filter-button { .add-library-button {
border-radius: deprecated.$br-8 0 0 deprecated.$br-8; @extend .button-primary;
@include deprecated.uppercaseTitleTipography;
gap: deprecated.$s-2;
height: deprecated.$s-32;
width: 100%;
margin-bottom: deprecated.$s-4;
border-radius: deprecated.$s-8;
}
.section-button {
@include deprecated.flexCenter;
@include deprecated.buttonStyle;
height: deprecated.$s-32;
width: deprecated.$s-32;
margin: 0;
border: deprecated.$s-1 solid var(--input-border-color-rest);
border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8;
background-color: var(--input-background-color-rest);
svg {
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-focus);
color: var(--input-foreground-color-focus);
svg {
background-color: var(--input-background-color-focus);
}
}
&:hover {
border: deprecated.$s-1 solid var(--input-border-color-hover);
background-color: var(--input-background-color-hover);
svg {
background-color: var(--input-background-color-hover);
stroke: var(--button-foreground-hover);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-focus);
color: var(--input-foreground-color-focus);
svg {
background-color: var(--input-background-color-focus);
}
}
}
&.opened {
@extend .button-icon-selected;
}
} }
.sections-container { .sections-container {
@ -50,6 +125,10 @@
border-radius: deprecated.$br-8; border-radius: deprecated.$br-8;
} }
.section-btn {
@include deprecated.buttonStyle;
}
.assets-header { .assets-header {
padding: 0 0 deprecated.$s-24 deprecated.$s-12; padding: 0 0 deprecated.$s-24 deprecated.$s-12;
} }

View File

@ -22,10 +22,10 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.editable-label :refer [editable-label*]] [app.main.ui.components.editable-label :refer [editable-label*]]
[app.main.ui.components.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.common :as cmm]
@ -563,27 +563,27 @@
[:> cmm/asset-section-block* {:role :title-button} [:> cmm/asset-section-block* {:role :title-button}
(when ^boolean is-open (when ^boolean is-open
[:div [:div
[:> radio-buttons* {:selected (if is-listing-thumbs "grid" "list") [:& radio-buttons {:selected (if is-listing-thumbs "grid" "list")
:on-change toggle-list-style :on-change toggle-list-style
:name "listing-style" :name "listing-style"}
:options [{:id "opt-list" [:& radio-button {:icon i/view-as-list
:icon i/view-as-list :value "list"
:label (tr "workspace.assets.list-view") :title (tr "workspace.assets.list-view")
:value "list"} :id "opt-list"}]
{:id "opt-grid" [:& radio-button {:icon i/flex-grid
:icon i/flex-grid :value "grid"
:label (tr "workspace.assets.grid-view") :title (tr "workspace.assets.grid-view")
:value "grid"}]}]]) :id "opt-grid"}]]])
(when (and (not read-only?) is-local) (when (and (not read-only?) is-local)
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.components.add-component") :aria-label (tr "workspace.assets.components.add-component")
:on-click add-component :on-click add-component
:icon i/add} :icon i/add}
[:> file-uploader* {:accept dwm/accept-image-types [:& file-uploader {:accept dwm/accept-image-types
:multi true :multi true
:ref input-ref :ref input-ref
:on-selected on-file-selected}]])] :on-selected on-file-selected}]])]
[:> cmm/asset-section-block* {:role :content} [:> cmm/asset-section-block* {:role :content}
(when ^boolean is-open (when ^boolean is-open

View File

@ -23,7 +23,7 @@
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.sidebar.assets.groups :as grp] [app.main.ui.workspace.sidebar.assets.groups :as grp]
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry*]] [app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str] [cuerdas.core :as str]
@ -113,17 +113,18 @@
:on-drag-over dom/prevent-default :on-drag-over dom/prevent-default
:on-drop on-drop} :on-drop on-drop}
[:> typography-entry* {:file-id file-id [:& typography-entry
:typography typography {:file-id file-id
:local? local? :typography typography
:selected? (contains? selected typography-id) :local? local?
:on-click on-asset-click :selected? (contains? selected typography-id)
:on-change handle-change :on-click on-asset-click
:on-context-menu on-context-menu :on-change handle-change
:editing? editing? :on-context-menu on-context-menu
:renaming? renaming? :editing? editing?
:focus-name? rename? :renaming? renaming?
:external-open* open*}] :focus-name? rename?
:external-open* open*}]
(when ^boolean dragging? (when ^boolean dragging?
[:div {:class (stl/css :dragging)}])])) [:div {:class (stl/css :dragging)}])]))

View File

@ -291,12 +291,13 @@
:value current-search :value current-search
:on-clear clear-search-text :on-clear clear-search-text
:placeholder (tr "workspace.sidebar.layers.search")} :placeholder (tr "workspace.sidebar.layers.search")}
[:> icon-button* {:variant "secondary" [:button {:on-click on-toggle-filters-click
:class (stl/css :filter-button) :class (stl/css-case
:aria-pressed show-menu? :filter-button true
:aria-label (tr "workspace.sidebar.layers.filter") :opened show-menu?
:on-click on-toggle-filters-click :active active?)}
:icon i/filter}]] [:> icon* {:icon-id i/filter}]]]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "labels.close") :aria-label (tr "labels.close")
:on-click toggle-search :on-click toggle-search

View File

@ -19,7 +19,39 @@
padding: 0 deprecated.$s-12 0 deprecated.$s-8; padding: 0 deprecated.$s-12 0 deprecated.$s-8;
gap: deprecated.$s-4; gap: deprecated.$s-4;
.filter-button { .filter-button {
border-radius: deprecated.$br-8 0 0 deprecated.$br-8; @include deprecated.flexCenter;
@include deprecated.buttonStyle;
height: deprecated.$s-32;
width: deprecated.$s-32;
margin: 0;
border: deprecated.$s-1 solid var(--color-background-tertiary);
border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8;
background-color: var(--color-background-tertiary);
svg {
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-active);
color: var(--input-foreground-color-active);
svg {
background-color: var(--input-background-color-active);
}
}
&:hover {
border: deprecated.$s-1 solid var(--input-border-color-hover);
background-color: var(--input-background-color-hover);
svg {
background-color: var(--input-background-color-hover);
stroke: var(--button-foreground-hover);
}
}
&.opened {
@extend .button-icon-selected;
}
} }
} }
} }
@ -111,7 +143,7 @@
.filters-container { .filters-container {
@extend .menu-dropdown; @extend .menu-dropdown;
position: absolute; position: absolute;
left: deprecated.$s-16; left: deprecated.$s-20;
width: deprecated.$s-192; width: deprecated.$s-192;
.filter-menu-item { .filter-menu-item {
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;

View File

@ -12,7 +12,7 @@
[app.main.data.workspace.drawing :as dwd] [app.main.data.workspace.drawing :as dwd]
[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.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -95,15 +95,15 @@
(when preset-match (when preset-match
[:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]]
[:> radio-buttons* {:class (stl/css :radio-buttons) [:& radio-buttons {:selected (or (d/name orientation) "")
:selected (or (d/name orientation) "") :on-change on-orientation-change
:on-change on-orientation-change :name "frame-orientation"
:name "frame-orientation" :wide true
:options [{:id "size-vertical" :class (stl/css :radio-buttons)}
:icon i/size-vertical [:& radio-button {:icon i/size-vertical
:label (tr "workspace.options.orientation.vertical") :value "vertical"
:value "vertical"} :id "size-vertical"}]
{:id "size-horizontal" [:& radio-button {:icon i/size-horizontal
:icon i/size-horizontal :value "horizontal"
:label (tr "workspace.options.orientation.horizontal") :id "size-horizontal"}]]]))
:value "horizontal"}]}]]))

View File

@ -10,8 +10,7 @@
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.shortcuts :as sc] [app.main.data.workspace.shortcuts :as sc]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -43,59 +42,68 @@
(when-not (and disabled-align disabled-distribute) (when-not (and disabled-align disabled-distribute)
[:div {:class (stl/css :align-options)} [:div {:class (stl/css :align-options)}
[:div {:class (stl/css :align-group-horizontal)} [:div {:class (stl/css :align-group-horizontal)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-left :disabled disabled-align)
:aria-label (tr "workspace.align.hleft" (sc/get-tooltip :align-left)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.hleft" (sc/get-tooltip :align-left))
:data-value "hleft" :data-value "hleft"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-left]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-horizontal-center :disabled disabled-align)
:aria-label (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter))
:data-value "hcenter" :data-value "hcenter"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-horizontal-center]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-right :disabled disabled-align)
:aria-label (tr "workspace.align.hright" (sc/get-tooltip :align-right)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.hright" (sc/get-tooltip :align-right))
:data-value "hright" :data-value "hright"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-right]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/distribute-horizontally :disabled disabled-distribute)
:aria-label (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute)) :disabled disabled-distribute
:on-click distribute-objects :title (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute))
:data-value "horizontal" :data-value "horizontal"
:disabled disabled-distribute}]] :on-click distribute-objects}
deprecated-icon/distribute-horizontally]]
[:div {:class (stl/css :align-group-vertical)} [:div {:class (stl/css :align-group-vertical)}
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-top :disabled disabled-align)
:aria-label (tr "workspace.align.vtop" (sc/get-tooltip :align-top)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.vtop" (sc/get-tooltip :align-top))
:data-value "vtop" :data-value "vtop"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-top]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-vertical-center :disabled disabled-align)
:aria-label (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter))
:data-value "vcenter" :data-value "vcenter"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-vertical-center]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :align-button true
:icon i/align-bottom :disabled disabled-align)
:aria-label (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom)) :disabled disabled-align
:on-click align-objects :title (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom))
:data-value "vbottom" :data-value "vbottom"
:disabled disabled-align}] :on-click align-objects}
deprecated-icon/align-bottom]
[:button {:title (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:class (stl/css-case :align-button true
:disabled disabled-distribute)
:disabled disabled-distribute
:data-value "vertical"
:on-click distribute-objects}
deprecated-icon/distribute-vertical-spacing]]])))
[:> icon-button* {:variant "ghost"
:icon i/distribute-vertical-spacing
:aria-label (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:on-click distribute-objects
:data-value "vertical"
:disabled disabled-distribute}]]])))

View File

@ -4,10 +4,12 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated;
@use "../../../sidebar/common/sidebar.scss" as sidebar; @use "../../../sidebar/common/sidebar.scss" as sidebar;
.align-options { .align-options {
@include sidebar.option-grid-structure; @include sidebar.option-grid-structure;
height: deprecated.$s-32;
} }
.align-group-horizontal, .align-group-horizontal,
.align-group-vertical { .align-group-vertical {
@ -24,3 +26,27 @@
.align-group-vertical { .align-group-vertical {
grid-column: 5 / span 4; grid-column: 5 / span 4;
} }
.align-button {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
padding: 0;
border-radius: deprecated.$br-8;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
&.disabled {
cursor: default;
svg {
stroke: var(--button-foreground-color-disabled);
}
&:hover {
background-color: var(--panel-background-color);
svg {
stroke: var(--button-foreground-color-disabled);
}
}
}
}

View File

@ -15,6 +15,7 @@
[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 :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -102,12 +103,10 @@
[:div {:class (stl/css-case :first-row true [:div {:class (stl/css-case :first-row true
:hidden hidden?)} :hidden hidden?)}
[:div {:class (stl/css :blur-info)} [:div {:class (stl/css :blur-info)}
[:> icon-button* {:variant "secondary" [:button {:class (stl/css-case :show-more true
:class (stl/css :show-more) :selected more-options?)
:aria-label (tr "labels.options") :on-click toggle-more-options}
:aria-pressed more-options? deprecated-icon/menu]
:on-click toggle-more-options
:icon i/menu}]
[:span {:class (stl/css :label)} [:span {:class (stl/css :label)}
(tr "workspace.options.blur-options.title")]] (tr "workspace.options.blur-options.title")]]
[:div {:class (stl/css :actions)} [:div {:class (stl/css :actions)}

View File

@ -37,7 +37,21 @@
border-radius: deprecated.$br-8; border-radius: deprecated.$br-8;
background-color: var(--input-details-color); background-color: var(--input-details-color);
.show-more { .show-more {
@extend .button-secondary;
height: deprecated.$s-32;
width: deprecated.$s-28;
border-radius: deprecated.$br-8 0 0 deprecated.$br-8; border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
box-sizing: border-box;
border: deprecated.$s-1 solid var(--button-secondary-background-color-rest);
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-radio-background-color-active);
svg {
stroke: var(--button-radio-foreground-color-active);
}
}
} }
.label { .label {
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;

View File

@ -15,12 +15,15 @@
[app.main.data.workspace.shortcuts :as sc] [app.main.data.workspace.shortcuts :as sc]
[app.main.features :as features] [app.main.features :as features]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def ^:private flatten-icon
(deprecated-icon/icon-xref :boolean-flatten (stl/css :flatten-icon)))
(mf/defc bool-options* (mf/defc bool-options*
[{:keys [total-selected shapes shapes-with-children]}] [{:keys [total-selected shapes shapes-with-children]}]
(let [head (first shapes) (let [head (first shapes)
@ -67,40 +70,41 @@
(st/emit! (dwb/change-bool-type head-id bool-type))))))) (st/emit! (dwb/change-bool-type head-id bool-type)))))))
flatten-objects flatten-objects
(mf/use-fn (mf/use-fn #(st/emit! (dwps/convert-selected-to-path)))]
#(st/emit! (dwps/convert-selected-to-path)))]
(when (not (and disabled-bool-btns disabled-flatten)) (when (not (and disabled-bool-btns disabled-flatten))
[:div {:class (stl/css :boolean-options)} [:div {:class (stl/css :boolean-options)}
[:div {:class (stl/css :boolean-group)} [:div {:class (stl/css :bool-group)}
[:> radio-buttons* {:class (stl/css :boolean-radio-btn) [:& radio-buttons {:selected (d/name head-bool-type)
:variant "ghost" :class (stl/css :boolean-radio-btn)
:selected (d/name head-bool-type) :on-change on-change
:on-change on-change :name "bool-options"}
:name "bool-options" [:& radio-button {:icon i/boolean-union
:options [{:id "bool-opt-union" :value "union"
:icon i/boolean-union :disabled disabled-bool-btns
:label (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")") :title (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
:value "union" :id "bool-opt-union"}]
:disabled disabled-bool-btns} [:& radio-button {:icon i/boolean-difference
{:id "bool-opt-differente" :value "difference"
:icon i/boolean-difference :disabled disabled-bool-btns
:label (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")") :title (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
:value "difference" :id "bool-opt-differente"}]
:disabled disabled-bool-btns} [:& radio-button {:icon i/boolean-intersection
{:id "bool-opt-intersection" :value "intersection"
:icon i/boolean-intersection :disabled disabled-bool-btns
:label (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")") :title (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:value "intersection" :id "bool-opt-intersection"}]
:disabled disabled-bool-btns} [:& radio-button {:icon i/boolean-exclude
{:id "bool-opt-exclude" :value "exclude"
:icon i/boolean-exclude :disabled disabled-bool-btns
:label (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")") :title (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:value "exclude" :id "bool-opt-exclude"}]]]
:disabled disabled-bool-btns}]}]]
[:> icon-button* {:variant "ghost" [:button
:icon i/boolean-flatten {:title (tr "workspace.shape.menu.flatten")
:aria-label (tr "workspace.shape.menu.flatten") :class (stl/css-case
:on-click flatten-objects :flatten-button true
:disabled disabled-flatten}]]))) :disabled disabled-flatten)
:disabled disabled-flatten
:on-click flatten-objects}
flatten-icon]])))

View File

@ -4,18 +4,45 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated;
@use "../../../sidebar/common/sidebar.scss" as sidebar; @use "../../../sidebar/common/sidebar.scss" as sidebar;
.boolean-options { .boolean-options {
@include sidebar.option-grid-structure; @include sidebar.option-grid-structure;
height: var(--sp-xxxl);
} }
.boolean-group { .bool-group {
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
grid-column: 1 / span 4; grid-column: 1 / span 4;
} }
.flatten-button {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
border-radius: deprecated.$br-8;
grid-column: 5 / span 1;
--flatten-icon-foreground-color: var(--icon-foreground);
&.disabled {
cursor: default;
--flatten-icon-foreground-color: var(--button-foreground-color-disabled);
&:hover {
background-color: var(--panel-background-color);
--flatten-icon-foreground-color: var(--button-foreground-color-disabled);
}
}
}
.flatten-icon {
@extend .button-icon;
stroke: var(--flatten-icon-foreground-color);
}
.boolean-radio-btn { .boolean-radio-btn {
background-color: transparent; background-color: transparent;
gap: var(--sp-xs);
} }

View File

@ -333,9 +333,9 @@
:on-change on-radius-r3-change :on-change on-radius-r3-change
:value (:r3 values)}]]])) :value (:r3 values)}]]]))
[:> icon-button* {:variant "ghost" [:> icon-button* {:class (stl/css-case :selected radius-expanded)
:variant "ghost"
:on-click toggle-radius-mode :on-click toggle-radius-mode
:aria-pressed radius-expanded
:aria-label (if radius-expanded :aria-label (if radius-expanded
(tr "workspace.options.radius.hide-all-corners") (tr "workspace.options.radius.hide-all-corners")
(tr "workspace.options.radius.show-single-corners")) (tr "workspace.options.radius.show-single-corners"))

View File

@ -36,6 +36,12 @@
color: var(--color-accent-primary); color: var(--color-accent-primary);
} }
.selected {
border-color: var(--button-icon-border-color-selected);
background-color: var(--button-icon-background-color-selected);
color: var(--button-icon-foreground-color-selected);
}
.icon { .icon {
margin-inline: var(--sp-xs); margin-inline: var(--sp-xs);
} }

View File

@ -13,7 +13,6 @@
[app.main.data.workspace.tokens.application :as dwta] [app.main.data.workspace.tokens.application :as dwta]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -218,8 +217,8 @@
:origin :color-selection :origin :color-selection
:on-close on-close}])) :on-close on-close}]))
(when (and (false? @expand-lib-color) (< 3 (count library-colors))) (when (and (false? @expand-lib-color) (< 3 (count library-colors)))
[:> button* {:variant "secondary" [:button {:class (stl/css :more-colors-btn)
:on-click #(reset! expand-lib-color true)} :on-click #(reset! expand-lib-color true)}
(tr "workspace.options.more-lib-colors")])] (tr "workspace.options.more-lib-colors")])]
[:div {:class (stl/css :selected-color-group)} [:div {:class (stl/css :selected-color-group)}
@ -236,8 +235,8 @@
:on-close on-close}]) :on-close on-close}])
(when (and (false? @expand-color) (< 3 (count colors))) (when (and (false? @expand-color) (< 3 (count colors)))
[:> button* {:variant "secondary" [:button {:class (stl/css :more-colors-btn)
:on-click #(reset! expand-color true)} :on-click #(reset! expand-color true)}
(tr "workspace.options.more-colors")])] (tr "workspace.options.more-colors")])]
[:div {:class (stl/css :selected-color-group)} [:div {:class (stl/css :selected-color-group)}
@ -260,6 +259,6 @@
(when (and (false? @expand-token-color) (when (and (false? @expand-token-color)
(< 3 (count token-colors))) (< 3 (count token-colors)))
[:> button* {:variant "secondary" [:button {:class (stl/css :more-colors-btn)
:on-click #(reset! expand-token-color true)} :on-click #(reset! expand-token-color true)}
(tr "workspace.options.more-token-colors")])]])])) (tr "workspace.options.more-token-colors")])]])]))

View File

@ -40,5 +40,7 @@
} }
.more-colors-btn { .more-colors-btn {
justify-content: center; @extend .button-secondary;
@include deprecated.uppercaseTitleTipography;
height: deprecated.$s-32;
} }

View File

@ -28,6 +28,7 @@
[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.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.reorder-handler :refer [reorder-handler*]] [app.main.ui.components.reorder-handler :refer [reorder-handler*]]
[app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
@ -36,7 +37,6 @@
[app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.combobox :refer [combobox*]] [app.main.ui.ds.controls.combobox :refer [combobox*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.controls.select :refer [select*]] [app.main.ui.ds.controls.select :refer [select*]]
[app.main.ui.ds.controls.switch :refer [switch*]] [app.main.ui.ds.controls.switch :refer [switch*]]
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
@ -794,17 +794,15 @@
[:div {:class (stl/css :swap-library)} [:div {:class (stl/css :swap-library)}
[:div {:class (stl/css :swap-library-title)} [:div {:class (stl/css :swap-library-title)}
[:div {:class (stl/css :swap-library-name)} current-lib-name] [:div {:class (stl/css :swap-library-name)} current-lib-name]
[:> radio-buttons* {:selected (if (:listing-thumbs? filters) "grid" "list") [:& radio-buttons {:selected (if (:listing-thumbs? filters) "grid" "list")
:on-change toggle-list-style :on-change toggle-list-style
:name "swap-listing-style" :name "swap-listing-style"}
:options [{:id "swap-opt-list" [:& radio-button {:icon i/view-as-list
:icon i/view-as-list :value "list"
:label (tr "workspace.assets.list-view") :id "swap-opt-list"}]
:value "list"} [:& radio-button {:icon i/flex-grid
{:id "swap-opt-grid" :value "grid"
:icon i/flex-grid :id "swap-opt-grid"}]]]
:label (tr "workspace.assets.grid-view")
:value "grid"}]}]]
(when-not (or search? (str/empty? (:path filters))) (when-not (or search? (str/empty? (:path filters)))
[:button {:class (stl/css :swap-library-back) [:button {:class (stl/css :swap-library-back)
@ -899,13 +897,11 @@
(when menu-entries? (when menu-entries?
[:div {:class (stl/css :pill-actions)} [:div {:class (stl/css :pill-actions)}
[:> icon-button* {:variant "secondary" [:button {:class (stl/css-case :pill-actions-btn true
:class (stl/css-case :pill-actions-btn true :selected menu-open?)
:extended subtext) :on-click on-menu-click}
:aria-pressed menu-open? [:> icon* {:icon-id i/menu}]]
:aria-label (tr "labels.options")
:on-click on-menu-click
:icon i/menu}]
[:& dropdown {:show menu-open? [:& dropdown {:show menu-open?
:on-close on-menu-close} :on-close on-menu-close}
[:ul {:class (stl/css-case :pill-actions-dropdown true [:ul {:class (stl/css-case :pill-actions-dropdown true

View File

@ -587,9 +587,14 @@
} }
.pill-actions-btn { .pill-actions-btn {
@extend .button-secondary;
cursor: unset;
block-size: 100%;
inline-size: 100%;
border-radius: 0 $br-8 $br-8 0; border-radius: 0 $br-8 $br-8 0;
&.extended {
block-size: $sz-48; &.selected {
@extend .button-icon-selected;
} }
} }

View File

@ -16,7 +16,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.controls.checkbox :refer [checkbox*]] [app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str] [cuerdas.core :as str]
@ -61,7 +61,6 @@
constraints-h (or (get values :constraints-h) (gsh/default-constraints-h values)) constraints-h (or (get values :constraints-h) (gsh/default-constraints-h values))
constraints-v (or (get values :constraints-v) (gsh/default-constraints-v values)) constraints-v (or (get values :constraints-v) (gsh/default-constraints-v values))
fixed-scroll? (d/nilv (:fixed-scroll values) false)
on-constraint-button-clicked on-constraint-button-clicked
(mf/use-fn (mf/use-fn
@ -219,8 +218,16 @@
:options options-v :options options-v
:on-change on-constraint-v-select-changed}]] :on-change on-constraint-v-select-changed}]]
(when first-level? (when first-level?
[:> checkbox* {:id "fixed-on-scroll" [:div {:class (stl/css :checkbox)}
:class (stl/css :checkbox)
:label (tr "workspace.options.constraints.fix-when-scrolling") [:label {:for "fixed-on-scroll"
:checked fixed-scroll? :class (stl/css-case :checked (:fixed-scroll values))}
:on-change on-fixed-scroll-clicked}])]])]))) [:span {:class (stl/css-case :check-mark true
:checked (:fixed-scroll values))}
(when (:fixed-scroll values)
deprecated-icon/status-tick)]
(tr "workspace.options.constraints.fix-when-scrolling")
[:input {:type "checkbox"
:id "fixed-on-scroll"
:checked (:fixed-scroll values)
:on-change on-fixed-scroll-clicked}]]])]])])))

View File

@ -137,4 +137,36 @@
margin-bottom: deprecated.$s-8; margin-bottom: deprecated.$s-8;
margin-top: deprecated.$s-8; margin-top: deprecated.$s-8;
padding-left: 0; padding-left: 0;
input {
margin: 0;
}
label {
@include deprecated.bodySmallTypography;
display: flex;
align-items: center;
gap: deprecated.$s-2;
cursor: pointer;
color: var(--input-checkbox-text-foreground-color);
.check-mark {
@include deprecated.flexCenter;
width: deprecated.$s-16;
height: deprecated.$s-16;
border-radius: deprecated.$br-6;
background-color: var(--input-checkbox-inactive-background-color);
&.checked {
background-color: var(--input-checkbox-background-color-active);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
}
}
&:hover {
border-color: var(--input-checkbox-border-color-hover);
}
&:focus {
border-color: var(--input-checkbox-border-color-focus);
}
}
}
} }

View File

@ -14,7 +14,6 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.button :refer [button*]]
[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 :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.exports.assets] [app.main.ui.exports.assets]
@ -264,10 +263,12 @@
:icon i/remove}]])]) :icon i/remove}]])])
(when (or (= :multiple exports) (seq exports)) (when (or (= :multiple exports) (seq exports))
[:> button* {:variant "secondary" [:button
:class (stl/css :export-btn) {:on-click (when-not in-progress? on-download)
:on-click (when-not in-progress? on-download) :class (stl/css-case
:disabled in-progress?} :export-btn true
:btn-disabled in-progress?)
:disabled in-progress?}
(if in-progress? (if in-progress?
(tr "workspace.options.exporting-object") (tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count shapes-with-exports))))])])])) (tr "workspace.options.export-object" (c (count shapes-with-exports))))])])]))

View File

@ -27,7 +27,7 @@
.multiple-exports { .multiple-exports {
@include deprecated.flexRow; @include deprecated.flexRow;
grid-column: 1 / span 8; grid-column: 1 / span 9;
.label { .label {
@extend .mixed-bar; @extend .mixed-bar;
} }
@ -76,6 +76,8 @@
} }
.export-btn { .export-btn {
grid-column: 1 / span 8; @extend .button-secondary;
justify-content: center; @include deprecated.uppercaseTitleTipography;
grid-column: 1 / span 9;
height: deprecated.$s-32;
} }

View File

@ -17,9 +17,9 @@
[app.main.store :as st] [app.main.store :as st]
[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.controls.checkbox :refer [checkbox*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -252,9 +252,16 @@
(when (or (= type :frame) (when (or (= type :frame)
(and (= type :multiple) (and (= type :multiple)
(some? hide-on-export))) (some? hide-on-export)))
[:> checkbox* {:ref checkbox-ref [:div {:class (stl/css :fill-checkbox)}
:id "show-fill-on-export" [:label {:for "show-fill-on-export"
:class (stl/css :fill-checkbox) :class (stl/css-case :global/checked (not hide-on-export))}
:label (tr "workspace.options.show-fill-on-export") [:span {:class (stl/css-case :check-mark true
:checked (not hide-on-export) :checked (not hide-on-export))}
:on-change on-change-show-on-export}])])])) (when (not hide-on-export)
deprecated-icon/status-tick)]
(tr "workspace.options.show-fill-on-export")
[:input {:type "checkbox"
:id "show-fill-on-export"
:ref checkbox-ref
:checked (not hide-on-export)
:on-change on-change-show-on-export}]]])])]))

View File

@ -50,5 +50,14 @@
} }
.fill-checkbox { .fill-checkbox {
// TODO create a checkbox component in the DS
@extend .input-checkbox;
padding-inline-start: var(--sp-s); padding-inline-start: var(--sp-s);
span.checked {
background-color: var(--color-accent-primary);
svg {
@extend .button-icon-small;
stroke: var(--color-background-primary);
}
}
} }

View File

@ -148,13 +148,10 @@
[:div {:class (stl/css :grid-title)} [:div {:class (stl/css :grid-title)}
[:div {:class (stl/css-case :option-row true [:div {:class (stl/css-case :option-row true
:hidden is-hidden?)} :hidden is-hidden?)}
[:> icon-button* {:variant "secondary" [:button {:class (stl/css-case :show-options true
:icon i/menu :selected open?)
:class (stl/css :show-options) :on-click toggle-advanced-options}
:aria-pressed open? deprecated-icon/menu]
:aria-label (tr "labels.options")
:on-click toggle-advanced-options
:disabled is-hidden?}]
[:div {:class (stl/css :type-select-wrapper)} [:div {:class (stl/css :type-select-wrapper)}
[:& select [:& select
{:class (stl/css :grid-type-select) {:class (stl/css :grid-type-select)
@ -207,11 +204,10 @@
:origin :guides :origin :guides
:on-change handle-change-color :on-change handle-change-color
:on-detach handle-detach-color}] :on-detach handle-detach-color}]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :show-more-options true
:icon i/menu :selected show-more-options?)
:aria-pressed show-more-options? :on-click toggle-more-options}
:aria-label (tr "labels.options") deprecated-icon/menu]]
:on-click toggle-more-options}]]
(when show-more-options? (when show-more-options?
[:div {:class (stl/css :second-row)} [:div {:class (stl/css :second-row)}
[:button {:class (stl/css-case :btn-options true [:button {:class (stl/css-case :btn-options true
@ -288,12 +284,11 @@
:className (stl/css :numeric-input) :className (stl/css :numeric-input)
:value (or (:margin params) 0)}]] :value (or (:margin params) 0)}]]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :show-more-options true
:icon i/menu :selected show-more-options?)
:aria-pressed show-more-options? :on-click toggle-more-options
:aria-label (tr "labels.options") :disabled is-default}
:on-click toggle-more-options deprecated-icon/menu]
:disabled is-default}]
(when show-more-options? (when show-more-options?
[:div {:class (stl/css :more-options)} [:div {:class (stl/css :more-options)}
[:button {:class (stl/css :option-btn) [:button {:class (stl/css :option-btn)

View File

@ -38,7 +38,18 @@
border-radius: deprecated.$br-8; border-radius: deprecated.$br-8;
background-color: var(--input-details-color); background-color: var(--input-details-color);
.show-options { .show-options {
@extend .button-secondary;
height: deprecated.$s-32;
width: deprecated.$s-28;
border-radius: deprecated.$br-8 0 0 deprecated.$br-8; border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
box-sizing: border-box;
border: deprecated.$s-1 solid var(--input-border-color);
svg {
@extend .button-icon;
}
&.selected {
@extend .button-icon-selected;
}
} }
.type-select-wrapper { .type-select-wrapper {
flex-grow: 1; flex-grow: 1;
@ -97,6 +108,7 @@
&.hidden { &.hidden {
.show-options { .show-options {
@include deprecated.hiddenElement;
border: deprecated.$s-1 solid var(--input-border-color-disabled); border: deprecated.$s-1 solid var(--input-border-color-disabled);
} }
.type-select-wrapper, .type-select-wrapper,
@ -164,7 +176,17 @@
.color-wrapper { .color-wrapper {
width: deprecated.$s-156; width: deprecated.$s-156;
} }
.show-more-options {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
svg {
@extend .button-icon;
}
&.selected {
@extend .button-icon-selected;
}
}
.height { .height {
@extend .input-element; @extend .input-element;
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;

View File

@ -16,9 +16,8 @@
[app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.shape-layout :as dwsl]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
@ -36,10 +35,10 @@
:justify-self :justify-self
:area-name]) :area-name])
(mf/defc set-self-alignment* (mf/defc set-self-alignment
[{:keys [is-col alignment set-alignment]}] [{:keys [is-col? alignment set-alignment] :as props}]
(let [alignment (or alignment :auto) (let [alignment (or alignment :auto)
type (if is-col "col" "row") type (if is-col? "col" "row")
handle-set-alignment handle-set-alignment
(mf/use-callback (mf/use-callback
@ -47,35 +46,39 @@
(fn [value] (fn [value]
(set-alignment (-> value keyword))))] (set-alignment (-> value keyword))))]
[:> radio-buttons* {:class (stl/css :self-align-menu) [:div {:class (stl/css :self-align-menu)}
:selected (d/name alignment) [:& radio-buttons {:selected (d/name alignment)
:name (dm/str "flex-align-items-" type)
:allow-empty true
:on-change handle-set-alignment :on-change handle-set-alignment
:options [{:id (dm/str "align-self-start-" type) :allow-empty true
:icon (if is-col :name (dm/str "flex-align-items-" type)}
i/align-self-row-left [:& radio-button {:value "start"
i/align-self-column-top) :icon (if is-col?
:label "Align self start" i/align-self-row-left
:value "start"} i/align-self-column-top)
{:id (dm/str "align-self-center-" type) :title "Align self start"
:icon (if is-col :id (dm/str "align-self-start-" type)}]
i/align-self-row-center
i/align-self-column-center) [:& radio-button {:value "center"
:label "Align self center" :icon (if is-col?
:value "center"} i/align-self-row-center
{:id (dm/str "align-self-end-" type) i/align-self-column-center)
:icon (if is-col :title "Align self center"
i/align-self-row-right :id (dm/str "align-self-center-" type)}]
i/align-self-column-bottom)
:label "Align self end" [:& radio-button {:value "end"
:value "end"} :icon (if is-col?
{:id (dm/str "align-self-stretch-" type) i/align-self-row-right
:icon (if is-col i/align-self-column-bottom)
i/align-self-row-stretch :title "Align self end"
i/align-self-column-stretch) :id (dm/str "align-self-end-" type)}]
:label "Align self stretch"
:value "stretch"}]}])) [:& radio-button {:value "stretch"
:icon (if is-col?
i/align-self-row-stretch
i/align-self-column-stretch)
:title "Align self stretch"
:id (dm/str "align-self-stretch-" type)}]]]))
(mf/defc options (mf/defc options
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
@ -179,19 +182,16 @@
(when open? (when open?
[:div {:class (stl/css :grid-cell-menu-container)} [:div {:class (stl/css :grid-cell-menu-container)}
[:> radio-buttons* {:selected (d/name cell-mode) [:div {:class (stl/css :cell-mode :row)}
:name "cell-mode" [:& radio-buttons {:selected (d/name cell-mode)
:on-change set-cell-mode :on-change set-cell-mode
:options [{:id "auto" :name "cell-mode"
:label "Auto" :wide true}
:value "auto"} [:& radio-button {:value "auto" :id :auto}]
{:id "manual" [:& radio-button {:value "manual" :id :manual}]
:label "Manual" [:& radio-button {:value "area"
:value "manual"} :id :area
{:id "area" :disabled (not valid-area-cells?)}]]]
:label "Area"
:value "area"
:disabled (not valid-area-cells?)}]}]
(when (= :area cell-mode) (when (= :area cell-mode)
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
@ -261,15 +261,16 @@
:value row-end}]]]]) :value row-end}]]]])
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:> set-self-alignment* {:is-col false [:& set-self-alignment {:is-col? false
:alignment align-self :alignment align-self
:set-alignment set-alignment}] :set-alignment set-alignment}]
[:> set-self-alignment* {:is-col true [:& set-self-alignment {:is-col? true
:alignment justify-self :alignment justify-self
:set-alignment set-justify-self}]] :set-alignment set-justify-self}]]
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:> button* {:variant "secondary" [:button
:class (stl/css :edit-grid-btn) {:class (stl/css :edit-grid-btn)
:on-click toggle-edit-mode} :alt (tr "workspace.layout-grid.editor.options.edit-grid")
:on-click toggle-edit-mode}
(tr "workspace.layout-grid.editor.options.edit-grid")]]])])) (tr "workspace.layout-grid.editor.options.edit-grid")]]])]))

View File

@ -30,6 +30,17 @@
@include deprecated.flexRow; @include deprecated.flexRow;
} }
.cell-mode :global(label) {
padding: 0 deprecated.$s-12;
}
.edit-grid-btn {
@extend .button-secondary;
@include deprecated.uppercaseTitleTipography;
width: 100%;
padding: deprecated.$s-8;
}
.area-input { .area-input {
@extend .input-element; @extend .input-element;
@include deprecated.bodySmallTypography; @include deprecated.bodySmallTypography;
@ -55,7 +66,3 @@
border-radius: 0 deprecated.$br-8 deprecated.$br-8 0; border-radius: 0 deprecated.$br-8 deprecated.$br-8 0;
border-left: deprecated.$s-1 solid var(--panel-background-color); border-left: deprecated.$s-1 solid var(--panel-background-color);
} }
.edit-grid-btn {
flex-grow: 1;
}

View File

@ -17,13 +17,13 @@
[app.main.data.workspace.interactions :as dwi] [app.main.data.workspace.interactions :as dwi]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[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.controls.checkbox :refer [checkbox*]] [app.main.ui.ds.controls.checkbox :refer [checkbox*]]
[app.main.ui.ds.controls.input :refer [input*]] [app.main.ui.ds.controls.input :refer [input*]]
[app.main.ui.ds.controls.numeric-input :refer [numeric-input*]] [app.main.ui.ds.controls.numeric-input :refer [numeric-input*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.product.empty-state :refer [empty-state*]] [app.main.ui.ds.product.empty-state :refer [empty-state*]]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -582,43 +582,41 @@
:options animation-opts :options animation-opts
:on-change change-animation-type}]]] :on-change change-animation-type}]]]
;; Way ;; Direction
(when (ctsi/has-way? interaction) (when (ctsi/has-way? interaction)
[:div {:class (stl/css :interaction-row)} [:div {:class (stl/css :interaction-row)}
[:div {:class (stl/css :interaction-row-radio)} [:div {:class (stl/css :interaction-row-radio)}
[:> radio-buttons* {:selected (d/name way) [:& radio-buttons {:selected (d/name way)
:on-change change-way :on-change change-way
:name "animation-way" :name "animation-way"}
:options [{:id "animation-way-in" [:& radio-button {:value "in"
:label (tr "workspace.options.interaction-animation-direction-in") :id "animation-way-in"}]
:value "in"} [:& radio-button {:id "animation-way-out"
{:id "animation-way-out" :value "out"}]]]])
:label (tr "workspace.options.interaction-animation-direction-out")
:value "out"}]}]]])
;; Direction ;; Direction
(when (ctsi/has-direction? interaction) (when (ctsi/has-direction? interaction)
[:div {:class (stl/css :interaction-row)} [:div {:class (stl/css :interaction-row)}
[:div {:class (stl/css :interaction-row-radio)} [:div {:class (stl/css :interaction-row-radio)}
[:> radio-buttons* {:selected (d/name direction) [:& radio-buttons {:selected (d/name direction)
:on-change change-direction :on-change change-direction
:name "animation-direction" :name "animation-direction"}
:options [{:id "animation-right" [:& radio-button {:icon i/row
:icon i/row :icon-class (stl/css :right)
:label (tr "workspace.options.interaction-animation-direction-right") :value "right"
:value "right"} :id "animation-right"}]
{:id "animation-left" [:& radio-button {:icon i/row-reverse
:icon i/row-reverse :icon-class (stl/css :left)
:label (tr "workspace.options.interaction-animation-direction-left") :id "animation-left"
:value "left"} :value "left"}]
{:id "animation-down" [:& radio-button {:icon i/column
:icon i/column :icon-class (stl/css :down)
:label (tr "workspace.options.interaction-animation-direction-down") :id "animation-down"
:value "down"} :value "down"}]
{:id "animation-up" [:& radio-button {:icon i/column-reverse
:icon i/column-reverse :icon-class (stl/css :up)
:label (tr "workspace.options.interaction-animation-direction-up") :id "animation-up"
:value "up"}]}]]]) :value "up"}]]]])
;; Duration ;; Duration
(when (ctsi/has-duration? interaction) (when (ctsi/has-duration? interaction)

View File

@ -22,11 +22,10 @@
[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.numeric-input :as deprecated-input] [app.main.ui.components.numeric-input :as deprecated-input]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
@ -163,118 +162,128 @@
:space-between i/align-content-row-between :space-between i/align-content-row-between
:stretch i/align-content-row-stretch)))) :stretch i/align-content-row-stretch))))
(mf/defc direction-row-flex* (mf/defc direction-row-flex
{::mf/private true} {::mf/props :obj
::mf/private true}
[{:keys [value on-change]}] [{:keys [value on-change]}]
[:> radio-buttons* {:class (stl/css :direction-row-flex) [:& radio-buttons {:class (stl/css :direction-row-flex)
:selected (d/name value) :selected (d/name value)
:on-change on-change :decode-fn keyword
:name "flex-direction" :on-change on-change
:options [{:id "flex-direction-row" :name "flex-direction"}
:icon (dir-icons-refactor :row) [:& radio-button {:value "row"
:label "Row" :id "flex-direction-row"
:value "row"} :title "Row"
{:id "flex-direction-row-reverse" :icon (dir-icons-refactor :row)}]
:icon (dir-icons-refactor :row-reverse) [:& radio-button {:value "row-reverse"
:label "Row reverse" :id "flex-direction-row-reverse"
:value "row-reverse"} :title "Row reverse"
{:id "flex-direction-column" :icon (dir-icons-refactor :row-reverse)}]
:icon (dir-icons-refactor :column) [:& radio-button {:value "column"
:label "Column" :id "flex-direction-column"
:value "column"} :title "Column"
{:id "flex-direction-column-reverse" :icon (dir-icons-refactor :column)}]
:icon (dir-icons-refactor :column-reverse) [:& radio-button {:value "column-reverse"
:label "Column reverse" :id "flex-direction-column-reverse"
:value "column-reverse"}]}]) :title "Column reverse"
:icon (dir-icons-refactor :column-reverse)}]])
(mf/defc wrap-row* (mf/defc wrap-row
{::mf/props :obj}
[{:keys [wrap-type on-click]}] [{:keys [wrap-type on-click]}]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :wrap-button true
:aria-label (if (= :wrap wrap-type) "No wrap" "Wrap") :selected (= wrap-type :wrap))
:aria-pressed (= wrap-type :wrap) :title (if (= :wrap wrap-type)
:on-click on-click "No wrap"
:icon i/wrap}]) "Wrap")
:on-click on-click}
deprecated-icon/wrap])
(mf/defc align-row* (mf/defc align-row
{::mf/props :obj}
[{:keys [is-column value on-change]}] [{:keys [is-column value on-change]}]
[:> radio-buttons* {:class (stl/css :align-row) [:& radio-buttons {:class (stl/css :align-row)
:selected (d/name value) :selected (d/name value)
:on-change on-change :decode-fn keyword
:name "flex-align-items" :on-change on-change
:options [{:id "align-items-start" :name "flex-align-items"}
:icon (get-layout-flex-icon :align-items :start is-column) [:& radio-button {:value "start"
:label "Align items start" :icon (get-layout-flex-icon :align-items :start is-column)
:value "start"} :title "Align items start"
{:id "align-items-center" :id "align-items-start"}]
:icon (get-layout-flex-icon :align-items :center is-column) [:& radio-button {:value "center"
:label "Align items center" :icon (get-layout-flex-icon :align-items :center is-column)
:value "center"} :title "Align items center"
{:id "align-items-end" :id "align-items-center"}]
:icon (get-layout-flex-icon :align-items :end is-column) [:& radio-button {:value "end"
:label "Align items end" :icon (get-layout-flex-icon :align-items :end is-column)
:value "end"}]}]) :title "Align items end"
:id "align-items-end"}]])
(mf/defc align-content-row* (mf/defc align-content-row
{::mf/props :obj}
[{:keys [is-column value on-change]}] [{:keys [is-column value on-change]}]
[:> radio-buttons* {:class (stl/css :align-content-row) [:& radio-buttons {:class (stl/css :align-content-row)
:selected (d/name value) :selected (d/name value)
:on-change on-change :decode-fn keyword
:name "flex-align-content" :on-change on-change
:options [{:id "align-content-start" :name "flex-align-content"}
:icon (get-layout-flex-icon :align-content :start is-column) [:& radio-button {:value "start"
:label "Align content start" :icon (get-layout-flex-icon :align-content :start is-column)
:value "start"} :title "Align content start"
{:id "align-content-center" :id "align-content-start"}]
:icon (get-layout-flex-icon :align-content :center is-column) [:& radio-button {:value "center"
:label "Align content center" :icon (get-layout-flex-icon :align-content :center is-column)
:value "center"} :title "Align content center"
{:id "align-content-end" :id "align-content-center"}]
:icon (get-layout-flex-icon :align-content :end is-column) [:& radio-button {:value "end"
:label "Align content end" :icon (get-layout-flex-icon :align-content :end is-column)
:value "end"} :title "Align content end"
{:id "align-content-space-between" :id "align-content-end"}]
:icon (get-layout-flex-icon :align-content :space-between is-column) [:& radio-button {:value "space-between"
:label "Align content space-between" :icon (get-layout-flex-icon :align-content :space-between is-column)
:value "space-between"} :title "Align content space-between"
{:id "align-content-space-around" :id "align-content-space-between"}]
:icon (get-layout-flex-icon :align-content :space-around is-column) [:& radio-button {:value "space-around"
:label "Align content space-around" :icon (get-layout-flex-icon :align-content :space-around is-column)
:value "space-around"} :title "Align content space-around"
{:id "align-content-space-evenly" :id "align-content-space-around"}]
:icon (get-layout-flex-icon :align-content :space-evenly is-column) [:& radio-button {:value "space-evenly"
:label "Align content space-evenly" :icon (get-layout-flex-icon :align-content :space-evenly is-column)
:value "space-evenly"}]}]) :title "Align content space-evenly"
:id "align-content-space-evenly"}]])
(mf/defc justify-content-row* (mf/defc justify-content-row
{::mf/props :obj}
[{:keys [is-column justify-content on-change]}] [{:keys [is-column justify-content on-change]}]
[:> radio-buttons* {:class (stl/css :justify-content-row) [:& radio-buttons {:class (stl/css :justify-content-row)
:selected (d/name justify-content) :selected (d/name justify-content)
:on-change on-change :on-change on-change
:name "flex-justify" :name "flex-justify"}
:options [{:id "justify-content-start" [:& radio-button {:value "start"
:icon (get-layout-flex-icon :justify-content :start is-column) :icon (get-layout-flex-icon :justify-content :start is-column)
:label "Justify content start" :title "Justify content start"
:value "start"} :id "justify-content-start"}]
{:id "justify-content-center" [:& radio-button {:value "center"
:icon (get-layout-flex-icon :justify-content :center is-column) :icon (get-layout-flex-icon :justify-content :center is-column)
:label "Justify content center" :title "Justify content center"
:value "center"} :id "justify-content-center"}]
{:id "justify-content-end" [:& radio-button {:value "end"
:icon (get-layout-flex-icon :justify-content :end is-column) :icon (get-layout-flex-icon :justify-content :end is-column)
:label "Justify content end" :title "Justify content end"
:value "end"} :id "justify-content-end"}]
{:id "justify-content-space-between" [:& radio-button {:value "space-between"
:icon (get-layout-flex-icon :justify-content :space-between is-column) :icon (get-layout-flex-icon :justify-content :space-between is-column)
:label "Justify content space-between" :title "Justify content space-between"
:value "space-between"} :id "justify-content-space-between"}]
{:id "justify-content-space-around" [:& radio-button {:value "space-around"
:icon (get-layout-flex-icon :justify-content :space-around is-column) :icon (get-layout-flex-icon :justify-content :space-around is-column)
:label "Justify content space-around" :title "Justify content space-around"
:value "space-around"} :id "justify-content-space-around"}]
{:id "justify-content-space-evenly" [:& radio-button {:value "space-evenly"
:icon (get-layout-flex-icon :justify-content :space-evenly is-column) :icon (get-layout-flex-icon :justify-content :space-evenly is-column)
:label "Justify content space-evenly" :title "Justify content space-evenly"
:value "space-evenly"}]}]) :id "justify-content-space-evenly"}]])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PADDING ;; PADDING
@ -665,12 +674,14 @@
(= type :multiple) (= type :multiple)
[:> multiple-padding-selection* props])] [:> multiple-padding-selection* props])]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case
:aria-label (tr "workspace.layout-grid.editor.padding.expand") :padding-toggle true
:aria-pressed (= type :multiple) :selected (= type :multiple))
:data-type (d/name type) :title (tr "workspace.layout-grid.editor.padding.expand")
:on-click on-type-change' :aria-label (tr "workspace.layout-grid.editor.padding.expand")
:icon i/padding-extended}]])) :data-type (d/name type)
:on-click on-type-change'}
deprecated-icon/padding-extended]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GAP ;; GAP
@ -825,22 +836,25 @@
;; GRID COMPONENTS ;; GRID COMPONENTS
(mf/defc direction-row-grid* (mf/defc direction-row-grid
{::mf/props :obj}
[{:keys [value on-change] :as props}] [{:keys [value on-change] :as props}]
[:> radio-buttons* {:class (stl/css :direction-row-grid) [:& radio-buttons {:class (stl/css :direction-row-grid)
:selected (d/name value) :selected (d/name value)
:on-change on-change :decode-fn keyword
:name "grid-direction" :on-change on-change
:options [{:id "grid-direction-row" :name "grid-direction"}
:icon (dir-icons-refactor :row) [:& radio-button {:value "row"
:label "Row" :id "grid-direction-row"
:value "row"} :title "Row"
{:id "grid-direction-column" :icon (dir-icons-refactor :row)}]
:icon (dir-icons-refactor :column) [:& radio-button {:value "column"
:label "Column" :id "grid-direction-column"
:value "column"}]}]) :title "Column"
:icon (dir-icons-refactor :column)}]])
(mf/defc grid-edit-mode* (mf/defc grid-edit-mode
{::mf/props :obj}
[{:keys [id]}] [{:keys [id]}]
(let [edition (mf/deref refs/selected-edition) (let [edition (mf/deref refs/selected-edition)
active? (= id edition) active? (= id edition)
@ -852,65 +866,81 @@
(if-not active? (if-not active?
(st/emit! (udw/start-edition-mode id)) (st/emit! (udw/start-edition-mode id))
(st/emit! :interrupt))))] (st/emit! :interrupt))))]
[:button
[:> button* {:variant "secondary" {:class (stl/css :edit-mode-btn)
:class (stl/css :edit-mode-btn) :alt "Grid edit mode"
:on-click toggle-edit-mode} :on-click toggle-edit-mode}
(tr "workspace.layout-grid.editor.options.edit-grid")])) (tr "workspace.layout-grid.editor.options.edit-grid")]))
(mf/defc align-grid-row* (mf/defc align-grid-row
{::mf/private true} {::mf/props :obj
::mf/private true}
[{:keys [is-column value on-change]}] [{:keys [is-column value on-change]}]
(let [type (if ^boolean is-column "column" "row")] (let [type (if ^boolean is-column "column" "row")]
[:> radio-buttons* {:class (stl/css :align-grid-row) [:& radio-buttons {:class (stl/css :align-grid-row)
:selected (d/name value) :selected (d/name value)
:on-change on-change :decode-fn keyword
:name (dm/str "flex-align-items-" type) :on-change on-change
:options [{:id (dm/str "align-items-start-" type) :name (dm/str "flex-align-items-" type)}
:icon (get-layout-grid-icon :align-items :start is-column) [:& radio-button {:value "start"
:label "Align items start" :icon (get-layout-grid-icon :align-items :start is-column)
:value "start"} :title "Align items start"
{:id (dm/str "align-items-center-" type) :id (dm/str "align-items-start-" type)}]
:icon (get-layout-grid-icon :align-items :center is-column) [:& radio-button {:value "center"
:label "Align items center" :icon (get-layout-grid-icon :align-items :center is-column)
:value "center"} :title "Align items center"
{:id (dm/str "align-items-end-" type) :id (dm/str "align-items-center-" type)}]
:icon (get-layout-grid-icon :align-items :end is-column) [:& radio-button {:value "end"
:label "Align items end" :icon (get-layout-grid-icon :align-items :end is-column)
:value "end"}]}])) :title "Align items end"
:id (dm/str "align-items-end-" type)}]]))
(mf/defc justify-grid-row* (mf/defc justify-grid-row
{::mf/private true} {::mf/props :obj
::mf/private :obj}
[{:keys [is-column value on-change]}] [{:keys [is-column value on-change]}]
(let [type (if ^boolean is-column "column" "row")] (let [type (if ^boolean is-column "column" "row")]
[:> radio-buttons* {:class (stl/css :justify-grid-row) [:& radio-buttons {:class (stl/css :justify-grid-row)
:selected (d/name value) :selected (d/name value)
:on-change on-change :on-change on-change
:name (dm/str "grid-justify-items-" type) :decode-fn keyword
:options [{:id (dm/str "justify-items-start-" type) :name (dm/str "grid-justify-items-" type)}
:icon (get-layout-grid-icon :justify-items :start is-column)
:label "Justify items start" [:& radio-button {:key "justify-item-start"
:value "start"} :value "start"
{:id (dm/str "justify-items-center-" type) :icon (get-layout-grid-icon :justify-items :start is-column)
:icon (get-layout-grid-icon :justify-items :center is-column) :title "Justify items start"
:label "Justify items center" :id (dm/str "justify-items-start-" type)}]
:value "center"}
{:id (dm/str "justify-items-end-" type) [:& radio-button {:key "justify-item-center"
:icon (get-layout-grid-icon :justify-items :end is-column) :value "center"
:label "Justify items end" :icon (get-layout-grid-icon :justify-items :center is-column)
:value "end"} :title "Justify items center"
{:id (dm/str "justify-items-space-around-" type) :id (dm/str "justify-items-center-" type)}]
:icon (get-layout-grid-icon :justify-items :space-around is-column)
:label "Justify items space-around" [:& radio-button {:key "justify-item-end"
:value "space-around"} :value "end"
{:id (dm/str "justify-items-space-between-" type) :icon (get-layout-grid-icon :justify-items :end is-column)
:icon (get-layout-grid-icon :justify-items :space-between is-column) :title "Justify items end"
:label "Justify items space-between" :id (dm/str "justify-items-end-" type)}]
:value "space-between"}
{:id (dm/str "justify-items-stretch-" type) [:& radio-button {:key "justify-item-space-around"
:icon (get-layout-grid-icon :justify-items :stretch is-column) :value "space-around"
:label "Justify items stretch" :icon (get-layout-grid-icon :justify-items :space-around is-column)
:value "stretch"}]}])) :title "Justify items space-around"
:id (dm/str "justify-items-space-around-" type)}]
[:& radio-button {:key "justify-item-space-between"
:value "space-between"
:icon (get-layout-grid-icon :justify-items :space-between is-column)
:title "Justify items space-between"
:id (dm/str "justify-items-space-between-" type)}]
[:& radio-button {:key "justify-item-stretch"
:value "stretch"
:icon (get-layout-grid-icon :justify-items :stretch is-column)
:title "Justify items stretch"
:id (dm/str "justify-items-stretch-" type)}]]))
(defn- manage-values (defn- manage-values
[{:keys [type value]}] [{:keys [type value]}]
@ -921,7 +951,8 @@
:fixed (fmt/format-pixels value) :fixed (fmt/format-pixels value)
value)) value))
(mf/defc grid-track-info* (mf/defc grid-track-info
{::mf/props :obj}
[{:keys [is-column [{:keys [is-column
type type
index index
@ -1004,7 +1035,8 @@
:data-index index :data-index index
:icon i/remove}]])) :icon i/remove}]]))
(mf/defc grid-columns-row* (mf/defc grid-columns-row
{::mf/props :obj}
[{:keys [is-column expanded? column-values toggle add-new-element set-column-value set-column-type [{:keys [is-column expanded? column-values toggle add-new-element set-column-value set-column-type
remove-element reorder-track hover-track on-select-track]}] remove-element reorder-track hover-track on-select-track]}]
(let [column-num (count column-values) (let [column-num (count column-values)
@ -1025,38 +1057,27 @@
[:div {:class (stl/css :grid-tracks) :data-testid testid} [:div {:class (stl/css :grid-tracks) :data-testid testid}
[:div {:class (stl/css :grid-track-header)} [:div {:class (stl/css :grid-track-header)}
[:> icon-button* {:variant "secondary" [:button {:class (stl/css :expand-icon) :on-click toggle} deprecated-icon/menu]
:class (stl/css :expand-icon)
:aria-pressed expanded?
:aria-label (tr "labels.options")
:on-click toggle
:icon i/menu}]
#_[:button {:class (stl/css :expand-icon) :on-click toggle} deprecated-icon/menu]
[:div {:class (stl/css :track-title) :on-click toggle} [:div {:class (stl/css :track-title) :on-click toggle}
[:div {:class (stl/css :track-name) :title track-name} track-name] [:div {:class (stl/css :track-name) :title track-name} track-name]
[:div {:class (stl/css :track-detail) :title track-detail} track-detail]] [:div {:class (stl/css :track-detail) :title track-detail} track-detail]]
[:> icon-button* {:variant "secondary" [:button {:class (stl/css :add-column) :on-click add-track} deprecated-icon/add]]
:class (stl/css :add-column)
:aria-label (tr "labels.add")
:on-click add-track
:icon i/add}]
#_[:button {:class (stl/css :add-column) :on-click add-track} deprecated-icon/add]]
(when expanded? (when expanded?
[:> h/sortable-container* {} [:> h/sortable-container* {}
[:div {:class (stl/css :grid-tracks-info-container)} [:div {:class (stl/css :grid-tracks-info-container)}
(for [[index column] (d/enumerate column-values)] (for [[index column] (d/enumerate column-values)]
[:> grid-track-info* {:key (dm/str index "-" (d/name type)) [:& grid-track-info {:key (dm/str index "-" (d/name type))
:type type :type type
:is-column is-column :is-column is-column
:index index :index index
:column column :column column
:set-column-value set-column-value :set-column-value set-column-value
:set-column-type set-column-type :set-column-type set-column-type
:remove-element remove-element :remove-element remove-element
:reorder-track reorder-track :reorder-track reorder-track
:hover-track hover-track :hover-track hover-track
:on-select-track on-select-track}])]])])) :on-select-track on-select-track}])]])]))
;; LAYOUT COMPONENT ;; LAYOUT COMPONENT
@ -1192,8 +1213,8 @@
(mf/deps layout-type ids) (mf/deps layout-type ids)
(fn [dir] (fn [dir]
(if (= :flex layout-type) (if (= :flex layout-type)
(st/emit! (dwsl/update-layout ids {:layout-flex-dir (keyword dir)})) (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir}))
(st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)}))))) (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))))
;; Align grid ;; Align grid
align-items-row (:layout-align-items values) align-items-row (:layout-align-items values)
@ -1203,13 +1224,13 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
on-row-align-change on-row-align-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-align-items value}))))
;; Justify grid ;; Justify grid
grid-justify-content-row (:layout-justify-content values) grid-justify-content-row (:layout-justify-content values)
@ -1219,13 +1240,13 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-align-content value}))))
on-row-justify-change on-row-justify-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))))
on-toggle-dropdown-visibility on-toggle-dropdown-visibility
(mf/use-fn #(swap! show-dropdown* not)) (mf/use-fn #(swap! show-dropdown* not))
@ -1298,31 +1319,31 @@
:flex :flex
[:div {:class (stl/css :flex-layout-menu)} [:div {:class (stl/css :flex-layout-menu)}
[:div {:class (stl/css :first-row)} [:div {:class (stl/css :first-row)}
[:> align-row* {:is-column is-column [:& align-row {:is-column is-column
:value align-items :value align-items
:on-change set-align-items}] :on-change set-align-items}]
[:> direction-row-flex* {:on-change on-direction-change [:& direction-row-flex {:on-change on-direction-change
:value saved-dir}] :value saved-dir}]
[:> wrap-row* {:wrap-type wrap-type [:& wrap-row {:wrap-type wrap-type
:on-click toggle-wrap}]] :on-click toggle-wrap}]]
[:div {:class (stl/css :middle-row)} [:div {:class (stl/css :second-row :help-button-wrapper)}
[:div {:class (stl/css :help-button-wrapper)} [:& justify-content-row {:is-column is-column
[:> justify-content-row* {:is-column is-column :justify-content justify-content
:justify-content justify-content :on-change set-justify-content}]
:on-change set-justify-content}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "labels.help-center")
:on-click open-flex-help
:icon i/help}]]
(when (= :wrap wrap-type)
[:> align-content-row* {:is-column is-column
:value align-content
:on-change on-align-content-change}])]
[:div {:class (stl/css :last-row)} [:> icon-button* {:variant "ghost"
:aria-label (tr "labels.help-center")
:on-click open-flex-help
:icon i/help}]]
(when (= :wrap wrap-type)
[:div {:class (stl/css :third-row)}
[:& align-content-row {:is-column is-column
:value align-content
:on-change on-align-content-change}]])
[:div {:class (stl/css :forth-row)}
[:> gap-section* {:is-column is-column [:> gap-section* {:is-column is-column
:wrap-type wrap-type :wrap-type wrap-type
:on-change on-gap-change :on-change on-gap-change
@ -1340,7 +1361,7 @@
[:div {:class (stl/css :grid-layout-menu)} [:div {:class (stl/css :grid-layout-menu)}
(when (= 1 (count ids)) (when (= 1 (count ids))
[:div {:class (stl/css :edit-grid-wrapper)} [:div {:class (stl/css :edit-grid-wrapper)}
[:> grid-edit-mode* {:id (first ids)}] [:& grid-edit-mode {:id (first ids)}]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "labels.help-center") :aria-label (tr "labels.help-center")
:on-click open-grid-help :on-click open-grid-help
@ -1349,23 +1370,23 @@
[:div {:class (stl/css :first-row)} [:div {:class (stl/css :first-row)}
[:div {:class (stl/css :direction-edit)} [:div {:class (stl/css :direction-edit)}
[:div {:class (stl/css :direction)} [:div {:class (stl/css :direction)}
[:> direction-row-grid* {:value saved-grid-dir [:& direction-row-grid {:value saved-grid-dir
:on-change on-direction-change}]]] :on-change on-direction-change}]]]
[:> align-grid-row* {:is-column false [:& align-grid-row {:is-column false
:value align-items-row :value align-items-row
:on-change on-row-align-change}] :on-change on-row-align-change}]
[:> align-grid-row* {:is-column true [:& align-grid-row {:is-column true
:value align-items-column :value align-items-column
:on-change on-column-align-change}]] :on-change on-column-align-change}]]
[:div {:class (stl/css :row :grid-layout-align)} [:div {:class (stl/css :row :grid-layout-align)}
[:> justify-grid-row* {:is-column true [:& justify-grid-row {:is-column true
:value grid-justify-content-column :value grid-justify-content-column
:on-change on-column-justify-change}] :on-change on-column-justify-change}]
[:> justify-grid-row* {:is-column false [:& justify-grid-row {:is-column false
:value grid-justify-content-row :value grid-justify-content-row
:on-change on-row-justify-change}]] :on-change on-row-justify-change}]]
[:div {:class (stl/css :gap-row)} [:div {:class (stl/css :gap-row)}
[:> gap-section* {:on-change on-gap-change [:> gap-section* {:on-change on-gap-change
@ -1391,7 +1412,7 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [dir] (fn [dir]
(st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)})))) (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))
on-gap-change on-gap-change
(mf/use-fn (mf/use-fn
@ -1430,13 +1451,13 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
on-row-align-change on-row-align-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-align-items value}))))
;; Justify grid ;; Justify grid
grid-justify-content-row (:layout-justify-content values) grid-justify-content-row (:layout-justify-content values)
@ -1446,13 +1467,13 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-align-content value}))))
on-row-justify-change on-row-justify-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))))
columns-open? (mf/use-state false) columns-open? (mf/use-state false)
rows-open? (mf/use-state false) rows-open? (mf/use-state false)
@ -1533,32 +1554,31 @@
:aria-label (tr "labels.help-center") :aria-label (tr "labels.help-center")
:on-click open-grid-help :on-click open-grid-help
:icon i/help}] :icon i/help}]
[:> button* {:variant "secondary" [:button {:class (stl/css :exit-btn)
:class (stl/css :exit-btn) :on-click #(st/emit! (udw/clear-edition-mode))}
:on-click #(st/emit! (udw/clear-edition-mode))}
(tr "workspace.layout-grid.editor.options.exit")]] (tr "workspace.layout-grid.editor.options.exit")]]
[:div {:class (stl/css :row :first-row)} [:div {:class (stl/css :row :first-row)}
[:div {:class (stl/css :direction-edit)} [:div {:class (stl/css :direction-edit)}
[:div {:class (stl/css :direction)} [:div {:class (stl/css :direction)}
[:> direction-row-grid* {:value saved-grid-dir [:& direction-row-grid {:value saved-grid-dir
:on-change on-direction-change}]]] :on-change on-direction-change}]]]
[:> align-grid-row* {:is-column false [:& align-grid-row {:is-column false
:value align-items-row :value align-items-row
:on-change on-row-align-change}] :on-change on-row-align-change}]
[:> align-grid-row* {:is-column true [:& align-grid-row {:is-column true
:value align-items-column :value align-items-column
:on-change on-column-align-change}]] :on-change on-column-align-change}]]
[:div {:class (stl/css :row :grid-layout-align)} [:div {:class (stl/css :row :grid-layout-align)}
[:> justify-grid-row* {:is-column true [:& justify-grid-row {:is-column true
:value grid-justify-content-column :value grid-justify-content-column
:on-change on-column-justify-change}] :on-change on-column-justify-change}]
[:> justify-grid-row* {:is-column false [:& justify-grid-row {:is-column false
:value grid-justify-content-row :value grid-justify-content-row
:on-change on-row-justify-change}] :on-change on-row-justify-change}]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:class (stl/css :locate-button) :class (stl/css :locate-button)
@ -1572,33 +1592,33 @@
:applied-tokens applied-tokens :applied-tokens applied-tokens
:value (:layout-gap values)}]] :value (:layout-gap values)}]]
[:div {:class (stl/css :padding-row)} [:div {:class (stl/css :padding-row :padding-section)}
[:> padding-section* {:value (:layout-padding values) [:> padding-section* {:value (:layout-padding values)
:type (:layout-padding-type values) :type (:layout-padding-type values)
:on-type-change on-padding-type-change :on-type-change on-padding-type-change
:on-change on-padding-change}]] :on-change on-padding-change}]]
[:div {:class (stl/css :grid-tracks-row)} [:div {:class (stl/css :grid-tracks-row)}
[:> grid-columns-row* {:is-column true [:& grid-columns-row {:is-column true
:expanded? @columns-open? :expanded? @columns-open?
:toggle toggle-columns-open :toggle toggle-columns-open
:column-values column-values :column-values column-values
:add-new-element add-new-element :add-new-element add-new-element
:set-column-value set-column-value :set-column-value set-column-value
:set-column-type set-column-type :set-column-type set-column-type
:remove-element remove-element :remove-element remove-element
:reorder-track reorder-track :reorder-track reorder-track
:hover-track hover-track :hover-track hover-track
:on-select-track handle-select-track}] :on-select-track handle-select-track}]
[:> grid-columns-row* {:is-column false [:& grid-columns-row {:is-column false
:expanded? @rows-open? :expanded? @rows-open?
:toggle toggle-rows-open :toggle toggle-rows-open
:column-values rows-values :column-values rows-values
:add-new-element add-new-element :add-new-element add-new-element
:set-column-value set-column-value :set-column-value set-column-value
:set-column-type set-column-type :set-column-type set-column-type
:remove-element remove-element :remove-element remove-element
:reorder-track reorder-track :reorder-track reorder-track
:hover-track hover-track :hover-track hover-track
:on-select-track handle-select-track}]]])) :on-select-track handle-select-track}]]]))

View File

@ -42,7 +42,6 @@
.flex-layout-menu { .flex-layout-menu {
@include sidebar.option-grid-structure; @include sidebar.option-grid-structure;
row-gap: var(--sp-s);
margin-block-end: var(--sp-s); margin-block-end: var(--sp-s);
} }
@ -50,6 +49,8 @@
grid-column: 1 / -1; grid-column: 1 / -1;
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
margin-block-end: var(--sp-m);
margin-block-start: var(--sp-xs);
} }
.align-row { .align-row {
@ -60,11 +61,27 @@
grid-column: span 4; grid-column: span 4;
} }
.middle-row { // TODO: Replace this buttons with DS buttons
grid-column: span 8; .wrap-button {
display: flex; @extend .button-tertiary;
flex-direction: column; border-radius: $br-8;
row-gap: var(--sp-xs); block-size: $sz-32;
inline-size: $sz-32;
svg {
@extend .button-icon;
stroke: var(--color-foreground-secondary);
}
&.selected {
@extend .button-icon-selected;
}
}
.second-row,
.third-row {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
margin-block-end: var(--sp-m);
} }
.align-content-row, .align-content-row,
@ -72,7 +89,7 @@
grid-column: span 6; grid-column: span 6;
} }
.last-row { .forth-row {
display: grid; display: grid;
grid-template-columns: grid-template-columns:
var(--grid-exception-input-width) /* first input block */ var(--grid-exception-input-width) /* first input block */
@ -83,7 +100,9 @@
} }
.help-button-wrapper { .help-button-wrapper {
grid-column: 1 / -1;
display: flex; display: flex;
flex-direction: row;
justify-content: space-between; justify-content: space-between;
} }
@ -130,10 +149,23 @@
gap: var(--sp-xs); gap: var(--sp-xs);
} }
// TODO: Replace this buttons with DS buttons
.padding-toggle {
@extend .button-tertiary;
block-size: $sz-32;
inline-size: $sz-32;
border-radius: $br-8;
svg {
@extend .button-icon;
stroke: var(--color-foreground-secondary);
}
&.selected {
@extend .button-icon-selected;
}
}
.grid-layout-menu { .grid-layout-menu {
@include sidebar.option-grid-structure; @include sidebar.option-grid-structure;
margin-top: var(--sp-xs);
row-gap: var(--sp-s);
} }
.edit-grid-wrapper, .edit-grid-wrapper,
@ -145,6 +177,7 @@
} }
.first-row { .first-row {
margin-block-end: var(--sp-s);
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
} }
@ -169,12 +202,20 @@
grid-column: span 5; grid-column: span 5;
} }
// TODO: Replace this buttons with DS buttons
.edit-mode-btn { .edit-mode-btn {
justify-content: center; @extend .button-secondary;
@include t.use-typography("headline-small");
inline-size: 100%;
padding: var(--sp-s);
grid-column: span 7; grid-column: span 7;
} }
// TODO: Replace this buttons with DS buttons
.exit-btn { .exit-btn {
@extend .button-secondary;
@include t.use-typography("headline-small");
padding: var(--sp-s) var(--sp-xl);
grid-column: span 2; grid-column: span 2;
} }
@ -186,11 +227,14 @@
margin-block-start: var(--sp-xs); margin-block-start: var(--sp-xs);
} }
.padding-section {
margin-block-start: var(--sp-s);
}
.grid-tracks-row { .grid-tracks-row {
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
grid-column: 1 / -1; grid-column: 1 / -1;
row-gap: var(--sp-s);
} }
.edit-grid-wrapper { .edit-grid-wrapper {
@ -249,6 +293,7 @@
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
grid-column: 1 / -1; grid-column: 1 / -1;
margin-block-start: var(--sp-s);
} }
.grid-track-header { .grid-track-header {
@ -259,7 +304,7 @@
border-radius: $br-8; border-radius: $br-8;
overflow: hidden; overflow: hidden;
background: var(--color-background-tertiary); background: var(--color-background-tertiary);
block-size: $sz-48; block-size: px2rem(52);
grid-column: 1 / -1; grid-column: 1 / -1;
} }
@ -283,14 +328,44 @@
color: var(--color-foreground-secondary); color: var(--color-foreground-secondary);
} }
// TODO: Replace this buttons with DS buttons
.expand-icon { .expand-icon {
block-size: $sz-48; @extend .button-secondary;
block-size: px2rem(52);
border-radius: $br-8 0 0 $br-8; border-radius: $br-8 0 0 $br-8;
border-inline-end: $b-1 solid var(--color-background-primary);
svg {
@extend .button-icon;
stroke: var(--color-foreground-secondary);
fill: var(--color-foreground-secondary);
}
&:hover,
&:active {
svg {
stroke: var(--color-accent-primary);
fill: var(--color-accent-primary);
}
}
} }
// TODO: Replace this buttons with DS buttons
.add-column { .add-column {
block-size: $sz-48; @extend .button-tertiary;
border-radius: 0 $br-8 $br-8 0; block-size: px2rem(52);
svg {
display: flex;
justify-content: center;
align-items: center;
color: transparent;
fill: none;
stroke-width: px2rem(1);
block-size: $sz-12;
inline-size: $sz-12;
stroke: var(--color-foreground-secondary);
fill: var(--color-foreground-secondary);
}
} }
.layout-options { .layout-options {

View File

@ -17,9 +17,8 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.numeric-input :as deprecated-input] [app.main.ui.components.numeric-input :as deprecated-input]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[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.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]]
@ -417,85 +416,104 @@
(= type :multiple) (= type :multiple)
[:> margin-multiple* props])] [:> margin-multiple* props])]
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case
:aria-pressed (= type :multiple) :margin-mode true
:aria-label (tr "workspace.layout-grid.editor.margin.expand") :selected (= type :multiple))
:on-click on-type-change' :title "Margin - multiple"
:icon i/margin}]])) :on-click on-type-change'}
deprecated-icon/margin]]))
(mf/defc element-behaviour-horizontal* (mf/defc element-behaviour-horizontal
{::mf/private true} {::mf/props :obj
::mf/private true}
[{:keys [^boolean is-auto ^boolean has-fill value on-change]}] [{:keys [^boolean is-auto ^boolean has-fill value on-change]}]
[:div {:class (stl/css-case :horizontal-behaviour true [:div {:class (stl/css-case
:one-element (and (not has-fill) (not is-auto)) :horizontal-behaviour true
:two-element (or has-fill is-auto) :one-element (and (not has-fill) (not is-auto))
:three-element (and has-fill is-auto))} :two-element (or has-fill is-auto)
[:> radio-buttons* {:selected (d/name value) :three-element (and has-fill is-auto))}
:on-change on-change [:& radio-buttons
:name "flex-behaviour-h" {:selected (d/name value)
:options (remove nil? :decode-fn keyword
[{:id "behaviour-h-fix" :on-change on-change
:icon i/fixed-width :name "flex-behaviour-h"}
:label (tr "workspace.layout-item.fix-width")
:value "fix"}
(when has-fill
{:id "behaviour-h-fill"
:icon i/fill-content
:label (tr "workspace.layout-item.width-100")
:value "fill"})
(when is-auto
{:id "behaviour-h-auto"
:icon i/hug-content
:label (tr "workspace.layout-item.fit-content-horizontal")
:value "auto"})])}]])
(mf/defc element-behaviour-vertical* [:& radio-button
{::mf/private true} {:value "fix"
:icon i/fixed-width
:title "Fix width"
:id "behaviour-h-fix"}]
(when has-fill
[:& radio-button
{:value "fill"
:icon i/fill-content
:title "Width 100%"
:id "behaviour-h-fill"}])
(when is-auto
[:& radio-button
{:value "auto"
:icon i/hug-content
:title "Fit content (Horizontal)"
:id "behaviour-h-auto"}])]])
(mf/defc element-behaviour-vertical
{::mf/props :obj
::mf/private true}
[{:keys [^boolean is-auto ^boolean has-fill value on-change]}] [{:keys [^boolean is-auto ^boolean has-fill value on-change]}]
[:div {:class (stl/css-case :vertical-behaviour true [:div {:class (stl/css-case
:one-element (and (not has-fill) (not is-auto)) :vertical-behaviour true
:two-element (or has-fill is-auto) :one-element (and (not has-fill) (not is-auto))
:three-element (and has-fill is-auto))} :two-element (or has-fill is-auto)
[:> radio-buttons* {:selected (d/name value) :three-element (and has-fill is-auto))}
:on-change on-change [:& radio-buttons
:name "flex-behaviour-v" {:selected (d/name value)
:options (remove nil? :decode-fn keyword
[{:id "behaviour-v-fix" :on-change on-change
:icon i/fixed-width :name "flex-behaviour-v"}
:label (tr "workspace.layout-item.fix-height") [:& radio-button
:class (stl/css :rotated) {:value "fix"
:value "fix"} :icon i/fixed-width
(when has-fill :icon-class (stl/css :rotated)
{:id "behaviour-v-fill" :title "Fix height"
:icon i/fill-content :id "behaviour-v-fix"}]
:label (tr "workspace.layout-item.height-100")
:class (stl/css :rotated)
:value "fill"})
(when is-auto
{:id "behaviour-v-auto"
:icon i/hug-content
:label (tr "workspace.layout-item.fit-content-vertical")
:class (stl/css :rotated)
:value "auto"})])}]])
(mf/defc align-self-row* (when has-fill
[:& radio-button
{:value "fill"
:icon i/fill-content
:icon-class (stl/css :rotated)
:title "Height 100%"
:id "behaviour-v-fill"}])
(when is-auto
[:& radio-button
{:value "auto"
:icon i/hug-content
:icon-class (stl/css :rotated)
:title "Fit content (Vertical)"
:id "behaviour-v-auto"}])]])
(mf/defc align-self-row
{::mf/props :obj}
[{:keys [^boolean is-col value on-change]}] [{:keys [^boolean is-col value on-change]}]
[:> radio-buttons* {:selected (d/name value) [:& radio-buttons {:selected (d/name value)
:name "flex-align-self" :decode-fn keyword
:on-change on-change :on-change on-change
:allow-empty true :name "flex-align-self"
:options [{:id "align-self-start" :allow-empty true}
:icon (get-layout-flex-icon :align-self :start is-col) [:& radio-button {:value "start"
:label "Align self start" :icon (get-layout-flex-icon :align-self :start is-col)
:value "start"} :title "Align self start"
{:id "align-self-center" :id "align-self-start"}]
:icon (get-layout-flex-icon :align-self :center is-col) [:& radio-button {:value "center"
:label "Align self center" :icon (get-layout-flex-icon :align-self :center is-col)
:value "center"} :title "Align self center"
{:id "align-self-end" :id "align-self-center"}]
:icon (get-layout-flex-icon :align-self :end is-col) [:& radio-button {:value "end"
:label "Align self end" :icon (get-layout-flex-icon :align-self :end is-col)
:value "end"}]}]) :title "Align self end"
:id "align-self-end"}]])
(def ^:private schema:layout-item-props-schema (def ^:private schema:layout-item-props-schema
[:map [:map
@ -772,10 +790,9 @@
(mf/use-fn (mf/use-fn
(mf/deps ids align-self) (mf/deps ids align-self)
(fn [value] (fn [value]
(let [value (keyword value)] (if (= align-self value)
(if (= align-self value) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil}))
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil})) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value})))))
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))))
;; Margin ;; Margin
on-margin-type-change on-margin-type-change
@ -803,23 +820,22 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing (keyword value)})))) (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value}))))
on-behaviour-v-change on-behaviour-v-change
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing (keyword value)})))) (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value}))))
;; Position ;; Position
on-change-position on-change-position
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value] (fn [value]
(let [value (keyword value)] (when (= value :static)
(when (= value :static) (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil})))
(st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)}))))
(st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)})))))
;; Z Index ;; Z Index
on-change-z-index on-change-z-index
@ -841,17 +857,16 @@
[:div {:class (stl/css :flex-element-menu)} [:div {:class (stl/css :flex-element-menu)}
(when (or is-layout-child? is-absolute?) (when (or is-layout-child? is-absolute?)
[:div {:class (stl/css :position-row)} [:div {:class (stl/css :position-row)}
[:> radio-buttons* {:class (stl/css :position-options) [:div {:class (stl/css :position-options)}
:selected (if is-absolute? "absolute" "static") [:& radio-buttons {:selected (if is-absolute? "absolute" "static")
:decode-fn keyword
:on-change on-change-position :on-change on-change-position
:name "layout-style" :name "layout-style"
:extended true :wide true}
:options [{:id "static-position" [:& radio-button {:value "static"
:label "Static" :id :static-position}]
:value "static"} [:& radio-button {:value "absolute"
{:id "absolute-position" :id :absolute-position}]]]
:label "Absolute"
:value "absolute"}]}]
[:div {:class (stl/css :z-index-wrapper) [:div {:class (stl/css :z-index-wrapper)
:title "z-index"} :title "z-index"}
@ -870,20 +885,22 @@
:behaviour-menu true :behaviour-menu true
:wrap (and ^boolean is-layout-child? :wrap (and ^boolean is-layout-child?
^boolean is-layout-container?))} ^boolean is-layout-container?))}
[:> element-behaviour-horizontal* {:is-auto is-layout-container? [:& element-behaviour-horizontal
:has-fill is-layout-child? {:is-auto is-layout-container?
:value (:layout-item-h-sizing values) :has-fill is-layout-child?
:on-change on-behaviour-h-change}] :value (:layout-item-h-sizing values)
[:> element-behaviour-vertical* {:is-auto is-layout-container? :on-change on-behaviour-h-change}]
:has-fill is-layout-child? [:& element-behaviour-vertical
:value (:layout-item-v-sizing values) {:is-auto is-layout-container?
:on-change on-behaviour-v-change}]]] :has-fill is-layout-child?
:value (:layout-item-v-sizing values)
:on-change on-behaviour-v-change}]]]
(when (and is-layout-child? is-flex-parent?) (when (and is-layout-child? is-flex-parent?)
[:div {:class (stl/css :align-row)} [:div {:class (stl/css :align-row)}
[:> align-self-row* {:is-col is-col? [:& align-self-row {:is-col is-col?
:value align-self :value align-self
:on-change on-align-self-change}]]) :on-change on-align-self-change}]])
(when is-layout-child? (when is-layout-child?
[:> margin-section* {:value (:layout-item-margin values) [:> margin-section* {:value (:layout-item-margin values)

View File

@ -34,8 +34,10 @@
grid-template-columns: auto auto; grid-template-columns: auto auto;
} }
.rotated { .vertical-behaviour {
transform: rotate(90deg); .rotated {
transform: rotate(90deg);
}
} }
.z-index-wrapper { .z-index-wrapper {
@ -72,6 +74,18 @@
gap: var(--sp-xs); gap: var(--sp-xs);
} }
.margin-mode {
@extend .button-tertiary;
grid-column: 3;
height: deprecated.$s-32;
svg {
@extend .button-icon;
}
&.selected {
@extend .button-icon-selected;
}
}
.margin-simple { .margin-simple {
display: grid; display: grid;
gap: var(--sp-xs); gap: var(--sp-xs);

View File

@ -25,9 +25,9 @@
[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.numeric-input :as deprecated-input] [app.main.ui.components.numeric-input :as deprecated-input]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.options.menus.border-radius :refer [border-radius-menu*]] [app.main.ui.workspace.sidebar.options.menus.border-radius :refer [border-radius-menu*]]
[app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]]
@ -209,6 +209,12 @@
proportion-lock proportion-lock
(get values :proportion-lock) (get values :proportion-lock)
clip-content-ref
(mf/use-ref nil)
show-in-viewer-ref
(mf/use-ref nil)
;; PRESETS ;; PRESETS
preset-state* preset-state*
(mf/use-state false) (mf/use-state false)
@ -327,19 +333,19 @@
;; CLIP CONTENT AND SHOW IN VIEWER ;; CLIP CONTENT AND SHOW IN VIEWER
on-change-clip-content on-change-clip-content
(mf/use-fn (mf/use-fn
(mf/deps ids values) (mf/deps ids)
(fn [] (fn [event]
(let [value (not (:show-content values))] (let [value (-> event dom/get-target dom/checked?)]
(st/emit! (dwsh/update-shapes ids (fn [shape] (assoc shape :show-content value))))))) (st/emit! (dwsh/update-shapes ids (fn [shape] (assoc shape :show-content (not value))))))))
on-change-show-in-viewer on-change-show-in-viewer
(mf/use-fn (mf/use-fn
(mf/deps ids values) (mf/deps ids)
(fn [] (fn [event]
(let [value (not (:hide-in-viewer values)) (let [value (-> event dom/get-target dom/checked?)
undo-id (js/Symbol)] undo-id (js/Symbol)]
(st/emit! (dwu/start-undo-transaction undo-id) (st/emit! (dwu/start-undo-transaction undo-id)
(dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape value)))) (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value)))))
(when-not value (when-not value
;; when a frame is no longer shown in view mode, cannot ;; when a frame is no longer shown in view mode, cannot
@ -388,23 +394,22 @@
(when preset-match (when preset-match
[:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]]
[:> radio-buttons* {:class (stl/css :radio-buttons) [:& radio-buttons {:selected (or (d/name orientation) "")
:selected (or (d/name orientation) "") :on-change on-orientation-change
:on-change on-orientation-change :name "frame-orientation"
:name "frame-orientation" :wide true
:options [{:id "size-vertical" :class (stl/css :radio-buttons)}
:icon i/size-vertical [:& radio-button {:icon i/size-vertical
:label (tr "workspace.options.orientation.vertical") :value "vert"
:value "vert"} :id "size-vertical"}]
{:id "size-horizontal" [:& radio-button {:icon i/size-horizontal
:icon i/size-horizontal :value "horiz"
:label (tr "workspace.options.orientation.horizontal") :id "size-horizontal"}]]
:value "horiz"}]}] [:> icon-button*
{:variant "ghost"
[:> icon-button* {:variant "ghost" :aria-label (tr "workspace.options.fit-content")
:aria-label (tr "workspace.options.fit-content") :on-pointer-down handle-fit-content
:on-pointer-down handle-fit-content :icon i/fit-content}]])
:icon i/fit-content}]])
(when (options :size) (when (options :size)
[:div {:class (stl/css :size)} [:div {:class (stl/css :size)}
@ -464,8 +469,8 @@
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:tooltip-placement "top-left" :tooltip-placement "top-left"
:icon (if proportion-lock "lock" "unlock") :icon (if proportion-lock "lock" "unlock")
:class (stl/css-case :selected (true? proportion-lock))
:disabled (= proportion-lock :multiple) :disabled (= proportion-lock :multiple)
:aria-pressed (true? proportion-lock)
:aria-label (if proportion-lock (tr "workspace.options.size.unlock") (tr "workspace.options.size.lock")) :aria-label (if proportion-lock (tr "workspace.options.size.unlock") (tr "workspace.options.size.lock"))
:on-click on-proportion-lock-change}]]) :on-click on-proportion-lock-change}]])
@ -553,24 +558,41 @@
:on-change on-rotation-change :on-change on-rotation-change
:class (stl/css :numeric-input) :class (stl/css :numeric-input)
:value (:rotation values)}]])) :value (:rotation values)}]]))
(when (options :radius) (when (options :radius)
[:> border-radius-menu* {:class (stl/css :border-radius) [:> border-radius-menu* {:class (stl/css :border-radius)
:ids ids :ids ids
:values values :values values
:applied-tokens applied-tokens}])]) :applied-tokens applied-tokens}])])
(when (or (options :clip-content)
(options :show-in-viewer)) (when (or (options :clip-content) (options :show-in-viewer))
[:div {:class (stl/css :clip-show)} [:div {:class (stl/css :clip-show)}
(when (options :clip-content) (when (options :clip-content)
[:> icon-button* {:variant "ghost" [:div {:class (stl/css :clip-content)}
:aria-pressed (not (:show-content values)) [:input {:type "checkbox"
:aria-label (tr "workspace.options.clip-content") :id "clip-content"
:on-click on-change-clip-content :ref clip-content-ref
:icon i/clip-content}]) :class (stl/css :clip-content-input)
:checked (not (:show-content values))
:on-change on-change-clip-content}]
[:label {:for "clip-content"
:title (tr "workspace.options.clip-content")
:class (stl/css-case :clip-content-label true
:selected (not (:show-content values)))}
[:> icon* {:icon-id i/clip-content}]]])
(when (options :show-in-viewer) (when (options :show-in-viewer)
[:> icon-button* {:variant "ghost" [:div {:class (stl/css :show-in-viewer)}
:aria-pressed (not (:hide-in-viewer values)) [:input {:type "checkbox"
:aria-label (tr "workspace.options.show-in-viewer") :id "show-in-viewer"
:on-click on-change-show-in-viewer :ref show-in-viewer-ref
:icon i/play}])])])) :class (stl/css :clip-content-input)
:checked (not (:hide-in-viewer values))
:on-change on-change-show-in-viewer}]
[:label {:for "show-in-viewer"
:title (tr "workspace.options.show-in-viewer")
:class (stl/css-case :clip-content-label true
:selected (not (:hide-in-viewer values)))}
[:> icon* {:icon-id i/play}]]])])]))

View File

@ -145,6 +145,16 @@
grid-column: 2/-1; grid-column: 2/-1;
} }
.lock-size-btn {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
height: deprecated.$s-32;
width: deprecated.$s-28;
&.selected {
@extend .button-icon-selected;
}
}
.lock-ratio-icon { .lock-ratio-icon {
@extend .button-icon; @extend .button-icon;
stroke: var(--icon-foreground); stroke: var(--icon-foreground);
@ -156,3 +166,30 @@
justify-content: flex-start; justify-content: flex-start;
gap: deprecated.$s-4; gap: deprecated.$s-4;
} }
.clip-content,
.show-in-viewer {
.clip-content-input {
display: none;
}
}
.clip-content-label {
@extend .button-tertiary;
height: var(--sp-xxxl);
width: var(--sp-xxxl);
border-radius: deprecated.$br-8;
}
.selected {
@extend .button-icon-selected;
}
.checkbox-button {
@extend .button-icon;
}
// TODO: Add a proper variable to this sizing
.numeric-input-measures {
--dropdown-width: var(--7-columns-dropdown-width);
}

View File

@ -19,15 +19,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.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.options.menus.typography :refer [text-options* [app.main.ui.workspace.sidebar.options.menus.typography :refer [text-options
typography-entry*]] typography-entry]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.text.content :as content] [app.util.text.content :as content]
@ -37,99 +37,96 @@
[potok.v2.core :as ptk] [potok.v2.core :as ptk]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc text-align-options* (mf/defc text-align-options
[{:keys [values on-change on-blur]}] [{:keys [values on-change on-blur] :as props}]
(let [{:keys [text-align]} values (let [{:keys [text-align]} values
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-change on-blur) (mf/deps on-change on-blur)
(fn [value] (fn [value]
(on-change {:text-align value}) (on-change {:text-align value})
(when (some? on-blur) (when (some? on-blur) (on-blur))))]
(on-blur))))]
[:> radio-buttons* {:class (stl/css :align-options) ;; --- Align
:selected text-align [:div {:class (stl/css :align-options)}
[:& radio-buttons {:selected text-align
:on-change handle-change :on-change handle-change
:name "align-text-options" :name "align-text-options"}
:options [{:id "text-align-left" [:& radio-button {:value "left"
:icon i/text-align-left :id "text-align-left"
:label (tr "workspace.options.text-options.text-align-left") :title (tr "workspace.options.text-options.text-align-left")
:value "left"} :icon i/text-align-left}]
{:id "text-align-center" [:& radio-button {:value "center"
:icon i/text-align-center :id "text-align-center"
:label (tr "workspace.options.text-options.text-align-center") :title (tr "workspace.options.text-options.text-align-center")
:value "center"} :icon i/text-align-center}]
{:id "text-align-right" [:& radio-button {:value "right"
:icon i/text-align-right :id "text-align-right"
:label (tr "workspace.options.text-options.text-align-right") :title (tr "workspace.options.text-options.text-align-right")
:value "right"} :icon i/text-align-right}]
{:id "text-align-justify" [:& radio-button {:value "justify"
:icon i/text-justify :id "text-align-justify"
:label (tr "workspace.options.text-options.text-align-justify") :title (tr "workspace.options.text-options.text-align-justify")
:value "justify"}]}])) :icon i/text-justify}]]]))
(mf/defc text-direction-options* (mf/defc text-direction-options
[{:keys [values on-change on-blur]}] [{:keys [values on-change on-blur] :as props}]
(let [direction (:text-direction values) (let [direction (:text-direction values)
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-change on-blur direction) (mf/deps on-change on-blur direction)
(fn [value] (fn [value]
(let [dir (if (= value direction) "none" value)] (let [dir (if (= value direction)
"none"
value)]
(on-change {:text-direction dir}) (on-change {:text-direction dir})
(when (some? on-blur) (when (some? on-blur) (on-blur)))))]
(on-blur)))))]
[:> radio-buttons* {:class (stl/css :text-direction-options) [:div {:class (stl/css :text-direction-options)}
:selected direction [:& radio-buttons {:selected direction
:on-change handle-change :on-change handle-change
:allow-empty true :name "text-direction-options"}
:name "text-direction-options" [:& radio-button {:value "ltr"
:options [{:id "ltr-text-direction" :type "checkbox"
:icon i/text-ltr :id "ltr-text-direction"
:label (tr "workspace.options.text-options.direction-ltr") :title (tr "workspace.options.text-options.direction-ltr")
:value "ltr"} :icon i/text-ltr}]
{:id "rtl-text-direction" [:& radio-button {:value "rtl"
:icon i/text-rtl :type "checkbox"
:label (tr "workspace.options.text-options.direction-rtl") :id "rtl-text-direction"
:value "rtl"}]}])) :title (tr "workspace.options.text-options.direction-rtl")
:icon i/text-rtl}]]]))
(mf/defc vertical-align* (mf/defc vertical-align
[{:keys [values on-change on-blur]}] [{:keys [values on-change on-blur] :as props}]
(let [{:keys [vertical-align]} values (let [{:keys [vertical-align]} values
vertical-align (or vertical-align "top") vertical-align (or vertical-align "top")
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-change on-blur) (mf/deps on-change on-blur)
(fn [value] (fn [value]
(on-change {:vertical-align value}) (on-change {:vertical-align value})
(when (some? on-blur) (when (some? on-blur) (on-blur))))]
(on-blur))))]
[:> radio-buttons* {:class (stl/css :vertical-align-options) [:div {:class (stl/css :vertical-align-options)}
:selected vertical-align [:& radio-buttons {:selected vertical-align
:on-change handle-change :on-change handle-change
:name "vertical-align-text-options" :name "vertical-align-text-options"}
:options [{:id "vertical-text-align-top" [:& radio-button {:value "top"
:icon i/text-top :id "vertical-text-align-top"
:label (tr "workspace.options.text-options.align-top") :title (tr "workspace.options.text-options.align-top")
:value "top"} :icon i/text-top}]
{:id "vertical-text-align-center" [:& radio-button {:value "center"
:icon i/text-middle :id "vertical-text-align-center"
:label (tr "workspace.options.text-options.align-middle") :title (tr "workspace.options.text-options.align-middle")
:value "center"} :icon i/text-middle}]
{:id "vertical-text-align-bottom" [:& radio-button {:value "bottom"
:icon i/text-bottom :id "vertical-text-align-bottom"
:label (tr "workspace.options.text-options.align-bottom") :title (tr "workspace.options.text-options.align-bottom")
:value "bottom"}]}])) :icon i/text-bottom}]]]))
(mf/defc grow-options* (mf/defc grow-options
[{:keys [ids values on-blur]}] [{:keys [ids values on-blur] :as props}]
(let [grow-type (:grow-type values) (let [grow-type (:grow-type values)
editor-instance (mf/deref refs/workspace-editor) editor-instance (mf/deref refs/workspace-editor)
@ -152,56 +149,55 @@
(st/emit! (dwwt/resize-wasm-text-all ids))) (st/emit! (dwwt/resize-wasm-text-all ids)))
;; We asynchronously commit so every sychronous event is resolved first and inside the transaction ;; We asynchronously commit so every sychronous event is resolved first and inside the transaction
(ts/schedule #(st/emit! (dwu/commit-undo-transaction uid)))) (ts/schedule #(st/emit! (dwu/commit-undo-transaction uid))))
(when (some? on-blur) (when (some? on-blur) (on-blur))))]
(on-blur))))]
[:> radio-buttons* {:class (stl/css :grow-options) [:div {:class (stl/css :grow-options)}
:selected (d/name grow-type) [:& radio-buttons {:selected (d/name grow-type)
:on-change handle-change-grow :on-change handle-change-grow
:name "grow-text-options" :name "grow-text-options"}
:options [{:id "text-fixed-grow" [:& radio-button {:value "fixed"
:icon i/text-fixed :id "text-fixed-grow"
:label (tr "workspace.options.text-options.grow-fixed") :title (tr "workspace.options.text-options.grow-fixed")
:value "fixed"} :icon i/text-fixed}]
{:id "text-auto-width-grow" [:& radio-button {:value "auto-width"
:icon i/text-auto-width :id "text-auto-width-grow"
:label (tr "workspace.options.text-options.grow-auto-width") :title (tr "workspace.options.text-options.grow-auto-width")
:value "auto-width"} :icon i/text-auto-width}]
{:id "text-auto-height-grow" [:& radio-button {:value "auto-height"
:icon i/text-auto-height :id "text-auto-height-grow"
:label (tr "workspace.options.text-options.grow-auto-height") :title (tr "workspace.options.text-options.grow-auto-height")
:value "auto-height"}]}])) :icon i/text-auto-height}]]]))
(mf/defc text-decoration-options* (mf/defc text-decoration-options
[{:keys [values on-change on-blur]}] [{:keys [values on-change on-blur] :as props}]
(let [text-decoration (or (:text-decoration values) "none") (let [text-decoration (or (:text-decoration values) "none")
handle-change handle-change
(mf/use-fn (mf/use-fn
(mf/deps on-change on-blur text-decoration) (mf/deps on-change on-blur text-decoration)
(fn [value] (fn [value]
(let [decoration (if (= value text-decoration) "none" value)] (let [decoration (if (= value text-decoration)
"none"
value)]
(on-change {:text-decoration decoration}) (on-change {:text-decoration decoration})
(when (some? on-blur) (when (some? on-blur) (on-blur)))))]
(on-blur)))))] [:div {:class (stl/css :text-decoration-options)}
[:& radio-buttons {:selected text-decoration
[:> radio-buttons* {:class (stl/css :text-decoration-options)
:selected text-decoration
:on-change handle-change :on-change handle-change
:name "grow-text-options" :name "text-decoration-options"}
:allow-empty true [:& radio-button {:value "underline"
:options [{:id "underline-text-decoration" :type "checkbox"
:icon i/text-underlined :id "underline-text-decoration"
:label (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline)) :title (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline))
:value "underline"} :icon i/text-underlined}]
{:id "line-through-text-decoration" [:& radio-button {:value "line-through"
:icon i/text-stroked :type "checkbox"
:label (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through)) :id "line-through-text-decoration"
:value "line-through"}]}])) :title (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through))
:icon i/text-stroked}]]]))
(mf/defc text-menu* (mf/defc text-menu
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [ids type values]}] [{:keys [ids type values] :as props}]
(let [file-id (mf/use-ctx ctx/current-file-id) (let [file-id (mf/use-ctx ctx/current-file-id)
typographies (mf/deref refs/workspace-file-typography) typographies (mf/deref refs/workspace-file-typography)
@ -294,19 +290,18 @@
multiple? (->> values vals (d/seek #(= % :multiple))) multiple? (->> values vals (d/seek #(= % :multiple)))
props opts #js {:ids ids
(mf/props {:ids ids :values values
:values values :on-change on-change
:on-change on-change :show-recent true
:show-recent true :on-blur
:on-blur (fn []
(fn [] (ts/schedule
(ts/schedule 100
100 (fn []
(fn [] (when (not= "INPUT" (-> (dom/get-active) (dom/get-tag-name)))
(when (not= "INPUT" (-> (dom/get-active) (dom/get-tag-name))) (let [node (txu/get-text-editor-content)]
(let [node (txu/get-text-editor-content)] (dom/focus! node))))))}]
(dom/focus! node))))))})]
(hooks/use-stream (hooks/use-stream
expand-stream expand-stream
#(swap! state* assoc-in [:more-options] true)) #(swap! state* assoc-in [:more-options] true))
@ -328,11 +323,11 @@
[:div {:class (stl/css :element-content)} [:div {:class (stl/css :element-content)}
(cond (cond
typography typography
[:> typography-entry* {:file-id typography-file-id [:& typography-entry {:file-id typography-file-id
:typography typography :typography typography
:local? (= typography-file-id file-id) :local? (= typography-file-id file-id)
:on-detach handle-detach-typography :on-detach handle-detach-typography
:on-change handle-change-typography}] :on-change handle-change-typography}]
(= typography-id :multiple) (= typography-id :multiple)
[:div {:class (stl/css :multiple-typography)} [:div {:class (stl/css :multiple-typography)}
@ -343,20 +338,19 @@
deprecated-icon/detach]] deprecated-icon/detach]]
:else :else
[:> text-options* props]) [:> text-options opts])
[:div {:class (stl/css :text-align-options)} [:div {:class (stl/css :text-align-options)}
[:> text-align-options* props] [:> text-align-options opts]
[:> grow-options* props] [:> grow-options opts]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "labels.options") :aria-label (tr "labels.options")
:aria-pressed more-options-open?
:data-testid "text-align-options-button" :data-testid "text-align-options-button"
:on-click toggle-more-options :on-click toggle-more-options
:icon i/menu}]] :icon i/menu}]]
(when more-options-open? (when more-options-open?
[:div {:class (stl/css :text-decoration-options)} [:div {:class (stl/css :text-decoration-options)}
[:> vertical-align* props] [:> vertical-align opts]
[:> text-decoration-options* props] [:> text-decoration-options opts]
[:> text-direction-options* props]])])])) [:> text-direction-options opts]])])]))

View File

@ -22,10 +22,10 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.editable-select :refer [editable-select]] [app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -424,24 +424,27 @@
(on-change {:text-transform type})) (on-change {:text-transform type}))
(when (some? on-blur) (on-blur)))] (when (some? on-blur) (on-blur)))]
[:> radio-buttons* {:selected text-transform [:div {:class (stl/css :text-transform)}
[:& radio-buttons {:selected text-transform
:on-change handle-change :on-change handle-change
:name "text-transform" :name "text-transform"}
:allow-empty true [:& radio-button {:icon i/text-uppercase
:options [{:id "text-transform-uppercase" :type "checkbox"
:icon i/text-uppercase :title (tr "inspect.attributes.typography.text-transform.uppercase")
:label (tr "inspect.attributes.typography.text-transform.uppercase") :value "uppercase"
:value "uppercase"} :id "text-transform-uppercase"}]
{:id "text-transform-capitalize" [:& radio-button {:icon i/text-mixed
:icon i/text-mixed :type "checkbox"
:label (tr "inspect.attributes.typography.text-transform.capitalize") :value "capitalize"
:value "capitalize"} :title (tr "inspect.attributes.typography.text-transform.capitalize")
{:id "text-transform-lowercase" :id "text-transform-capitalize"}]
:icon i/text-lowercase [:& radio-button {:icon i/text-lowercase
:label (tr "inspect.attributes.typography.text-transform.lowercase") :type "checkbox"
:value "lowercase"}]}])) :title (tr "inspect.attributes.typography.text-transform.lowercase")
:value "lowercase"
:id "text-transform-lowercase"}]]]))
(mf/defc text-options* (mf/defc text-options
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [ids editor values on-change on-blur show-recent]}] [{:keys [ids editor values on-change on-blur show-recent]}]
(let [full-size-selector? (and show-recent (= (mf/use-ctx ctx/sidebar) :right)) (let [full-size-selector? (and show-recent (= (mf/use-ctx ctx/sidebar) :right))
@ -499,13 +502,14 @@
:on-click on-close} :on-click on-close}
deprecated-icon/tick]] deprecated-icon/tick]]
[:> text-options* {:values typography [:& text-options {:values typography
:on-change on-change :on-change on-change
:show-recent false}]] :show-recent false}]]
[:div {:class (stl/css :typography-info-wrapper)} [:div {:class (stl/css :typography-info-wrapper)}
[:div {:class (stl/css :typography-name-wrapper)} [:div {:class (stl/css :typography-name-wrapper)}
[:div {:class (stl/css :typography-sample) [:div {:class (stl/css :typography-sample)
:style {:font-family (:font-family typography) :style {:font-family (:font-family typography)
:font-weight (:font-weight typography) :font-weight (:font-weight typography)
:font-style (:font-style typography)}} :font-style (:font-style typography)}}
@ -545,7 +549,7 @@
:on-click navigate-to-library} :on-click navigate-to-library}
(tr "workspace.assets.typography.go-to-edit")])])]))) (tr "workspace.assets.typography.go-to-edit")])])])))
(mf/defc typography-entry* (mf/defc typography-entry
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [file-id typography local? selected? on-click on-change on-detach on-context-menu editing? renaming? focus-name? external-open*]}] [{:keys [file-id typography local? selected? on-click on-change on-detach on-context-menu editing? renaming? focus-name? external-open*]}]
(let [name-input-ref (mf/use-ref) (let [name-input-ref (mf/use-ref)

View File

@ -324,6 +324,15 @@
} }
} }
} }
.text-transform {
@extend .asset-element;
width: fit-content;
padding: 0;
background-color: var(--radio-btns-background-color);
&:hover {
background-color: var(--radio-btns-background-color);
}
}
} }
} }

View File

@ -141,9 +141,8 @@
[:> icon-button* {:variant "secondary" [:> icon-button* {:variant "secondary"
:icon i/menu :icon i/menu
:class (stl/css-case :shadow-basic-button true :class (stl/css-case :shadow-basic-button true
:hidden hidden?) :selected is-open)
:aria-pressed is-open :aria-label "open more options"
:aria-label (tr "labels.options")
:disabled hidden? :disabled hidden?
:on-click on-toggle-open}] :on-click on-toggle-open}]
[:& select {:class (stl/css :shadow-basic-select) [:& select {:class (stl/css :shadow-basic-select)

View File

@ -43,8 +43,14 @@
.shadow-basic-button { .shadow-basic-button {
border-radius: $br-8 0 0 $br-8; border-radius: $br-8 0 0 $br-8;
&.hidden {
border: deprecated.$s-1 solid var(--input-border-color-disabled); &.selected {
--button-bg-color: var(--color-background-quaternary);
--button-fg-color: var(--color-accent-primary);
}
&:disabled {
border: $b-1 solid var(--color-background-quaternary);
} }
} }

View File

@ -171,7 +171,7 @@
[:& blur-menu {:type type :ids blur-ids :values blur-values}]) [:& blur-menu {:type type :ids blur-ids :values blur-values}])
(when-not (empty? text-ids) (when-not (empty? text-ids)
[:> ot/text-menu* {:type type :ids text-ids :values text-values}]) [:& ot/text-menu {:type type :ids text-ids :values text-values}])
(when-not (empty? svg-values) (when-not (empty? svg-values)
[:& svg-attrs-menu {:ids ids :values svg-values}]) [:& svg-attrs-menu {:ids ids :values svg-values}])

View File

@ -478,7 +478,7 @@
[:& constraints-menu {:ids constraint-ids :values constraint-values}]) [:& constraints-menu {:ids constraint-ids :values constraint-values}])
(when-not (empty? text-ids) (when-not (empty? text-ids)
[:> ot/text-menu* {:type type :ids text-ids :values text-values}]) [:& ot/text-menu {:type type :ids text-ids :values text-values}])
(when-not (empty? fill-ids) (when-not (empty? fill-ids)
[:> fill/fill-menu* {:type type [:> fill/fill-menu* {:type type

View File

@ -25,7 +25,7 @@
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu*]] [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc options* (mf/defc options*
@ -162,9 +162,10 @@
{:ids ids {:ids ids
:values (select-keys shape constraint-attrs)}]) :values (select-keys shape constraint-attrs)}])
[:> text-menu* {:ids ids [:& text-menu
:type type {:ids ids
:values text-values}] :type type
:values text-values}]
[:> fill/fill-menu* [:> fill/fill-menu*
{:ids ids {:ids ids

View File

@ -12,15 +12,14 @@
[app.common.types.token :as cto] [app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob] [app.common.types.tokens-lib :as ctob]
[app.main.data.workspace.tokens.errors :as wte] [app.main.data.workspace.tokens.errors :as wte]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.forms :as forms] [app.main.ui.forms :as forms]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.workspace.tokens.management.forms.controls :as token.controls] [app.main.ui.workspace.tokens.management.forms.controls :as token.controls]
[app.main.ui.workspace.tokens.management.forms.generic-form :as generic] [app.main.ui.workspace.tokens.management.forms.generic-form :as generic]
[app.main.ui.workspace.tokens.management.forms.validators :refer [check-self-reference [app.main.ui.workspace.tokens.management.forms.validators :refer [check-self-reference default-validate-token]]
default-validate-token]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
@ -232,17 +231,18 @@
:aria-label (tr "workspace.tokens.shadow-add-shadow") :aria-label (tr "workspace.tokens.shadow-add-shadow")
:on-click on-add-shadow-block :on-click on-add-shadow-block
:icon i/add}] :icon i/add}]
[:> radio-buttons* {:selected (d/name tab) [:& radio-buttons {:class (stl/css :listing-options)
:on-change handle-toggle :selected (d/name tab)
:name "reference-composite-tab" :on-change handle-toggle
:options [{:id "composite-opt" :name "reference-composite-tab"}
:icon i/layers [:& radio-button {:icon i/layers
:label (tr "workspace.tokens.individual-tokens") :value "composite"
:value "composite"} :title (tr "workspace.tokens.individual-tokens")
{:id "reference-opt" :id "composite-opt"}]
:icon i/tokens [:& radio-button {:icon i/tokens
:label (tr "workspace.tokens.use-reference") :value "reference"
:value "reference"}]}]] :title (tr "workspace.tokens.use-reference")
:id "reference-opt"}]]]
(if (= tab :composite) (if (= tab :composite)
[:> composite-form* {:token token [:> composite-form* {:token token

View File

@ -12,13 +12,11 @@
[app.common.types.token :as cto] [app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob] [app.common.types.tokens-lib :as ctob]
[app.main.data.workspace.tokens.errors :as wte] [app.main.data.workspace.tokens.errors :as wte]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.workspace.tokens.management.forms.controls :as token.controls] [app.main.ui.workspace.tokens.management.forms.controls :as token.controls]
[app.main.ui.workspace.tokens.management.forms.generic-form :as generic] [app.main.ui.workspace.tokens.management.forms.generic-form :as generic]
[app.main.ui.workspace.tokens.management.forms.validators :refer [check-coll-self-reference [app.main.ui.workspace.tokens.management.forms.validators :refer [check-coll-self-reference check-self-reference default-validate-token]]
check-self-reference
default-validate-token]]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[cuerdas.core :as str] [cuerdas.core :as str]
@ -187,17 +185,18 @@
[:* [:*
[:div {:class (stl/css :title-bar)} [:div {:class (stl/css :title-bar)}
[:div {:class (stl/css :title)} (tr "labels.typography")] [:div {:class (stl/css :title)} (tr "labels.typography")]
[:> radio-buttons* {:selected (d/name tab) [:& radio-buttons {:class (stl/css :listing-options)
:on-change handle-toggle :selected (d/name tab)
:name "reference-composite-tab" :on-change handle-toggle
:options [{:id "composite-opt" :name "reference-composite-tab"}
:icon i/layers [:& radio-button {:icon i/layers
:label (tr "workspace.tokens.individual-tokens") :value "composite"
:value "composite"} :title (tr "workspace.tokens.individual-tokens")
{:id "reference-opt" :id "composite-opt"}]
:icon i/tokens [:& radio-button {:icon i/tokens
:label (tr "workspace.tokens.use-reference") :value "reference"
:value "reference"}]}]] :title (tr "workspace.tokens.use-reference")
:id "reference-opt"}]]]
[:div {:class (stl/css :inputs-wrapper)} [:div {:class (stl/css :inputs-wrapper)}
(if (= tab :composite) (if (= tab :composite)
[:> composite-form* {:token token [:> composite-form* {:token token

View File

@ -119,7 +119,6 @@
:on-change on-switch-theme :on-change on-switch-theme
:default-checked selected?}]] :default-checked selected?}]]
[:div {:class (stl/css :theme-actions-row)} [:div {:class (stl/css :theme-actions-row)}
(let [sets-count (some-> theme :sets seq count)] (let [sets-count (some-> theme :sets seq count)]
[:> button* {:class (stl/css-case :sets-count-button sets-count [:> button* {:class (stl/css-case :sets-count-button sets-count

View File

@ -17,10 +17,9 @@
[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.file-uploader :refer [file-uploader*]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.timers :as ts] [app.util.timers :as ts]
@ -28,7 +27,7 @@
[potok.v2.core :as ptk] [potok.v2.core :as ptk]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc image-upload* (mf/defc image-upload
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[] []
(let [ref (mf/use-ref nil) (let [ref (mf/use-ref nil)
@ -54,17 +53,18 @@
:position (gpt/point x y)}] :position (gpt/point x y)}]
(st/emit! (dwm/upload-media-workspace params)))))] (st/emit! (dwm/upload-media-workspace params)))))]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image))
:icon i/img :aria-label (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image))
:aria-label (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image)) :on-click on-click
:tooltip-placement "bottom" :class (stl/css :main-toolbar-options-button)}
:on-click on-click} deprecated-icon/img
[:> file-uploader* {:input-id "image-upload" [:& file-uploader
:accept dwm/accept-image-types {:input-id "image-upload"
:multi true :accept dwm/accept-image-types
:ref ref :multi true
:on-selected on-selected}]]])) :ref ref
:on-selected on-selected}]]]))
(def ^:private toolbar-hidden-ref (def ^:private toolbar-hidden-ref
(l/derived (fn [state] (l/derived (fn [state]
@ -136,104 +136,98 @@
[:ul {:class (stl/css :main-toolbar-options) [:ul {:class (stl/css :main-toolbar-options)
:data-testid "toolbar-options"} :data-testid "toolbar-options"}
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.move" (sc/get-tooltip :move))
:icon i/move :aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move))
:aria-pressed (and (nil? drawtool) (not edition)) :class (stl/css-case :main-toolbar-options-button true
:aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move)) :selected (and (nil? drawtool)
:tooltip-placement "bottom" (not edition)))
:on-click interrupt}]] :on-click interrupt}
deprecated-icon/move]]
[:* [:*
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title test-tooltip-board-text
:icon i/board :aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
:aria-pressed (= drawtool :frame) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :frame))
:aria-label test-tooltip-board-text :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "frame"
:on-click select-drawtool :data-testid "artboard-btn"}
:data-tool "frame" deprecated-icon/board]]
:data-testid "artboard-btn"}]]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
:icon i/rectangle :aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
:aria-pressed (= drawtool :rect) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :rect))
:aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "rect"
:on-click select-drawtool :data-testid "rect-btn"}
:data-tool "rect" deprecated-icon/rectangle]]
:data-testid "rect-btn"}]]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
:icon i/elipse :aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
:aria-pressed (= drawtool :circle) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :circle))
:aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "circle"
:on-click select-drawtool :data-testid "ellipse-btn"}
:data-tool "circle" deprecated-icon/elipse]]
:data-testid "ellipse-btn"}]]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
:icon i/text :aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
:aria-pressed (= drawtool :text) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :text))
:aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "text"}
:on-click select-drawtool deprecated-icon/text]]
:data-tool "text"
:data-testid "text-btn"}]]
[:> image-upload*] [:& image-upload]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
:icon i/curve :aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
:aria-pressed (= drawtool :curve) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :curve))
:aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "curve"
:on-click select-drawtool :data-testid "curve-btn"}
:data-tool "curve" deprecated-icon/curve]]
:data-testid "curve-btn"}]]
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
:icon i/path :aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
:aria-pressed (= drawtool :path) :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :path))
:aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) :on-click select-drawtool
:tooltip-placement "bottom" :data-tool "path"
:on-click select-drawtool :data-testid "path-btn"}
:data-tool "path" deprecated-icon/path]]
:data-testid "path-btn"}]]
(when (features/active-feature? @st/state "plugins/runtime") (when (features/active-feature? @st/state "plugins/runtime")
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
:icon i/puzzle :aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
:aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins)) :class (stl/css :main-toolbar-options-button)
:tooltip-placement "bottom" :on-click #(st/emit!
:on-click #(st/emit! (ptk/data-event ::ev/event {::ev/name "open-plugins-manager"
(ptk/data-event ::ev/event {::ev/name "open-plugins-manager" ::ev/origin "workspace:toolbar"})
::ev/origin "workspace:toolbar"}) (modal/show :plugin-management {}))
(modal/show :plugin-management {})) :data-tool "plugins"
:data-tool "plugins" :data-testid "plugins-btn"}
:data-testid "plugins-btn"}]]) deprecated-icon/puzzle]])
(when *assert* (when *assert*
[:li [:li
[:> icon-button* {:variant "ghost" [:button
:class (stl/css :main-toolbar-options-button) {:title "Debugging tool"
:icon i/bug :class (stl/css-case :main-toolbar-options-button true :selected (contains? layout :debug-panel))
:aria-pressed (contains? layout :debug-panel) :on-click toggle-debug-panel}
:aria-label (tr "workspace.toolbar.debug") deprecated-icon/bug]])]]
:tooltip-placement "bottom"
:on-click toggle-debug-panel}]])]]
[:button {:title (tr "workspace.toolbar.toggle-toolbar") [:button {:title (tr "workspace.toolbar.toggle-toolbar")
:aria-label (tr "workspace.toolbar.toggle-toolbar") :aria-label (tr "workspace.toolbar.toggle-toolbar")
:class (stl/css :toolbar-handler) :class (stl/css :toolbar-handler)
:on-click toggle-toolbar} :on-click toggle-toolbar}
[:div {:class (stl/css :toolbar-handler-btn)}]]]))) [:div {:class (stl/css :toolbar-handler-btn)}]]])))

View File

@ -54,7 +54,6 @@
align-items: center; align-items: center;
margin: 0; margin: 0;
opacity: deprecated.$op-10; opacity: deprecated.$op-10;
gap: var(--sp-xs);
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
li { li {
@ -63,8 +62,21 @@
} }
.main-toolbar-options-button { .main-toolbar-options-button {
@extend .button-tertiary;
height: deprecated.$s-36; height: deprecated.$s-36;
width: deprecated.$s-36; width: deprecated.$s-36;
flex-shrink: 0;
border-radius: deprecated.$s-8;
margin: 0 deprecated.$s-2;
svg {
@extend .button-icon;
stroke: var(--color-foreground-secondary);
}
&.selected {
@extend .button-icon-selected;
}
} }
.toolbar-handler { .toolbar-handler {
@ -85,3 +97,7 @@
background-color: var(--palette-handler-background-color); background-color: var(--palette-handler-background-color);
} }
} }
ul.main-toolbar-panels {
display: none;
}

View File

@ -28,7 +28,6 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.css-cursors :as cur] [app.main.ui.css-cursors :as cur]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.viewport.viewport-ref :as uwvv] [app.main.ui.workspace.viewport.viewport-ref :as uwvv]
@ -60,13 +59,11 @@
[:div {:class (stl/css :grid-actions-container)} [:div {:class (stl/css :grid-actions-container)}
[:div {:class (stl/css :grid-actions-title)} [:div {:class (stl/css :grid-actions-title)}
(tr "workspace.layout-grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]] (tr "workspace.layout-grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]]
[:> button* {:variant "secondary" [:button {:class (stl/css :locate-btn)
:class (stl/css :action-btn) :on-click #(st/emit! (dwge/locate-board (:id shape)))}
:on-click #(st/emit! (dwge/locate-board (:id shape)))}
(tr "workspace.layout-grid.editor.top-bar.locate")] (tr "workspace.layout-grid.editor.top-bar.locate")]
[:> button* {:variant "primary" [:button {:class (stl/css :done-btn)
:class (stl/css :action-btn) :on-click #(st/emit! (dw/clear-edition-mode))}
:on-click #(st/emit! (dw/clear-edition-mode))}
(tr "workspace.layout-grid.editor.top-bar.done")]]]) (tr "workspace.layout-grid.editor.top-bar.done")]]])
(mf/defc grid-editor-frame (mf/defc grid-editor-frame

View File

@ -138,8 +138,18 @@
padding-left: deprecated.$s-8; padding-left: deprecated.$s-8;
} }
.action-btn { .locate-btn {
padding: 0 var(--sp-xl); @extend .button-secondary;
text-transform: uppercase;
padding: deprecated.$s-8 deprecated.$s-20;
font-size: deprecated.$fs-11;
}
.done-btn {
@extend .button-primary;
text-transform: uppercase;
padding: deprecated.$s-8 deprecated.$s-20;
font-size: deprecated.$fs-11;
} }
.close-btn { .close-btn {

View File

@ -11,11 +11,40 @@
[app.main.data.workspace.path :as drp] [app.main.data.workspace.path :as drp]
[app.main.data.workspace.path.shortcuts :as sc] [app.main.data.workspace.path.shortcuts :as sc]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def ^:private pentool-icon
(deprecated-icon/icon-xref :pentool (stl/css :pentool-icon :pathbar-icon)))
(def ^:private move-icon
(deprecated-icon/icon-xref :move (stl/css :move-icon :pathbar-icon)))
(def ^:private add-icon
(deprecated-icon/icon-xref :add (stl/css :add-icon :pathbar-icon)))
(def ^:private remove-icon
(deprecated-icon/icon-xref :remove (stl/css :remove :pathbar-icon)))
(def ^:private merge-nodes-icon
(deprecated-icon/icon-xref :merge-nodes (stl/css :merge-nodes-icon :pathbar-icon)))
(def ^:private join-nodes-icon
(deprecated-icon/icon-xref :join-nodes (stl/css :join-nodes-icon :pathbar-icon)))
(def ^:private separate-nodes-icon
(deprecated-icon/icon-xref :separate-nodes (stl/css :separate-nodes-icon :pathbar-icon)))
(def ^:private to-corner-icon
(deprecated-icon/icon-xref :to-corner (stl/css :to-corner-icon :pathbar-icon)))
(def ^:private to-curve-icon
(deprecated-icon/icon-xref :to-curve (stl/css :to-curve-icon :pathbar-icon)))
(def ^:private snap-nodes-icon
(deprecated-icon/icon-xref :snap-nodes (stl/css :snap-nodes-icon :pathbar-icon)))
(defn check-enabled [content selected-points] (defn check-enabled [content selected-points]
(when content (when content
(let [segments (path.segm/get-segments-with-points content selected-points) (let [segments (path.segm/get-segments-with-points content selected-points)
@ -115,91 +144,76 @@
[:div {:class (stl/css :sub-actions) [:div {:class (stl/css :sub-actions)
:data-dont-clear-path true} :data-dont-clear-path true}
[:div {:class (stl/css :sub-actions-group)} [:div {:class (stl/css :sub-actions-group)}
;; Draw Mode ;; Draw Mode
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :is-toggled (= edit-mode :draw)
:class (stl/css :topbar-btn) :topbar-btn true)
:icon i/pentool :title (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:aria-pressed (= edit-mode :draw) :on-click on-select-draw-mode}
:aria-label (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes)) pentool-icon]
:tooltip-placement "bottom"
:on-click on-select-draw-mode}]
;; Edit mode ;; Edit mode
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :is-toggled (= edit-mode :move)
:class (stl/css :topbar-btn) :topbar-btn true)
:icon i/move :title (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes))
:aria-pressed (= edit-mode :move) :on-click on-select-edit-mode}
:aria-label (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes)) move-icon]]
:tooltip-placement "bottom"
:on-click on-select-edit-mode}]]
[:div {:class (stl/css :sub-actions-group)} [:div {:class (stl/css :sub-actions-group)}
;; Add Node ;; Add Node
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:add-node enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/add :title (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node))
:aria-label (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node)) :on-click on-add-node}
:tooltip-placement "bottom" add-icon]
:on-click on-add-node
:disabled (not (:add-node enabled-buttons))}]
;; Remove node ;; Remove node
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:remove-node enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/remove :title (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node))
:aria-label (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node)) :on-click on-remove-node}
:tooltip-placement "bottom" remove-icon]]
:on-click on-remove-node
:disabled (not (:remove-node enabled-buttons))}]]
[:div {:class (stl/css :sub-actions-group)} [:div {:class (stl/css :sub-actions-group)}
;; Merge Nodes ;; Merge Nodes
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:merge-nodes enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/merge-nodes :title (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes))
:aria-label (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes)) :on-click on-merge-nodes}
:tooltip-placement "bottom" merge-nodes-icon]
:on-click on-merge-nodes
:disabled (not (:merge-nodes enabled-buttons))}]
;; Join Nodes ;; Join Nodes
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:join-nodes enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/join-nodes :title (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes))
:aria-label (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes)) :on-click on-join-nodes}
:tooltip-placement "bottom" join-nodes-icon]
:on-click on-join-nodes
:disabled (not (:join-nodes enabled-buttons))}]
;; Separate Nodes ;; Separate Nodes
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:separate-nodes enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/separate-nodes :title (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes))
:aria-label (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes)) :on-click on-separate-nodes}
:tooltip-placement "bottom" separate-nodes-icon]]
:on-click on-separate-nodes
:disabled (not (:separate-nodes enabled-buttons))}]]
[:div {:class (stl/css :sub-actions-group)} [:div {:class (stl/css :sub-actions-group)}
; Make Corner ; Make Corner
[:> icon-button* {:variant "ghost" [:button {:disabled (not (:make-corner enabled-buttons))
:class (stl/css :topbar-btn) :class (stl/css :topbar-btn)
:icon i/to-corner :title (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner))
:aria-label (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner)) :on-click on-make-corner}
:tooltip-placement "bottom" to-corner-icon]
:on-click on-make-corner
:disabled (not (:make-corner enabled-buttons))}]
;; Make Curve
[:> icon-button* {:variant "ghost"
:class (stl/css :topbar-btn)
:icon i/to-curve
:aria-label (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:tooltip-placement "bottom"
:on-click on-make-curve
:disabled (not (:make-curve enabled-buttons))}]]
;; Make Curve
[:button {:disabled (not (:make-curve enabled-buttons))
:class (stl/css :topbar-btn)
:title (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:on-click on-make-curve}
to-curve-icon]]
[:div {:class (stl/css :sub-actions-group)} [:div {:class (stl/css :sub-actions-group)}
;; Toggle snap ;; Toggle snap
[:> icon-button* {:variant "ghost" [:button {:class (stl/css-case :is-toggled snap-toggled
:class (stl/css :topbar-btn) :topbar-btn true)
:icon i/snap-nodes :title (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes))
:aria-pressed snap-toggled :on-click on-toggle-snap}
:aria-label (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes)) snap-nodes-icon]]]))
:tooltip-placement "bottom"
:on-click on-toggle-snap}]]]))

View File

@ -34,11 +34,27 @@
align-items: center; align-items: center;
margin: 0; margin: 0;
opacity: deprecated.$op-10; opacity: deprecated.$op-10;
gap: var(--sp-xs);
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
} }
.topbar-btn { .topbar-btn {
--pathbar-icon-color: var(--color-foreground-secondary);
@extend .button-tertiary;
height: deprecated.$s-36; height: deprecated.$s-36;
width: deprecated.$s-36; width: deprecated.$s-36;
flex-shrink: 0;
background-color: transparent;
border-radius: deprecated.$s-8;
border: none;
margin: 0 deprecated.$s-2;
&.is-toggled {
--pathbar-icon-color: var(--button-radio-foreground-color-active);
background-color: var(--button-radio-background-color-active);
}
.pathbar-icon {
@extend .button-icon;
stroke: var(--pathbar-icon-color);
}
} }

View File

@ -10,7 +10,6 @@
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]] [app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]]
[app.main.ui.workspace.viewport.path-actions :refer [path-actions*]] [app.main.ui.workspace.viewport.path-actions :refer [path-actions*]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -35,9 +34,8 @@
[:> i18n/tr-html* [:> i18n/tr-html*
{:tag-name "span" {:tag-name "span"
:content (tr "workspace.top-bar.view-only")}]] :content (tr "workspace.top-bar.view-only")}]]
[:> button* {:variant "primary" [:button {:class (stl/css :done-btn)
:class (stl/css :done-btn) :on-click handle-close-view-mode}
:on-click handle-close-view-mode}
(tr "workspace.top-bar.read-only.done")]]])) (tr "workspace.top-bar.read-only.done")]]]))
(mf/defc path-edition-bar* (mf/defc path-edition-bar*

View File

@ -45,7 +45,10 @@
} }
.done-btn { .done-btn {
padding: 0 var(--sp-xl); @extend .button-primary;
text-transform: uppercase;
padding: deprecated.$s-8 deprecated.$s-20;
font-size: deprecated.$fs-11;
} }
.viewport-actions-no-rulers { .viewport-actions-no-rulers {

View File

@ -5426,10 +5426,6 @@ msgstr "Ungroup"
msgid "workspace.colorpicker.color-tokens" msgid "workspace.colorpicker.color-tokens"
msgstr "Color tokens" msgstr "Color tokens"
#: src/app/main/ui/workspace/colorpicker.cljs:434
msgid "workspace.colorpicker.get-color"
msgstr "Get color"
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506 #: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506
msgid "workspace.component.swap.loop-error" msgid "workspace.component.swap.loop-error"
msgstr "Components can't be nested inside themselves." msgstr "Components can't be nested inside themselves."
@ -5720,10 +5716,6 @@ msgstr "Full screen"
msgid "workspace.header.zoom-selected" msgid "workspace.header.zoom-selected"
msgstr "Zoom to selected" msgstr "Zoom to selected"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:422
msgid "workspace.layout-grid.editor.margin.expand"
msgstr "Show 4 sided margin options"
#: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:859 #: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:859
msgid "workspace.layout-grid.editor.options.edit-grid" msgid "workspace.layout-grid.editor.options.edit-grid"
msgstr "Edit grid" msgstr "Edit grid"
@ -5776,30 +5768,6 @@ msgstr "Locate"
msgid "workspace.layout-grid.editor.top-bar.locate.tooltip" msgid "workspace.layout-grid.editor.top-bar.locate.tooltip"
msgstr "Locate grid layout" msgstr "Locate grid layout"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:449
msgid "workspace.layout-item.fit-content-horizontal"
msgstr "Fit content (Horizontal)"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:477
msgid "workspace.layout-item.fit-content-vertical"
msgstr "Fit content (Vertical)"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:465
msgid "workspace.layout-item.fix-height"
msgstr "Fix height"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:439
msgid "workspace.layout-item.fix-width"
msgstr "Fix width"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:471
msgid "workspace.layout-item.height-100"
msgstr "Height 100%"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:444
msgid "workspace.layout-item.width-100"
msgstr "Width 100%"
#: src/app/main/ui/workspace/libraries.cljs #: src/app/main/ui/workspace/libraries.cljs
#, unused #, unused
msgid "workspace.libraries.add" msgid "workspace.libraries.add"
@ -6400,30 +6368,6 @@ msgstr "After delay"
msgid "workspace.options.interaction-animation" msgid "workspace.options.interaction-animation"
msgstr "Animation" msgstr "Animation"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:616
msgid "workspace.options.interaction-animation-direction-down"
msgstr "Down"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:593
msgid "workspace.options.interaction-animation-direction-in"
msgstr "In"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:612
msgid "workspace.options.interaction-animation-direction-left"
msgstr "Left"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:596
msgid "workspace.options.interaction-animation-direction-out"
msgstr "Out"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:608
msgid "workspace.options.interaction-animation-direction-right"
msgstr "Right"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:620
msgid "workspace.options.interaction-animation-direction-up"
msgstr "Up"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383
msgid "workspace.options.interaction-animation-dissolve" msgid "workspace.options.interaction-animation-dissolve"
msgstr "Dissolve" msgstr "Dissolve"
@ -6869,14 +6813,6 @@ msgstr "More color tokens"
msgid "workspace.options.opacity" msgid "workspace.options.opacity"
msgstr "Opacity" msgstr "Opacity"
#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:401
msgid "workspace.options.orientation.horizontal"
msgstr "Horizontal"
#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:397
msgid "workspace.options.orientation.vertical"
msgstr "Vertical"
#: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs #: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
#, unused #, unused
msgid "workspace.options.position" msgid "workspace.options.position"
@ -7715,7 +7651,7 @@ msgstr "Components"
msgid "workspace.sidebar.layers.filter" msgid "workspace.sidebar.layers.filter"
msgstr "Filter" msgstr "Filter"
#: src/app/main/ui/workspace/sidebar/layers.cljs:310, src/app/main/ui/workspace/sidebar/layers.cljs:338 #: src/app/main/ui/workspace/sidebar/layers.cljs:311, src/app/main/ui/workspace/sidebar/layers.cljs:339
msgid "workspace.sidebar.layers.frames" msgid "workspace.sidebar.layers.frames"
msgstr "Boards" msgstr "Boards"

View File

@ -5407,10 +5407,6 @@ msgstr "Desagrupar"
msgid "workspace.colorpicker.color-tokens" msgid "workspace.colorpicker.color-tokens"
msgstr "Tokens de color" msgstr "Tokens de color"
#: src/app/main/ui/workspace/colorpicker.cljs:434
msgid "workspace.colorpicker.get-color"
msgstr "Absorber color"
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506 #: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506
msgid "workspace.component.swap.loop-error" msgid "workspace.component.swap.loop-error"
msgstr "Los componentes no pueden anidarse dentro de sí mismos." msgstr "Los componentes no pueden anidarse dentro de sí mismos."
@ -5696,12 +5692,8 @@ msgstr "Pantalla completa"
msgid "workspace.header.zoom-selected" msgid "workspace.header.zoom-selected"
msgstr "Zoom a selección" msgstr "Zoom a selección"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:422 #: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:274, src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:276, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:868
msgid "workspace.layout-grid.editor.margin.expand" msgid "workspace.layout_grid.editor.options.edit-grid"
msgstr "Mostrar el margen a 4 lados"
#: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:859
msgid "workspace.layout-grid.editor.options.edit-grid"
msgstr "Editar rejilla" msgstr "Editar rejilla"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:1539 #: src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:1539
@ -5752,30 +5744,6 @@ msgstr "Mostrar"
msgid "workspace.layout-grid.editor.top-bar.locate.tooltip" msgid "workspace.layout-grid.editor.top-bar.locate.tooltip"
msgstr "Mostrar grid layout" msgstr "Mostrar grid layout"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:449
msgid "workspace.layout-item.fit-content-horizontal"
msgstr "Ajustar contenido (horizontal)"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:477
msgid "workspace.layout-item.fit-content-vertical"
msgstr "Ajustar contenido (vertical)"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:465
msgid "workspace.layout-item.fix-height"
msgstr "Fijar altura"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:439
msgid "workspace.layout-item.fix-width"
msgstr "Fijar anchura"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:471
msgid "workspace.layout-item.height-100"
msgstr "Altura 100%"
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:444
msgid "workspace.layout-item.width-100"
msgstr "Anchura 100%"
#: src/app/main/ui/workspace/libraries.cljs #: src/app/main/ui/workspace/libraries.cljs
#, unused #, unused
msgid "workspace.libraries.add" msgid "workspace.libraries.add"
@ -6340,30 +6308,6 @@ msgstr "Tiempo"
msgid "workspace.options.interaction-animation" msgid "workspace.options.interaction-animation"
msgstr "Animación" msgstr "Animación"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:616
msgid "workspace.options.interaction-animation-direction-down"
msgstr "Abajo"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:593
msgid "workspace.options.interaction-animation-direction-in"
msgstr "Dentro"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:612
msgid "workspace.options.interaction-animation-direction-left"
msgstr "Izquierda"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:596
msgid "workspace.options.interaction-animation-direction-out"
msgstr "Fuera"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:608
msgid "workspace.options.interaction-animation-direction-right"
msgstr "Derecha"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:620
msgid "workspace.options.interaction-animation-direction-up"
msgstr "Arriba"
#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383
msgid "workspace.options.interaction-animation-dissolve" msgid "workspace.options.interaction-animation-dissolve"
msgstr "Disolver" msgstr "Disolver"
@ -6809,14 +6753,6 @@ msgstr "Más tokens de color"
msgid "workspace.options.opacity" msgid "workspace.options.opacity"
msgstr "Opacidad" msgstr "Opacidad"
#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:401
msgid "workspace.options.orientation.horizontal"
msgstr "Horizontal"
#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:397
msgid "workspace.options.orientation.vertical"
msgstr "Vertical"
#: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs #: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
#, unused #, unused
msgid "workspace.options.position" msgid "workspace.options.position"
@ -7655,11 +7591,7 @@ msgstr "Capas"
msgid "workspace.sidebar.layers.components" msgid "workspace.sidebar.layers.components"
msgstr "Componentes" msgstr "Componentes"
#: src/app/main/ui/workspace/sidebar/layers.cljs:297 #: src/app/main/ui/workspace/sidebar/layers.cljs:311, src/app/main/ui/workspace/sidebar/layers.cljs:339
msgid "workspace.sidebar.layers.filter"
msgstr "Filtrar"
#: src/app/main/ui/workspace/sidebar/layers.cljs:310, src/app/main/ui/workspace/sidebar/layers.cljs:338
msgid "workspace.sidebar.layers.frames" msgid "workspace.sidebar.layers.frames"
msgstr "Paneles" msgstr "Paneles"
@ -8216,7 +8148,6 @@ msgid "workspace.tokens.text-decoration-value-enter"
msgstr "none | underline | strike-through o {alias}" msgstr "none | underline | strike-through o {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:154 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:154
#, unused
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"
msgstr "Tema %s" msgstr "Tema %s"

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ pushd $SCRIPT_DIR;
if [[ "$URL" = "http://localhost:9090" ]]; then if [[ "$URL" = "http://localhost:9090" ]]; then
pushd ../../plugins pushd ../../plugins
rm -rf node_modules;
pnpm install pnpm install
pnpm run build:doc pnpm run build:doc
popd popd

873
plugins/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff