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]))
@ -50,16 +49,16 @@
• :prop → the property type (:fill, :stroke, :shadow, etc.) • :prop → the property type (:fill, :stroke, :shadow, etc.)
• :shape-id → the UUID of the shape using this color • :shape-id → the UUID of the shape using this color
• :index → index of the color in the shape's fill/stroke list • :index → index of the color in the shape's fill/stroke list
Example of groups: Example of groups:
{ {
{:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true} {:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true}
[{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}] [{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}]
{:color \"#1b54b6\", :opacity 1} {:color \"#1b54b6\", :opacity 1}
[{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}] [{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}]
} }
This structure allows fast lookups of all shapes using the same visual color, This structure allows fast lookups of all shapes using the same visual color,
regardless of whether it comes from local fills, strokes or shadow-colors." regardless of whether it comes from local fills, strokes or shadow-colors."
@ -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