mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 21:26:11 +02:00
✨ Add base font fallback (#6468)
* ✨ Add base font fallback * ♻️ Add asserts to change-builder * 🐛 Change fn name
This commit is contained in:
parent
965b22718f
commit
8f7c63d6e2
19 changed files with 394 additions and 58 deletions
|
@ -425,7 +425,12 @@
|
||||||
[:type [:= :set-token]]
|
[:type [:= :set-token]]
|
||||||
[:set-name :string]
|
[:set-name :string]
|
||||||
[:token-name :string]
|
[:token-name :string]
|
||||||
[:token [:maybe ctob/schema:token-attrs]]]]]])
|
[:token [:maybe ctob/schema:token-attrs]]]]
|
||||||
|
|
||||||
|
[:set-base-font-size
|
||||||
|
[:map {:title "ModBaseFontSize"}
|
||||||
|
[:type [:= :set-base-font-size]]
|
||||||
|
[:base-font-size :string]]]]])
|
||||||
|
|
||||||
(def schema:changes
|
(def schema:changes
|
||||||
[:sequential {:gen/max 5 :gen/min 1} schema:change])
|
[:sequential {:gen/max 5 :gen/min 1} schema:change])
|
||||||
|
@ -1068,6 +1073,13 @@
|
||||||
(ctob/ensure-tokens-lib)
|
(ctob/ensure-tokens-lib)
|
||||||
(ctob/move-set-group from-path to-path before-path before-group))))
|
(ctob/move-set-group from-path to-path before-path before-group))))
|
||||||
|
|
||||||
|
;; === Base font size
|
||||||
|
|
||||||
|
(defmethod process-change :set-base-font-size
|
||||||
|
[data {:keys [base-font-size]}]
|
||||||
|
(ctf/set-base-font-size data base-font-size))
|
||||||
|
|
||||||
|
|
||||||
;; === Operations
|
;; === Operations
|
||||||
|
|
||||||
(def ^:private decode-shape
|
(def ^:private decode-shape
|
||||||
|
|
|
@ -124,28 +124,41 @@
|
||||||
; TODO: remove this when not needed
|
; TODO: remove this when not needed
|
||||||
(defn- assert-page-id!
|
(defn- assert-page-id!
|
||||||
[changes]
|
[changes]
|
||||||
(dm/assert!
|
(assert
|
||||||
"Give a page-id or call (with-page) before using this function"
|
(contains? (meta changes) ::page-id)
|
||||||
(contains? (meta changes) ::page-id)))
|
"Give a page-id or call (with-page) before using this function"))
|
||||||
|
|
||||||
|
(defn- assert-page!
|
||||||
|
[changes]
|
||||||
|
(assert
|
||||||
|
(contains? (meta changes) ::page)
|
||||||
|
"Give a page or call (with-page) before using this function"))
|
||||||
|
|
||||||
(defn- assert-container-id!
|
(defn- assert-container-id!
|
||||||
[changes]
|
[changes]
|
||||||
(dm/assert!
|
(assert
|
||||||
"Give a page-id or call (with-container) before using this function"
|
|
||||||
(or (contains? (meta changes) ::page-id)
|
(or (contains? (meta changes) ::page-id)
|
||||||
(contains? (meta changes) ::component-id))))
|
(contains? (meta changes) ::component-id))
|
||||||
|
"Give a page-id or call (with-container) before using this function"))
|
||||||
|
|
||||||
(defn- assert-objects!
|
(defn- assert-objects!
|
||||||
[changes]
|
[changes]
|
||||||
(dm/assert!
|
(assert
|
||||||
"Call (with-objects) before using this function"
|
(contains? (meta changes) ::file-data)
|
||||||
(contains? (meta changes) ::file-data)))
|
"Call (with-objects) before using this function"))
|
||||||
|
|
||||||
(defn- assert-library!
|
(defn- assert-library!
|
||||||
[changes]
|
[changes]
|
||||||
(dm/assert!
|
(assert
|
||||||
"Call (with-library-data) before using this function"
|
(contains? (meta changes) ::library-data)
|
||||||
(contains? (meta changes) ::library-data)))
|
"Call (with-library-data) before using this function"))
|
||||||
|
|
||||||
|
(defn- assert-file-data!
|
||||||
|
[changes]
|
||||||
|
(assert
|
||||||
|
(contains? (meta changes) ::file-data)
|
||||||
|
"Call (with-file-data) before using this function"))
|
||||||
|
|
||||||
|
|
||||||
(defn- lookup-objects
|
(defn- lookup-objects
|
||||||
[changes]
|
[changes]
|
||||||
|
@ -154,9 +167,9 @@
|
||||||
|
|
||||||
(defn apply-changes-local
|
(defn apply-changes-local
|
||||||
[changes & {:keys [apply-to-library?]}]
|
[changes & {:keys [apply-to-library?]}]
|
||||||
(dm/assert!
|
(assert
|
||||||
"expected valid changes"
|
(check-changes! changes)
|
||||||
(check-changes! changes))
|
"expected valid changes")
|
||||||
|
|
||||||
(if-let [file-data (::file-data (meta changes))]
|
(if-let [file-data (::file-data (meta changes))]
|
||||||
(let [library-data (::library-data (meta changes))
|
(let [library-data (::library-data (meta changes))
|
||||||
|
@ -195,6 +208,7 @@
|
||||||
|
|
||||||
(defn mod-page
|
(defn mod-page
|
||||||
([changes options]
|
([changes options]
|
||||||
|
(assert-page! changes)
|
||||||
(let [page (::page (meta changes))]
|
(let [page (::page (meta changes))]
|
||||||
(mod-page changes page options)))
|
(mod-page changes page options)))
|
||||||
|
|
||||||
|
@ -225,6 +239,7 @@
|
||||||
([changes type id namespace key value]
|
([changes type id namespace key value]
|
||||||
(set-plugin-data changes type id nil namespace key value))
|
(set-plugin-data changes type id nil namespace key value))
|
||||||
([changes type id page-id namespace key value]
|
([changes type id page-id namespace key value]
|
||||||
|
(assert-file-data! changes)
|
||||||
(let [data (::file-data (meta changes))
|
(let [data (::file-data (meta changes))
|
||||||
old-val
|
old-val
|
||||||
(case type
|
(case type
|
||||||
|
@ -291,6 +306,8 @@
|
||||||
|
|
||||||
(defn set-guide
|
(defn set-guide
|
||||||
[changes id guide]
|
[changes id guide]
|
||||||
|
(assert-page-id! changes)
|
||||||
|
(assert-page! changes)
|
||||||
(let [page-id (::page-id (meta changes))
|
(let [page-id (::page-id (meta changes))
|
||||||
page (::page (meta changes))
|
page (::page (meta changes))
|
||||||
old-val (dm/get-in page [:guides id])]
|
old-val (dm/get-in page [:guides id])]
|
||||||
|
@ -304,8 +321,11 @@
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:id id
|
:id id
|
||||||
:params old-val}))))
|
:params old-val}))))
|
||||||
|
|
||||||
(defn set-flow
|
(defn set-flow
|
||||||
[changes id flow]
|
[changes id flow]
|
||||||
|
(assert-page-id! changes)
|
||||||
|
(assert-page! changes)
|
||||||
(let [page-id (::page-id (meta changes))
|
(let [page-id (::page-id (meta changes))
|
||||||
page (::page (meta changes))
|
page (::page (meta changes))
|
||||||
old-val (dm/get-in page [:flows id])
|
old-val (dm/get-in page [:flows id])
|
||||||
|
@ -324,6 +344,8 @@
|
||||||
|
|
||||||
(defn set-comment-thread-position
|
(defn set-comment-thread-position
|
||||||
[changes {:keys [id frame-id position] :as thread}]
|
[changes {:keys [id frame-id position] :as thread}]
|
||||||
|
(assert-page-id! changes)
|
||||||
|
(assert-page! changes)
|
||||||
(let [page-id (::page-id (meta changes))
|
(let [page-id (::page-id (meta changes))
|
||||||
page (::page (meta changes))
|
page (::page (meta changes))
|
||||||
|
|
||||||
|
@ -345,6 +367,8 @@
|
||||||
|
|
||||||
(defn set-default-grid
|
(defn set-default-grid
|
||||||
[changes type params]
|
[changes type params]
|
||||||
|
(assert-page-id! changes)
|
||||||
|
(assert-page! changes)
|
||||||
(let [page-id (::page-id (meta changes))
|
(let [page-id (::page-id (meta changes))
|
||||||
page (::page (meta changes))
|
page (::page (meta changes))
|
||||||
old-val (dm/get-in page [:grids type])
|
old-val (dm/get-in page [:grids type])
|
||||||
|
@ -498,6 +522,7 @@
|
||||||
:or {ignore-geometry? false ignore-touched false with-objects? false}}]
|
:or {ignore-geometry? false ignore-touched false with-objects? false}}]
|
||||||
(assert-container-id! changes)
|
(assert-container-id! changes)
|
||||||
(assert-objects! changes)
|
(assert-objects! changes)
|
||||||
|
(assert-page-id! changes)
|
||||||
(let [page-id (::page-id (meta changes))
|
(let [page-id (::page-id (meta changes))
|
||||||
component-id (::component-id (meta changes))
|
component-id (::component-id (meta changes))
|
||||||
objects (lookup-objects changes)
|
objects (lookup-objects changes)
|
||||||
|
@ -846,6 +871,7 @@
|
||||||
|
|
||||||
(defn set-tokens-lib
|
(defn set-tokens-lib
|
||||||
[changes tokens-lib]
|
[changes tokens-lib]
|
||||||
|
(assert-library! changes)
|
||||||
(let [library-data (::library-data (meta changes))
|
(let [library-data (::library-data (meta changes))
|
||||||
prev-tokens-lib (get library-data :tokens-lib)]
|
prev-tokens-lib (get library-data :tokens-lib)]
|
||||||
(-> changes
|
(-> changes
|
||||||
|
@ -1135,3 +1161,16 @@
|
||||||
(defn get-page-id
|
(defn get-page-id
|
||||||
[changes]
|
[changes]
|
||||||
(::page-id (meta changes)))
|
(::page-id (meta changes)))
|
||||||
|
|
||||||
|
(defn set-base-font-size
|
||||||
|
[changes new-base-font-size]
|
||||||
|
(assert-file-data! changes)
|
||||||
|
(let [file-data (::file-data (meta changes))
|
||||||
|
previous-font-size (ctf/get-base-font-size file-data)]
|
||||||
|
(-> changes
|
||||||
|
(update :redo-changes conj {:type :set-base-font-size
|
||||||
|
:base-font-size new-base-font-size})
|
||||||
|
|
||||||
|
(update :undo-changes conj {:type :set-base-font-size
|
||||||
|
:base-font-size previous-font-size})
|
||||||
|
(apply-changes-local))))
|
|
@ -2190,7 +2190,9 @@
|
||||||
:starting-frame frame-id}]
|
:starting-frame frame-id}]
|
||||||
|
|
||||||
(vswap! unames conj name)
|
(vswap! unames conj name)
|
||||||
(pcb/set-flow changes flow-id new-flow)))
|
(-> changes
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/set-flow flow-id new-flow))))
|
||||||
|
|
||||||
changes
|
changes
|
||||||
(->> shapes
|
(->> shapes
|
||||||
|
|
|
@ -151,7 +151,9 @@
|
||||||
changes
|
changes
|
||||||
(reduce (fn [changes {:keys [id] :as flow}]
|
(reduce (fn [changes {:keys [id] :as flow}]
|
||||||
(if (contains? ids-to-delete (:starting-frame flow))
|
(if (contains? ids-to-delete (:starting-frame flow))
|
||||||
(pcb/set-flow changes id nil)
|
(-> changes
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/set-flow id nil))
|
||||||
changes))
|
changes))
|
||||||
changes
|
changes
|
||||||
(:flows page))
|
(:flows page))
|
||||||
|
@ -213,7 +215,9 @@
|
||||||
(map :id))
|
(map :id))
|
||||||
|
|
||||||
changes (reduce (fn [changes guide-id]
|
changes (reduce (fn [changes guide-id]
|
||||||
(pcb/set-flow changes guide-id nil))
|
(-> changes
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/set-flow guide-id nil)))
|
||||||
changes
|
changes
|
||||||
guides-to-delete)
|
guides-to-delete)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,13 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; CONSTANTS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defonce BASE-FONT-SIZE "16px")
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; SCHEMA
|
;; SCHEMA
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -65,7 +72,8 @@
|
||||||
|
|
||||||
(def schema:options
|
(def schema:options
|
||||||
[:map {:title "FileOptions"}
|
[:map {:title "FileOptions"}
|
||||||
[:components-v2 {:optional true} ::sm/boolean]])
|
[:components-v2 {:optional true} ::sm/boolean]
|
||||||
|
[:base-font-size {:optional true} :string]])
|
||||||
|
|
||||||
(def schema:data
|
(def schema:data
|
||||||
[:map {:title "FileData"}
|
[:map {:title "FileData"}
|
||||||
|
@ -133,7 +141,8 @@
|
||||||
(ctpl/add-page page)
|
(ctpl/add-page page)
|
||||||
|
|
||||||
:always
|
:always
|
||||||
(update :options assoc :components-v2 true)))))
|
(update :options merge {:components-v2 true
|
||||||
|
:base-font-size BASE-FONT-SIZE})))))
|
||||||
|
|
||||||
(defn make-file
|
(defn make-file
|
||||||
[{:keys [id project-id name revn is-shared features migrations
|
[{:keys [id project-id name revn is-shared features migrations
|
||||||
|
@ -1028,3 +1037,14 @@
|
||||||
|
|
||||||
(-> file
|
(-> file
|
||||||
(update-in [:data :pages-index] detach-pages))))
|
(update-in [:data :pages-index] detach-pages))))
|
||||||
|
|
||||||
|
;; Base font size
|
||||||
|
|
||||||
|
(defn get-base-font-size
|
||||||
|
"Retrieve the base font size value or token reference."
|
||||||
|
[file-data]
|
||||||
|
(get-in file-data [:options :base-font-size] BASE-FONT-SIZE))
|
||||||
|
|
||||||
|
(defn set-base-font-size
|
||||||
|
[file-data base-font-size]
|
||||||
|
(assoc-in file-data [:options :base-font-size] base-font-size))
|
3
frontend/resources/images/icons/settings.svg
Normal file
3
frontend/resources/images/icons/settings.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" fill="none" viewBox="0 0 16 16">
|
||||||
|
<path d="M12.933 10a1.1 1.1 0 0 0 .22 1.213l.04.04c1.258 1.257-.628 3.144-1.886 1.887l-.04-.04a1.1 1.1 0 0 0-1.214-.22 1.1 1.1 0 0 0-.666 1.007V14c0 1.778-2.667 1.778-2.667 0v-.06A1.1 1.1 0 0 0 6 12.933a1.1 1.1 0 0 0-1.213.22l-.04.04c-1.257 1.258-3.144-.628-1.887-1.886l.04-.04a1.1 1.1 0 0 0 .22-1.214 1.1 1.1 0 0 0-1.007-.666H2C.222 9.387.222 6.72 2 6.72h.06A1.1 1.1 0 0 0 3.067 6a1.1 1.1 0 0 0-.22-1.213l-.04-.04C1.549 3.49 3.435 1.603 4.693 2.86l.04.04a1.1 1.1 0 0 0 1.214.22H6a1.1 1.1 0 0 0 .667-1.007V2c0-1.777 2.666-1.777 2.666 0v.06A1.1 1.1 0 0 0 10 3.067a1.1 1.1 0 0 0 1.213-.22l.04-.04c1.257-1.278 3.165.628 1.887 1.886l-.04.04a1.1 1.1 0 0 0-.22 1.214V6a1.1 1.1 0 0 0 1.007.667H14c1.777 0 1.777 2.666 0 2.666h-.06a1.1 1.1 0 0 0-1.007.667ZM8 10c2.667 0 2.667-4 0-4s-2.667 4 0 4z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 943 B |
|
@ -616,6 +616,7 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page (dsh/lookup-page state id)
|
(let [page (dsh/lookup-page state id)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
|
(pcb/with-page page)
|
||||||
(pcb/mod-page page {:name name}))]
|
(pcb/mod-page page {:name name}))]
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
|
|
25
frontend/src/app/main/data/workspace/tokens/typography.cljs
Normal file
25
frontend/src/app/main/data/workspace/tokens/typography.cljs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.data.workspace.tokens.typography
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.changes-builder :as pcb]
|
||||||
|
[app.main.data.changes :as dch]
|
||||||
|
[beicon.v2.core :as rx]
|
||||||
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
(defn set-base-font-size [base-font-size]
|
||||||
|
(ptk/reify ::set-base-font-size
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [it state _]
|
||||||
|
(let [file-id (dm/get-in state [:workspace :current-file-id])
|
||||||
|
file-data (dm/get-in state [:files file-id :data])
|
||||||
|
changes (-> (pcb/empty-changes it)
|
||||||
|
(pcb/with-file-data file-data)
|
||||||
|
(pcb/set-base-font-size base-font-size))]
|
||||||
|
(rx/of
|
||||||
|
(dch/commit-changes changes))))))
|
|
@ -16,6 +16,7 @@
|
||||||
[:map
|
[:map
|
||||||
[:class {:optional true} :string]
|
[:class {:optional true} :string]
|
||||||
[:icon-class {:optional true} :string]
|
[:icon-class {:optional true} :string]
|
||||||
|
[:tooltip-id {:optional true} :string]
|
||||||
[:icon
|
[:icon
|
||||||
[:and :string [:fn #(contains? icon-list %)]]]
|
[:and :string [:fn #(contains? icon-list %)]]]
|
||||||
[:aria-label :string]
|
[:aria-label :string]
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
(mf/defc icon-button*
|
(mf/defc icon-button*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/schema schema:icon-button}
|
::mf/schema schema:icon-button}
|
||||||
[{:keys [class icon icon-class variant aria-label children] :rest props}]
|
[{:keys [class icon icon-class variant aria-label children tooltip-id] :rest props}]
|
||||||
(let [variant (or variant "primary")
|
(let [variant (or variant "primary")
|
||||||
class (dm/str class " " (stl/css-case :icon-button true
|
class (dm/str class " " (stl/css-case :icon-button true
|
||||||
:icon-button-primary (= variant "primary")
|
:icon-button-primary (= variant "primary")
|
||||||
|
@ -33,5 +34,10 @@
|
||||||
:icon-button-ghost (= variant "ghost")
|
:icon-button-ghost (= variant "ghost")
|
||||||
:icon-button-action (= variant "action")
|
:icon-button-action (= variant "action")
|
||||||
:icon-button-destructive (= variant "destructive")))
|
:icon-button-destructive (= variant "destructive")))
|
||||||
props (mf/spread-props props {:class class :title aria-label})]
|
props (if (some? tooltip-id)
|
||||||
[:> "button" props [:> icon* {:icon-id icon :aria-label aria-label :class icon-class}] children]))
|
(mf/spread-props props {:class class
|
||||||
|
:aria-describedby tooltip-id})
|
||||||
|
(mf/spread-props props {:class class
|
||||||
|
:aria-label aria-label
|
||||||
|
:title aria-label}))]
|
||||||
|
[:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]))
|
|
@ -231,6 +231,7 @@
|
||||||
(def ^:icon-id row-reverse "row-reverse")
|
(def ^:icon-id row-reverse "row-reverse")
|
||||||
(def ^:icon-id search "search")
|
(def ^:icon-id search "search")
|
||||||
(def ^:icon-id separate-nodes "separate-nodes")
|
(def ^:icon-id separate-nodes "separate-nodes")
|
||||||
|
(def ^:icon-id settings "settings")
|
||||||
(def ^:icon-id shown "shown")
|
(def ^:icon-id shown "shown")
|
||||||
(def ^:icon-id size-horizontal "size-horizontal")
|
(def ^:icon-id size-horizontal "size-horizontal")
|
||||||
(def ^:icon-id size-vertical "size-vertical")
|
(def ^:icon-id size-vertical "size-vertical")
|
||||||
|
|
|
@ -208,6 +208,7 @@
|
||||||
(def ^:icon row-reverse (icon-xref :row-reverse))
|
(def ^:icon row-reverse (icon-xref :row-reverse))
|
||||||
(def ^:icon search (icon-xref :search))
|
(def ^:icon search (icon-xref :search))
|
||||||
(def ^:icon separate-nodes (icon-xref :separate-nodes))
|
(def ^:icon separate-nodes (icon-xref :separate-nodes))
|
||||||
|
(def ^:icon settings (icon-xref :settings))
|
||||||
(def ^:icon share (icon-xref :share))
|
(def ^:icon share (icon-xref :share))
|
||||||
(def ^:icon shown (icon-xref :shown))
|
(def ^:icon shown (icon-xref :shown))
|
||||||
(def ^:icon size-horizontal (icon-xref :size-horizontal))
|
(def ^:icon size-horizontal (icon-xref :size-horizontal))
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
||||||
[app.main.ui.workspace.tokens.modals]
|
[app.main.ui.workspace.tokens.modals]
|
||||||
[app.main.ui.workspace.tokens.modals.import]
|
[app.main.ui.workspace.tokens.modals.import]
|
||||||
|
[app.main.ui.workspace.tokens.modals.settings]
|
||||||
[app.main.ui.workspace.tokens.modals.themes]
|
[app.main.ui.workspace.tokens.modals.themes]
|
||||||
[app.main.ui.workspace.viewport :refer [viewport*]]
|
[app.main.ui.workspace.viewport :refer [viewport*]]
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
|
|
|
@ -277,22 +277,21 @@
|
||||||
[:> icon-button* {:variant "ghost"
|
[:> icon-button* {:variant "ghost"
|
||||||
:aria-label (tr "labels.close")
|
:aria-label (tr "labels.close")
|
||||||
:on-click on-close-history
|
:on-click on-close-history
|
||||||
:icon "close"}])]
|
:icon "close"}])
|
||||||
|
tabs (mf/object
|
||||||
|
[{:label (tr "workspace.versions.tab.history")
|
||||||
|
:id "history"
|
||||||
|
:content versions-tab}
|
||||||
|
{:label (tr "workspace.versions.tab.actions")
|
||||||
|
:id "actions"
|
||||||
|
:content history-tab}])]
|
||||||
|
|
||||||
|
[:> tab-switcher*
|
||||||
(let [tabs (mf/object
|
{:tabs tabs
|
||||||
[{:label (tr "workspace.versions.tab.history")
|
:default-selected "history"
|
||||||
:id "history"
|
:class (stl/css :left-sidebar-tabs)
|
||||||
:content versions-tab}
|
:action-button-position "end"
|
||||||
{:label (tr "workspace.versions.tab.actions")
|
:action-button button}])
|
||||||
:id "actions"
|
|
||||||
:content history-tab}])]
|
|
||||||
[:> tab-switcher*
|
|
||||||
{:tabs tabs
|
|
||||||
:default-selected "history"
|
|
||||||
:class (stl/css :left-sidebar-tabs)
|
|
||||||
:action-button-position "end"
|
|
||||||
:action-button button}]))
|
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[:> options-toolbox* props])]]]))
|
[:> options-toolbox* props])]]]))
|
||||||
|
|
117
frontend/src/app/main/ui/workspace/tokens/modals/settings.cljs
Normal file
117
frontend/src/app/main/ui/workspace/tokens/modals/settings.cljs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.ui.workspace.tokens.modals.settings
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
|
(:require
|
||||||
|
[app.common.types.file :as ctf]
|
||||||
|
[app.main.data.modal :as modal]
|
||||||
|
[app.main.data.workspace.tokens.typography :as wtt]
|
||||||
|
[app.main.refs :as refs]
|
||||||
|
[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.controls.input :refer [input*]]
|
||||||
|
[app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]]
|
||||||
|
[app.main.ui.ds.foundations.typography :as t]
|
||||||
|
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
|
||||||
|
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[app.util.i18n :refer [tr]]
|
||||||
|
[app.util.keyboard :as k]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
|
||||||
|
(mf/defc token-settings-modal*
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[]
|
||||||
|
(let [file-data (deref refs/workspace-data)
|
||||||
|
base-font-size* (mf/use-state #(ctf/get-base-font-size file-data))
|
||||||
|
base-font-size (deref base-font-size*)
|
||||||
|
valid?* (mf/use-state true)
|
||||||
|
is-valid (deref valid?*)
|
||||||
|
|
||||||
|
is-valid?
|
||||||
|
(fn [value]
|
||||||
|
(boolean (re-matches #"^\d+(\.\d+)?(px)?$" value)))
|
||||||
|
|
||||||
|
hint-message (if is-valid
|
||||||
|
(str "1rem = " base-font-size)
|
||||||
|
(tr "workspace.token.base-font-size.error"))
|
||||||
|
|
||||||
|
on-change-base-font-size
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps base-font-size*)
|
||||||
|
(fn [e]
|
||||||
|
(let [value (dom/get-target-val e)]
|
||||||
|
(reset! valid?* (is-valid? value))
|
||||||
|
(when (is-valid? value)
|
||||||
|
(let [unit-value (if (str/ends-with? value "px")
|
||||||
|
value
|
||||||
|
(str value "px"))]
|
||||||
|
(reset! base-font-size* unit-value))))))
|
||||||
|
|
||||||
|
on-set-font
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps base-font-size)
|
||||||
|
(fn []
|
||||||
|
(st/emit! (wtt/set-base-font-size base-font-size)
|
||||||
|
(modal/hide))))
|
||||||
|
|
||||||
|
handle-key-down
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps base-font-size is-valid)
|
||||||
|
(fn [e]
|
||||||
|
(when (and (k/enter? e) is-valid)
|
||||||
|
(on-set-font))))]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :setting-modal-overlay)
|
||||||
|
:data-testid "token-font-settings-modal"}
|
||||||
|
[:div {:class (stl/css :setting-modal)}
|
||||||
|
[:> icon-button* {:on-click modal/hide!
|
||||||
|
:class (stl/css :close-btn)
|
||||||
|
:icon i/close
|
||||||
|
:variant "action"
|
||||||
|
:aria-label (tr "labels.close")}]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :settings-modal-layout)}
|
||||||
|
[:> heading* {:level 2
|
||||||
|
:typography t/headline-medium
|
||||||
|
:class (stl/css :settings-modal-title)}
|
||||||
|
(tr "workspace.token.settings")]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :settings-modal-content)}
|
||||||
|
[:div {:class (stl/css :settings-modal-subtitle-wrapper)}
|
||||||
|
[:> text* {:as "span" :typography t/body-large :class (stl/css :settings-subtitle)}
|
||||||
|
(tr "workspace.token.base-font-size")]
|
||||||
|
[:> icon* {:icon-id "info"}]]
|
||||||
|
[:> text* {:as "span" :typography t/body-medium :class (stl/css :settings-modal-description)}
|
||||||
|
(tr "workspace.token.setting-description")]
|
||||||
|
|
||||||
|
[:> input* {:type "text"
|
||||||
|
:placeholder "16"
|
||||||
|
:default-value base-font-size
|
||||||
|
:hint-message hint-message
|
||||||
|
:hint-type (if is-valid "hint" "error")
|
||||||
|
:on-key-down handle-key-down
|
||||||
|
:on-change on-change-base-font-size}]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :settings-modal-actions)}
|
||||||
|
[:> button* {:on-click modal/hide!
|
||||||
|
:variant "secondary"}
|
||||||
|
(tr "labels.cancel")]
|
||||||
|
[:> button* {:on-click on-set-font
|
||||||
|
:disabled (not is-valid)
|
||||||
|
:variant "primary"}
|
||||||
|
(tr "labels.save")]]]]]]))
|
||||||
|
|
||||||
|
|
||||||
|
(mf/defc base-font-size-modal
|
||||||
|
{::mf/register modal/components
|
||||||
|
::mf/register-as :tokens/base-font-size}
|
||||||
|
[]
|
||||||
|
[:> token-settings-modal*])
|
|
@ -0,0 +1,55 @@
|
||||||
|
// 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 "../../../ds/spacing.scss" as *;
|
||||||
|
|
||||||
|
@import "refactor/common-refactor.scss";
|
||||||
|
|
||||||
|
.setting-modal-overlay {
|
||||||
|
@extend .modal-overlay-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-modal {
|
||||||
|
@extend .modal-container-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
@extend .modal-close-btn-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
gap: var(--sp-xxl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-title {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr auto;
|
||||||
|
gap: var(--sp-m);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-subtitle-wrapper {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--sp-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-description,
|
||||||
|
.settings-modal-resume {
|
||||||
|
color: var(--color-foreground-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-modal-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: var(--sp-s);
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
[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.foundations.typography.text :refer [text*]]
|
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||||
|
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
|
||||||
[app.main.ui.hooks :as h]
|
[app.main.ui.hooks :as h]
|
||||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||||
|
@ -384,10 +385,17 @@
|
||||||
(json/encode :key-fn identity))]
|
(json/encode :key-fn identity))]
|
||||||
(->> (wapi/create-blob (or tokens-json "{}") "application/json")
|
(->> (wapi/create-blob (or tokens-json "{}") "application/json")
|
||||||
(dom/trigger-download "tokens.json")))))
|
(dom/trigger-download "tokens.json")))))
|
||||||
|
|
||||||
on-modal-show
|
on-modal-show
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn []
|
(fn []
|
||||||
(modal/show! :tokens/import {})))]
|
(modal/show! :tokens/import {})))
|
||||||
|
|
||||||
|
open-settings-modal
|
||||||
|
(mf/use-fn
|
||||||
|
(fn [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(modal/show! :tokens/base-font-size {})))]
|
||||||
|
|
||||||
[:div {:class (stl/css :import-export-button-wrapper)}
|
[:div {:class (stl/css :import-export-button-wrapper)}
|
||||||
[:> button* {:on-click open-menu
|
[:> button* {:on-click open-menu
|
||||||
|
@ -404,7 +412,15 @@
|
||||||
[:div (tr "labels.import")]]])
|
[:div (tr "labels.import")]]])
|
||||||
[:> dropdown-menu-item* {:class (stl/css :import-export-menu-item)
|
[:> dropdown-menu-item* {:class (stl/css :import-export-menu-item)
|
||||||
:on-click on-export}
|
:on-click on-export}
|
||||||
(tr "labels.export")]]]))
|
(tr "labels.export")]]
|
||||||
|
|
||||||
|
[:> tooltip* {:tooltip-content "Tokens settings"
|
||||||
|
:id "button-setting"}
|
||||||
|
[:> icon-button* {:variant "secondary"
|
||||||
|
:icon "settings"
|
||||||
|
:tooltip-id "button-setting"
|
||||||
|
:aria-label "Settings"
|
||||||
|
:on-click open-settings-modal}]]]))
|
||||||
|
|
||||||
(mf/defc tokens-sidebar-tab*
|
(mf/defc tokens-sidebar-tab*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// Copyright (c) KALEIDOS INC
|
// Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
@use "../../ds/typography.scss" as *;
|
@use "../../ds/typography.scss" as *;
|
||||||
|
@use "../../ds/spacing.scss" as *;
|
||||||
@import "refactor/common-refactor.scss";
|
@import "refactor/common-refactor.scss";
|
||||||
|
|
||||||
.sidebar-wrapper {
|
.sidebar-wrapper {
|
||||||
|
@ -28,20 +29,20 @@
|
||||||
|
|
||||||
.tokens-section-wrapper {
|
.tokens-section-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-left: $s-12;
|
padding-left: var(--sp-m);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-gutter: stable;
|
scrollbar-gutter: stable;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sets-sidebar {
|
.sets-sidebar {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-block-end: $s-16;
|
padding-block-end: var(--sp-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
.themes-header,
|
.themes-header,
|
||||||
.sets-header-container {
|
.sets-header-container {
|
||||||
@include use-typography("headline-small");
|
@include use-typography("headline-small");
|
||||||
padding: $s-8;
|
padding: var(--sp-s);
|
||||||
color: var(--title-foreground-color);
|
color: var(--title-foreground-color);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
@ -50,8 +51,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: $s-4;
|
gap: var(--sp-xs);
|
||||||
margin-block-start: $s-8;
|
margin-block-start: var(--sp-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sets-header {
|
.sets-header {
|
||||||
|
@ -64,7 +65,7 @@
|
||||||
color: var(--color-foreground-secondary);
|
color: var(--color-foreground-secondary);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: $s-4;
|
gap: var(--sp-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sets-header-status-text {
|
.sets-header-status-text {
|
||||||
|
@ -72,11 +73,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.themes-wrapper {
|
.themes-wrapper {
|
||||||
padding: $s-12 0 0 $s-12;
|
padding: var(--sp-m) 0 0 var(--sp-m);
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-theme-wrapper {
|
.empty-theme-wrapper {
|
||||||
padding: $s-12;
|
padding: var(--sp-m);
|
||||||
color: var(--color-foreground-secondary);
|
color: var(--color-foreground-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +85,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-left: $s-12;
|
margin-left: var(--sp-m);
|
||||||
padding-top: $s-12;
|
padding-top: var(--sp-m);
|
||||||
color: var(--layer-row-foreground-color);
|
color: var(--layer-row-foreground-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,20 +96,20 @@
|
||||||
|
|
||||||
.token-pills-wrapper {
|
.token-pills-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: $s-4;
|
gap: var(--sp-xs);
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-text-icon {
|
.section-text-icon {
|
||||||
font-size: $fs-12;
|
font-size: $fs-12;
|
||||||
width: $s-16;
|
width: var(--sp-l);
|
||||||
height: $s-16;
|
height: var(--sp-l);
|
||||||
display: flex;
|
display: flex;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-icon {
|
.section-icon {
|
||||||
margin-right: $s-4;
|
margin-right: var(--sp-xs);
|
||||||
// Align better with the label
|
// Align better with the label
|
||||||
translate: 0px -1px;
|
translate: 0px -1px;
|
||||||
}
|
}
|
||||||
|
@ -116,10 +117,11 @@
|
||||||
.import-export-button-wrapper {
|
.import-export-button-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: var(--sp-s);
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding: $s-8;
|
padding: var(--sp-s);
|
||||||
background-color: var(--color-background-primary);
|
background-color: var(--color-background-primary);
|
||||||
box-shadow: var(--el-shadow-dark);
|
box-shadow: var(--el-shadow-dark);
|
||||||
}
|
}
|
||||||
|
@ -129,9 +131,9 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding: $s-6 $s-8;
|
padding: $s-6 var(--sp-s);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
gap: $s-8;
|
gap: var(--sp-s);
|
||||||
background-color: var(--color-background-primary);
|
background-color: var(--color-background-primary);
|
||||||
|
|
||||||
box-shadow: var(--el-shadow-dark);
|
box-shadow: var(--el-shadow-dark);
|
||||||
|
|
|
@ -7124,6 +7124,22 @@ msgstr "The value is not valid"
|
||||||
msgid "workspace.token.warning-name-change"
|
msgid "workspace.token.warning-name-change"
|
||||||
msgstr "Renaming this token will break any reference to its old name."
|
msgstr "Renaming this token will break any reference to its old name."
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.settings"
|
||||||
|
msgstr "Tokens settings"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.base-font-size"
|
||||||
|
msgstr "Base font size"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.setting-description"
|
||||||
|
msgstr "Here you can configure the base font size, which defines the value of 1rem:"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.base-font-size.error"
|
||||||
|
msgstr "Base font size must be a value in pixels or unitless."
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/sidebar.cljs:135, src/app/main/ui/workspace/sidebar.cljs:144
|
#: src/app/main/ui/workspace/sidebar.cljs:135, src/app/main/ui/workspace/sidebar.cljs:144
|
||||||
msgid "workspace.toolbar.assets"
|
msgid "workspace.toolbar.assets"
|
||||||
msgstr "Assets"
|
msgstr "Assets"
|
||||||
|
|
|
@ -7103,6 +7103,22 @@ msgstr "El valor no es válido"
|
||||||
msgid "workspace.token.warning-name-change"
|
msgid "workspace.token.warning-name-change"
|
||||||
msgstr "Al renombrar este token se romperán las referencias al nombre anterior"
|
msgstr "Al renombrar este token se romperán las referencias al nombre anterior"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.settings"
|
||||||
|
msgstr "Configuración de tokens"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.base-font-size"
|
||||||
|
msgstr "Tamaño de fuente base"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.setting-description"
|
||||||
|
msgstr "Aquí puedes configurar el tamaño de fuente base, que define el tamaño de 1rem:"
|
||||||
|
|
||||||
|
#: src/app/main/ui/workspace/tokens/modals/settings.cljs
|
||||||
|
msgid "workspace.token.base-font-size.error"
|
||||||
|
msgstr "El tamaño de fuente base debe estar en px o sin unidad."
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/sidebar.cljs:135, src/app/main/ui/workspace/sidebar.cljs:144
|
#: src/app/main/ui/workspace/sidebar.cljs:135, src/app/main/ui/workspace/sidebar.cljs:144
|
||||||
msgid "workspace.toolbar.assets"
|
msgid "workspace.toolbar.assets"
|
||||||
msgstr "Recursos"
|
msgstr "Recursos"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue