mirror of
https://github.com/penpot/penpot.git
synced 2025-05-21 19:06:11 +02:00
🎉 Add new font selector to workspace.
This commit is contained in:
parent
8831f3241c
commit
2ea200be78
19 changed files with 800 additions and 199 deletions
16
CHANGES.md
16
CHANGES.md
|
@ -4,6 +4,7 @@
|
||||||
## :rocket: Next
|
## :rocket: Next
|
||||||
|
|
||||||
### :sparkles: New features
|
### :sparkles: New features
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
### :boom: Breaking changes
|
### :boom: Breaking changes
|
||||||
|
@ -14,21 +15,24 @@
|
||||||
|
|
||||||
### :sparkles: New features
|
### :sparkles: New features
|
||||||
|
|
||||||
- Add many performance related improvements to indexes handling on workspace.
|
- Add improved workspace font selector [Taiga US #292](https://tree.taiga.io/project/penpot/us/292).
|
||||||
- Add option to interactively scale text [Taiga #1527](https://tree.taiga.io/project/penpot/us/1527)
|
- Add option to interactively scale text [Taiga #1527](https://tree.taiga.io/project/penpot/us/1527)
|
||||||
- Add the ability to upload/use custom fonts (and automatically generate all needed webfonts).
|
- Add performance improvements on dashboard data loading.
|
||||||
- Refactor dashboard state management (improves considerably the performance when you have a dashboard with a big collection of projects and files).
|
- Add performance improvements to indexes handling on workspace.
|
||||||
- Translate automatic names of new files and projects.
|
- Add the ability to upload/use custom fonts (and automatically generate all needed webfonts) [Taiga US #292](https://tree.taiga.io/project/penpot/us/292).
|
||||||
- Transform shapes to path on double click
|
- Transform shapes to path on double click
|
||||||
|
- Translate automatic names of new files and projects.
|
||||||
- Use shift instead of ctrl/cmd to keep aspect ratio [Taiga 1697](https://tree.taiga.io/project/penpot/issue/1697).
|
- Use shift instead of ctrl/cmd to keep aspect ratio [Taiga 1697](https://tree.taiga.io/project/penpot/issue/1697).
|
||||||
|
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
- Remove interactions when the destination artboard is deleted [Taiga #1656](https://tree.taiga.io/project/penpot/issue/1656)
|
- Remove interactions when the destination artboard is deleted [Taiga #1656](https://tree.taiga.io/project/penpot/issue/1656)
|
||||||
|
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
- Update exporter dependencies (puppetteer), that fixes some unexpected exceptions.
|
- Update exporter dependencies (puppeteer), that fixes some unexpected exceptions.
|
||||||
- Update string manipulation library.
|
- Update string manipulation library.
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,8 +42,6 @@
|
||||||
configuration added scopes to the default set. Now it replaces it, so use with care, because
|
configuration added scopes to the default set. Now it replaces it, so use with care, because
|
||||||
penpot requires at least `name` and `email` props found on the user info object.
|
penpot requires at least `name` and `email` props found on the user info object.
|
||||||
|
|
||||||
### :heart: Community contributions by (Thank you!)
|
|
||||||
|
|
||||||
|
|
||||||
## 1.5.4-alpha
|
## 1.5.4-alpha
|
||||||
|
|
||||||
|
|
|
@ -253,14 +253,8 @@
|
||||||
(map (fn [x] (f x) x) coll)))
|
(map (fn [x] (f x) x) coll)))
|
||||||
|
|
||||||
(defn merge
|
(defn merge
|
||||||
"A faster merge."
|
|
||||||
[& maps]
|
[& maps]
|
||||||
(loop [res (transient (or (first maps) {}))
|
(reduce conj (or (first maps) {}) (rest maps)))
|
||||||
maps (next maps)]
|
|
||||||
(if (nil? maps)
|
|
||||||
(persistent! res)
|
|
||||||
(recur (reduce-kv assoc! res (first maps))
|
|
||||||
(next maps)))))
|
|
||||||
|
|
||||||
(defn distinct-xf
|
(defn distinct-xf
|
||||||
[f]
|
[f]
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
(ns cljs.user)
|
|
|
@ -46,6 +46,7 @@
|
||||||
"randomcolor": "^0.6.2",
|
"randomcolor": "^0.6.2",
|
||||||
"react": "~17.0.1",
|
"react": "~17.0.1",
|
||||||
"react-dom": "~17.0.1",
|
"react-dom": "~17.0.1",
|
||||||
|
"react-virtualized": "^9.22.3",
|
||||||
"rxjs": "~7.0.1",
|
"rxjs": "~7.0.1",
|
||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"tdigest": "^0.1.1",
|
"tdigest": "^0.1.1",
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// 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/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
//
|
//
|
||||||
// Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
// Copyright (c) UXBOX Labs SL
|
||||||
// Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
|
||||||
|
|
||||||
.element-options {
|
.element-options {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -809,9 +808,10 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: calc(100% - 8px);
|
width: calc(100%);
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-options-wrapper {
|
.advanced-options-wrapper {
|
||||||
|
@ -1061,37 +1061,200 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiple-typography {
|
.multiple-typography {
|
||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border: 1px dashed $color-gray-30;
|
border: 1px dashed $color-gray-30;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.multiple-typography-text,
|
.multiple-typography-text,
|
||||||
.multiple-typography-button {
|
.multiple-typography-button {
|
||||||
font-size: $fs13;
|
font-size: $fs13;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiple-typography-button {
|
||||||
|
cursor: pointer;
|
||||||
|
svg {
|
||||||
|
transition: fill 0.3s;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
fill: $color-gray-10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiple-typography-button {
|
&:hover svg {
|
||||||
cursor: pointer;
|
fill: $color-primary;
|
||||||
svg {
|
}
|
||||||
transition: fill 0.3s;
|
}
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
fill: $color-gray-10;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover svg {
|
svg {
|
||||||
fill: $color-primary;
|
}
|
||||||
|
|
||||||
|
.multiple-typography-button:hover svg {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-selector {
|
||||||
|
background: $color-black;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: calc(100%);
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.font-selector-dropdown {
|
||||||
|
background: #303236;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
padding: 15px 17px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.backend-filters {
|
||||||
|
padding: $small $medium;
|
||||||
|
// width: 220px;
|
||||||
|
top: 40px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
.backend-filter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: $small 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.checkbox-icon {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: $medium;
|
||||||
|
height: $medium;
|
||||||
|
border: 1px solid $color-gray-30;
|
||||||
|
border-radius: $br-small;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 8px;
|
||||||
|
display: none;
|
||||||
|
height: 8px;
|
||||||
|
fill: $color-black;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.backend-name {
|
||||||
|
margin-left: $small;
|
||||||
|
color: $color-gray-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
.checkbox-icon {
|
||||||
|
svg {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: $fs12;
|
||||||
|
background: $color-gray-50;
|
||||||
|
border-radius: $br-small;
|
||||||
|
color: $color-gray-20;
|
||||||
|
border: 1px solid $color-gray-30;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-left: $small;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
fill: $color-gray-20
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
svg {
|
||||||
|
fill: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fonts-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-item {
|
||||||
|
padding-left: $big;
|
||||||
|
height: $x-big;
|
||||||
|
max-height: $x-big;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $color-gray-10;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: $color-black;
|
||||||
|
color: $color-primary;
|
||||||
|
|
||||||
|
.icon svg {fill: $color-primary;}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $color-primary;
|
||||||
|
color: $color-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
// border: 1px solid red;
|
||||||
|
width: $big
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
fill: $color-gray-10;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.multiple-typography-button:hover svg {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ $width-settings-bar: 16rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.tool-window {
|
.tool-window {
|
||||||
|
position: relative;
|
||||||
border-bottom: 1px solid $color-gray-60;
|
border-bottom: 1px solid $color-gray-60;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.data.events :as ev]
|
[app.main.data.events :as ev]
|
||||||
[app.main.data.users :as du]
|
[app.main.data.users :as du]
|
||||||
|
[app.main.data.fonts :as df]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
|
@ -86,6 +87,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(rx/merge
|
(rx/merge
|
||||||
|
(ptk/watch (df/load-team-fonts id) state stream)
|
||||||
(ptk/watch (fetch-projects) state stream)
|
(ptk/watch (fetch-projects) state stream)
|
||||||
(ptk/watch (du/fetch-teams) state stream)
|
(ptk/watch (du/fetch-teams) state stream)
|
||||||
(ptk/watch (du/fetch-users {:team-id id}) state stream)))))
|
(ptk/watch (du/fetch-users {:team-id id}) state stream)))))
|
||||||
|
|
57
frontend/src/app/main/data/fonts.cljs
Normal file
57
frontend/src/app/main/data/fonts.cljs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
;; 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) UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns app.main.data.fonts
|
||||||
|
(:require
|
||||||
|
[app.common.media :as cm]
|
||||||
|
[app.main.fonts :as fonts]
|
||||||
|
[app.main.repo :as rp]
|
||||||
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[cljs.spec.alpha :as s]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
|
(defn prepare-font-variant
|
||||||
|
[item]
|
||||||
|
{:id (str (:font-style item) "-" (:font-weight item))
|
||||||
|
:name (str (cm/font-weight->name (:font-weight item)) " "
|
||||||
|
(str/capital (:font-style item)))
|
||||||
|
:style (:font-style item)
|
||||||
|
:weight (str (:font-weight item))
|
||||||
|
::fonts/woff1-file-id (:woff1-file-id item)
|
||||||
|
::fonts/woff2-file-id (:woff2-file-id item)
|
||||||
|
::fonts/ttf-file-id (:ttf-file-id item)
|
||||||
|
::fonts/otf-file-id (:otf-file-id item)})
|
||||||
|
|
||||||
|
(defn prepare-font
|
||||||
|
[[id [item :as items]]]
|
||||||
|
{:id id
|
||||||
|
:name (:font-family item)
|
||||||
|
:family (:font-family item)
|
||||||
|
:variants (mapv prepare-font-variant items)})
|
||||||
|
|
||||||
|
(defn team-fonts-loaded
|
||||||
|
[fonts]
|
||||||
|
(ptk/reify ::team-fonts-loaded
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state stream]
|
||||||
|
(let [fonts (->> (group-by :font-id fonts)
|
||||||
|
(mapv prepare-font))]
|
||||||
|
(fonts/register! :custom fonts)))))
|
||||||
|
|
||||||
|
(defn load-team-fonts
|
||||||
|
[team-id]
|
||||||
|
(ptk/reify ::load-team-fonts
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(->> (rp/query :team-font-variants {:team-id team-id})
|
||||||
|
(rx/map team-fonts-loaded)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-fonts
|
||||||
|
[backend]
|
||||||
|
(get @fonts/fonts backend []))
|
|
@ -1258,6 +1258,15 @@
|
||||||
(rx/of ::dwp/force-persist
|
(rx/of ::dwp/force-persist
|
||||||
(rt/nav :dashboard-projects {:team-id team-id})))))))
|
(rt/nav :dashboard-projects {:team-id team-id})))))))
|
||||||
|
|
||||||
|
(defn go-to-dashboard-fonts
|
||||||
|
[]
|
||||||
|
(ptk/reify ::go-to-dashboard
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [it state stream]
|
||||||
|
(let [team-id (:current-team-id state)]
|
||||||
|
(rx/of ::dwp/force-persist
|
||||||
|
(rt/nav :dashboard-fonts {:team-id team-id}))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Context Menu
|
;; Context Menu
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.dashboard :as dd]
|
[app.main.data.dashboard :as dd]
|
||||||
[app.main.data.media :as di]
|
[app.main.data.media :as di]
|
||||||
|
[app.main.data.fonts :as df]
|
||||||
[app.main.data.messages :as dm]
|
[app.main.data.messages :as dm]
|
||||||
[app.main.data.workspace.changes :as dch]
|
[app.main.data.workspace.changes :as dch]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
|
@ -270,7 +271,8 @@
|
||||||
:project project
|
:project project
|
||||||
:libraries libraries}))
|
:libraries libraries}))
|
||||||
(rx/mapcat (fn [{:keys [project] :as bundle}]
|
(rx/mapcat (fn [{:keys [project] :as bundle}]
|
||||||
(rx/of (ptk/data-event ::bundle-fetched bundle))))))))
|
(rx/of (ptk/data-event ::bundle-fetched bundle)
|
||||||
|
(df/load-team-fonts (:team-id project)))))))))
|
||||||
|
|
||||||
;; --- Set File shared
|
;; --- Set File shared
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,22 @@
|
||||||
"Fonts management and loading logic."
|
"Fonts management and loading logic."
|
||||||
(:require-macros [app.main.fonts :refer [preload-gfonts]])
|
(:require-macros [app.main.fonts :refer [preload-gfonts]])
|
||||||
(:require
|
(:require
|
||||||
|
[app.config :as cf]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
|
[app.util.logging :as log]
|
||||||
|
[lambdaisland.uri :as u]
|
||||||
|
[goog.events :as gev]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|
||||||
|
(log/set-level! :trace)
|
||||||
|
|
||||||
(def google-fonts
|
(def google-fonts
|
||||||
(preload-gfonts "fonts/gfonts.2020.04.23.json"))
|
(preload-gfonts "fonts/gfonts.2020.04.23.json"))
|
||||||
|
|
||||||
|
@ -38,22 +44,27 @@
|
||||||
{:id "blackitalic" :name "black (italic)" :weight "900" :style "italic"}]}])
|
{:id "blackitalic" :name "black (italic)" :weight "900" :style "italic"}]}])
|
||||||
|
|
||||||
(defonce fontsdb (l/atom {}))
|
(defonce fontsdb (l/atom {}))
|
||||||
(defonce fontsview (l/atom {}))
|
(defonce fonts (l/atom []))
|
||||||
|
|
||||||
(defn- materialize-fontsview
|
|
||||||
[db]
|
|
||||||
(reset! fontsview (reduce-kv (fn [acc k v]
|
|
||||||
(assoc acc k (sort-by :name v)))
|
|
||||||
{}
|
|
||||||
(group-by :backend (vals db)))))
|
|
||||||
(add-watch fontsdb "main"
|
(add-watch fontsdb "main"
|
||||||
(fn [_ _ _ db]
|
(fn [_ _ _ db]
|
||||||
(ts/schedule #(materialize-fontsview db))))
|
(->> (vals db)
|
||||||
|
(sort-by :name)
|
||||||
|
(map-indexed #(assoc %2 :index %1))
|
||||||
|
(vec)
|
||||||
|
(reset! fonts))))
|
||||||
|
|
||||||
|
(defn- remove-fonts
|
||||||
|
[db backend]
|
||||||
|
(reduce-kv #(cond-> %1 (= backend (:backend %3)) (dissoc %2)) db db))
|
||||||
|
|
||||||
(defn register!
|
(defn register!
|
||||||
[backend fonts]
|
[backend fonts]
|
||||||
(let [fonts (map #(assoc % :backend backend) fonts)]
|
(swap! fontsdb
|
||||||
(swap! fontsdb #(merge % (d/index-by :id fonts)))))
|
(fn [db]
|
||||||
|
(let [db (reduce-kv #(cond-> %1 (= backend (:backend %3)) (dissoc %2)) db db)
|
||||||
|
fonts (map #(assoc % :backend backend) fonts)]
|
||||||
|
(merge db (d/index-by :id fonts))))))
|
||||||
|
|
||||||
(register! :builtin local-fonts)
|
(register! :builtin local-fonts)
|
||||||
(register! :google google-fonts)
|
(register! :google google-fonts)
|
||||||
|
@ -67,13 +78,15 @@
|
||||||
|
|
||||||
(defn resolve-fonts
|
(defn resolve-fonts
|
||||||
[backend]
|
[backend]
|
||||||
(get @fontsview backend))
|
(get @fonts backend))
|
||||||
|
|
||||||
;; --- Fonts Loader
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; FONTS LOADING
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defonce loaded (l/atom #{}))
|
(defonce loaded (l/atom #{}))
|
||||||
|
|
||||||
(defn- create-link-node
|
(defn- create-link-element
|
||||||
[uri]
|
[uri]
|
||||||
(let [node (.createElement js/document "link")]
|
(let [node (.createElement js/document "link")]
|
||||||
(unchecked-set node "href" uri)
|
(unchecked-set node "href" uri)
|
||||||
|
@ -81,32 +94,107 @@
|
||||||
(unchecked-set node "type" "text/css")
|
(unchecked-set node "type" "text/css")
|
||||||
node))
|
node))
|
||||||
|
|
||||||
(defn gfont-url [family variants]
|
|
||||||
|
(defn- create-style-element
|
||||||
|
[css]
|
||||||
|
(let [node (.createElement js/document "style")]
|
||||||
|
(unchecked-set node "innerHTML" css)
|
||||||
|
node))
|
||||||
|
|
||||||
|
(defn- load-font-css!
|
||||||
|
"Creates a link element and attaches it to the dom for correctly
|
||||||
|
load external css resource."
|
||||||
|
[url on-loaded]
|
||||||
|
(let [node (create-link-element url)
|
||||||
|
head (.-head ^js js/document)]
|
||||||
|
(gev/listenOnce node "load" (fn [event]
|
||||||
|
(when (fn? on-loaded)
|
||||||
|
(on-loaded))))
|
||||||
|
(dom/append-child! head node)))
|
||||||
|
|
||||||
|
(defn- add-font-css!
|
||||||
|
"Creates a style element and attaches it to the dom."
|
||||||
|
[css]
|
||||||
|
(let [head (.-head ^js js/document)]
|
||||||
|
(->> (create-style-element css)
|
||||||
|
(dom/append-child! head))))
|
||||||
|
|
||||||
|
;; --- LOADER: BUILTIN
|
||||||
|
|
||||||
|
(defmulti ^:private load-font :backend)
|
||||||
|
|
||||||
|
(defmethod load-font :default
|
||||||
|
[{:keys [backend] :as font}]
|
||||||
|
(log/warn :msg "no implementation found for" :backend backend))
|
||||||
|
|
||||||
|
(defmethod load-font :builtin
|
||||||
|
[{:keys [id ::on-loaded] :as font}]
|
||||||
|
(log/debug :action "load-font" :font-id id :backend "builtin")
|
||||||
|
;; (js/console.log "[debug:fonts]: loading builtin font" id)
|
||||||
|
(when (fn? on-loaded)
|
||||||
|
(on-loaded id)))
|
||||||
|
|
||||||
|
;; --- LOADER: GOOGLE
|
||||||
|
|
||||||
|
(defn generate-gfonts-url
|
||||||
|
[{:keys [family variants]}]
|
||||||
(let [base (str "https://fonts.googleapis.com/css?family=" family)
|
(let [base (str "https://fonts.googleapis.com/css?family=" family)
|
||||||
variants (str/join "," (map :id variants))]
|
variants (str/join "," (map :id variants))]
|
||||||
(str base ":" variants "&display=block")))
|
(str base ":" variants "&display=block")))
|
||||||
|
|
||||||
(defmulti ^:private load-font :backend)
|
|
||||||
|
|
||||||
(defmethod load-font :builtin
|
|
||||||
[{:keys [id ::on-loaded] :as font}]
|
|
||||||
(js/console.log "[debug:fonts]: loading builtin font" id)
|
|
||||||
(when (fn? on-loaded)
|
|
||||||
(on-loaded id)))
|
|
||||||
|
|
||||||
(defmethod load-font :google
|
(defmethod load-font :google
|
||||||
[{:keys [id family variants ::on-loaded] :as font}]
|
[{:keys [id family variants ::on-loaded] :as font}]
|
||||||
(when (exists? js/window)
|
(when (exists? js/window)
|
||||||
(js/console.log "[debug:fonts]: loading google font" id)
|
(log/debug :action "load-font" :font-id id :backend "google")
|
||||||
(let [node (create-link-node (gfont-url family variants))]
|
(let [url (generate-gfonts-url font)]
|
||||||
(.addEventListener node "load" (fn [event] (when (fn? on-loaded)
|
(load-font-css! url (partial on-loaded id))
|
||||||
(on-loaded id))))
|
|
||||||
(.append (.-head js/document) node)
|
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
(defmethod load-font :default
|
;; --- LOADER: CUSTOM
|
||||||
[{:keys [backend] :as font}]
|
|
||||||
(js/console.warn "no implementation found for" backend))
|
(def font-css-template
|
||||||
|
"@font-face {
|
||||||
|
font-family: '%(family)s';
|
||||||
|
font-style: %(style)s;
|
||||||
|
font-weight: %(weight)s;
|
||||||
|
font-display: block;
|
||||||
|
src: url(%(woff2-uri)s) format('woff2'),
|
||||||
|
url(%(woff1-uri)s) format('woff'),
|
||||||
|
url(%(ttf-uri)s) format('ttf'),
|
||||||
|
url(%(otf-uri)s) format('otf');
|
||||||
|
}")
|
||||||
|
|
||||||
|
(defn- font-id->uri
|
||||||
|
[font-id]
|
||||||
|
(str (u/join cf/public-uri "assets/by-id/" font-id)))
|
||||||
|
|
||||||
|
(defn generate-custom-font-variant-css
|
||||||
|
[family variant]
|
||||||
|
(str/fmt font-css-template
|
||||||
|
{:family family
|
||||||
|
:style (:style variant)
|
||||||
|
:weight (:weight variant)
|
||||||
|
:woff2-uri (font-id->uri (::woff2-file-id variant))
|
||||||
|
:woff1-uri (font-id->uri (::woff1-file-id variant))
|
||||||
|
:ttf-uri (font-id->uri (::ttf-file-id variant))
|
||||||
|
:otf-uri (font-id->uri (::otf-file-id variant))}))
|
||||||
|
|
||||||
|
(defn- generate-custom-font-css
|
||||||
|
[{:keys [family variants] :as font}]
|
||||||
|
(->> variants
|
||||||
|
(map #(generate-custom-font-variant-css family %))
|
||||||
|
(str/join "\n")))
|
||||||
|
|
||||||
|
(defmethod load-font :custom
|
||||||
|
[{:keys [id family variants ::on-loaded] :as font}]
|
||||||
|
(when (exists? js/window)
|
||||||
|
(js/console.log "[debug:fonts]: loading google font" id)
|
||||||
|
(let [css (generate-custom-font-css font)]
|
||||||
|
(add-font-css! css))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; LOAD API
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn ensure-loaded!
|
(defn ensure-loaded!
|
||||||
([id]
|
([id]
|
||||||
|
@ -119,7 +207,8 @@
|
||||||
(load-font (assoc font ::on-loaded on-loaded))
|
(load-font (assoc font ::on-loaded on-loaded))
|
||||||
(swap! loaded conj id)))))
|
(swap! loaded conj id)))))
|
||||||
|
|
||||||
(defn ready [cb]
|
(defn ready
|
||||||
|
[cb]
|
||||||
(-> (obj/get-in js/document ["fonts" "ready"])
|
(-> (obj/get-in js/document ["fonts" "ready"])
|
||||||
(p/then cb)))
|
(p/then cb)))
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
[props]
|
[props]
|
||||||
(let [children (gobj/get props "children")
|
(let [children (gobj/get props "children")
|
||||||
on-close (gobj/get props "on-close")
|
on-close (gobj/get props "on-close")
|
||||||
ref (gobj/get props "container")
|
ref (gobj/get props "container")
|
||||||
|
|
||||||
on-click
|
on-click
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
"Given a font and the variant-id, retrieves the style CSS for it."
|
"Given a font and the variant-id, retrieves the style CSS for it."
|
||||||
[{:keys [id backend family variants] :as font} font-variant-id]
|
[{:keys [id backend family variants] :as font} font-variant-id]
|
||||||
(if (= :google backend)
|
(if (= :google backend)
|
||||||
(let [uri (fonts/gfont-url family [{:id font-variant-id}])]
|
(let [uri (fonts/generate-gfonts-url {:family family :variants [{:id font-variant-id}]})]
|
||||||
(->> (http/send! {:method :get
|
(->> (http/send! {:method :get
|
||||||
:mode :cors
|
:mode :cors
|
||||||
:omit-default-headers true
|
:omit-default-headers true
|
||||||
|
|
|
@ -128,7 +128,6 @@
|
||||||
:on-click #(handle-change % "rtl")}
|
:on-click #(handle-change % "rtl")}
|
||||||
i/text-direction-rtl]]))
|
i/text-direction-rtl]]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc vertical-align
|
(mf/defc vertical-align
|
||||||
[{:keys [shapes ids values on-change] :as props}]
|
[{:keys [shapes ids values on-change] :as props}]
|
||||||
(let [{:keys [vertical-align]} values
|
(let [{:keys [vertical-align]} values
|
||||||
|
@ -225,63 +224,73 @@
|
||||||
(tr "workspace.options.text-options.title"))
|
(tr "workspace.options.text-options.title"))
|
||||||
|
|
||||||
emit-update!
|
emit-update!
|
||||||
(fn [id attrs]
|
(mf/use-callback
|
||||||
(let [attrs (select-keys attrs root-attrs)]
|
(fn [id attrs]
|
||||||
(when-not (empty? attrs)
|
(let [attrs (select-keys attrs root-attrs)]
|
||||||
(st/emit! (dwt/update-root-attrs {:id id :attrs attrs}))))
|
(when-not (empty? attrs)
|
||||||
|
(st/emit! (dwt/update-root-attrs {:id id :attrs attrs}))))
|
||||||
|
|
||||||
(let [attrs (select-keys attrs paragraph-attrs)]
|
(let [attrs (select-keys attrs paragraph-attrs)]
|
||||||
(when-not (empty? attrs)
|
(when-not (empty? attrs)
|
||||||
(st/emit! (dwt/update-paragraph-attrs {:id id :attrs attrs}))))
|
(st/emit! (dwt/update-paragraph-attrs {:id id :attrs attrs}))))
|
||||||
|
|
||||||
(let [attrs (select-keys attrs text-attrs)]
|
(let [attrs (select-keys attrs text-attrs)]
|
||||||
(when-not (empty? attrs)
|
(when-not (empty? attrs)
|
||||||
(st/emit! (dwt/update-text-attrs {:id id :attrs attrs})))))
|
(st/emit! (dwt/update-text-attrs {:id id :attrs attrs}))))))
|
||||||
|
|
||||||
|
on-change
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [attrs]
|
||||||
|
(run! #(emit-update! % attrs) ids)))
|
||||||
|
|
||||||
typography
|
typography
|
||||||
(cond
|
(mf/use-memo
|
||||||
(and (:typography-ref-id values)
|
(mf/deps values file-id shared-libs)
|
||||||
(not= (:typography-ref-id values) :multiple)
|
(fn []
|
||||||
(not= (:typography-ref-file values) file-id))
|
(cond
|
||||||
(-> shared-libs
|
(and (:typography-ref-id values)
|
||||||
(get-in [(:typography-ref-file values) :data :typographies (:typography-ref-id values)])
|
(not= (:typography-ref-id values) :multiple)
|
||||||
(assoc :file-id (:typography-ref-file values)))
|
(not= (:typography-ref-file values) file-id))
|
||||||
|
(-> shared-libs
|
||||||
|
(get-in [(:typography-ref-file values) :data :typographies (:typography-ref-id values)])
|
||||||
|
(assoc :file-id (:typography-ref-file values)))
|
||||||
|
|
||||||
(and (:typography-ref-id values)
|
(and (:typography-ref-id values)
|
||||||
(not= (:typography-ref-id values) :multiple)
|
(not= (:typography-ref-id values) :multiple)
|
||||||
(= (:typography-ref-file values) file-id))
|
(= (:typography-ref-file values) file-id))
|
||||||
(get typographies (:typography-ref-id values)))
|
(get typographies (:typography-ref-id values)))))
|
||||||
|
|
||||||
on-convert-to-typography
|
on-convert-to-typography
|
||||||
(mf/use-callback
|
(fn [event]
|
||||||
(mf/deps values)
|
(let [setted-values (-> (d/without-nils values)
|
||||||
(fn [event]
|
(select-keys
|
||||||
(let [setted-values (-> (d/without-nils values)
|
(d/concat text-font-attrs
|
||||||
(select-keys
|
text-spacing-attrs
|
||||||
(d/concat text-font-attrs
|
text-transform-attrs)))
|
||||||
text-spacing-attrs
|
typography (merge txt/default-typography setted-values)
|
||||||
text-transform-attrs)))
|
typography (generate-typography-name typography)]
|
||||||
typography (merge txt/default-typography setted-values)
|
(let [id (uuid/next)]
|
||||||
typography (generate-typography-name typography)]
|
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
||||||
(let [id (uuid/next)]
|
(run! #(emit-update! % {:typography-ref-id id
|
||||||
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
:typography-ref-file file-id}) ids))))
|
||||||
(run! #(emit-update! % {:typography-ref-id id
|
|
||||||
:typography-ref-file file-id}) ids)))))
|
|
||||||
|
|
||||||
handle-detach-typography
|
handle-detach-typography
|
||||||
(fn []
|
(mf/use-callback
|
||||||
(run! #(emit-update! % {:typography-ref-file nil
|
(mf/deps on-change)
|
||||||
:typography-ref-id nil})
|
(fn []
|
||||||
ids))
|
(on-change {:typography-ref-file nil
|
||||||
|
:typography-ref-id nil})))
|
||||||
|
|
||||||
handle-change-typography
|
handle-change-typography
|
||||||
(fn [changes]
|
(mf/use-callback
|
||||||
(st/emit! (dwl/update-typography (merge typography changes) file-id)))
|
(mf/deps typography file-id)
|
||||||
|
(fn [changes]
|
||||||
|
(st/emit! (dwl/update-typography (merge typography changes) file-id))))
|
||||||
|
|
||||||
opts #js {:ids ids
|
opts #js {:ids ids
|
||||||
:values values
|
:values values
|
||||||
:on-change (fn [attrs]
|
:on-change on-change}]
|
||||||
(run! #(emit-update! % attrs) ids))}]
|
|
||||||
|
|
||||||
[:div.element-set
|
[:div.element-set
|
||||||
[:div.element-set-title
|
[:div.element-set-title
|
||||||
|
|
|
@ -6,20 +6,30 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.sidebar.options.menus.typography
|
(ns app.main.ui.workspace.sidebar.options.menus.typography
|
||||||
(:require
|
(:require
|
||||||
|
["react-virtualized" :as rvt]
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
|
[app.main.data.shortcuts :as dsc]
|
||||||
|
[app.main.data.fonts :as df]
|
||||||
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[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.editable-select :refer [editable-select]]
|
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
|
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [t]]
|
[app.util.object :as obj]
|
||||||
|
[app.util.timers :as tm]
|
||||||
|
[app.util.keyboard :as kbd]
|
||||||
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
|
[goog.events :as events]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
|
@ -28,74 +38,279 @@
|
||||||
""
|
""
|
||||||
(str value)))
|
(str value)))
|
||||||
|
|
||||||
(mf/defc font-select-optgroups
|
(defn- get-next-font
|
||||||
|
[{:keys [id] :as current} fonts]
|
||||||
|
(if (seq fonts)
|
||||||
|
(let [index (d/index-of-pred fonts #(= (:id %) id))
|
||||||
|
index (or index -1)
|
||||||
|
next (ex/ignoring (nth fonts (inc index)))]
|
||||||
|
(or next (first fonts)))
|
||||||
|
current))
|
||||||
|
|
||||||
|
(defn- get-prev-font
|
||||||
|
[{:keys [id] :as current} fonts]
|
||||||
|
(if (seq fonts)
|
||||||
|
(let [index (d/index-of-pred fonts #(= (:id %) id))
|
||||||
|
next (ex/ignoring (nth fonts (dec index)))]
|
||||||
|
(or next (peek fonts)))
|
||||||
|
current))
|
||||||
|
|
||||||
|
(mf/defc font-item
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [locale] :as props}]
|
[{:keys [font current? on-click style]}]
|
||||||
[:*
|
(let [item-ref (mf/use-ref)
|
||||||
[:optgroup {:label (t locale "workspace.options.text-options.preset")}
|
on-click (mf/use-callback (mf/deps font) #(on-click font))]
|
||||||
(for [font fonts/local-fonts]
|
|
||||||
[:option {:value (:id font)
|
(mf/use-effect
|
||||||
:key (:id font)}
|
(mf/deps current?)
|
||||||
(:name font)])]
|
(fn []
|
||||||
[:optgroup {:label (t locale "workspace.options.text-options.google")}
|
(when current?
|
||||||
(for [font (fonts/resolve-fonts :google)]
|
(let [element (mf/ref-val item-ref)]
|
||||||
[:option {:value (:id font)
|
(when-not (dom/is-in-viewport? element)
|
||||||
:key (:id font)}
|
(dom/scroll-into-view! element))))))
|
||||||
(:name font)])]])
|
|
||||||
|
[:div.font-item {:ref item-ref
|
||||||
|
:style style
|
||||||
|
:class (when current? "selected")
|
||||||
|
:on-click on-click}
|
||||||
|
[:span.icon (when current? i/tick)]
|
||||||
|
[:span.label (:name font)]]))
|
||||||
|
|
||||||
|
(declare row-renderer)
|
||||||
|
|
||||||
|
(defn filter-fonts
|
||||||
|
[{:keys [term backends]} fonts]
|
||||||
|
(let [xform (cond-> (map identity)
|
||||||
|
(seq term)
|
||||||
|
(comp (filter #(str/includes? (str/lower (:name %)) term)))
|
||||||
|
|
||||||
|
(seq backends)
|
||||||
|
(comp (filter #(contains? backends (:backend %)))))]
|
||||||
|
(into [] xform fonts)))
|
||||||
|
|
||||||
|
(defn- toggle-backend
|
||||||
|
[backends id]
|
||||||
|
(if (contains? backends id)
|
||||||
|
(disj backends id)
|
||||||
|
(conj backends id)))
|
||||||
|
|
||||||
|
(mf/defc font-selector
|
||||||
|
[{:keys [on-select on-close current-font] :as props}]
|
||||||
|
(let [selected (mf/use-state current-font)
|
||||||
|
state (mf/use-state {:term "" :backends #{}})
|
||||||
|
|
||||||
|
flist (mf/use-ref)
|
||||||
|
input (mf/use-ref)
|
||||||
|
ddown (mf/use-ref)
|
||||||
|
|
||||||
|
fonts (mf/use-memo (mf/deps @state) #(filter-fonts @state @fonts/fonts))
|
||||||
|
|
||||||
|
select-next
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps fonts)
|
||||||
|
(fn [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(swap! selected get-next-font fonts)))
|
||||||
|
|
||||||
|
select-prev
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps fonts)
|
||||||
|
(fn [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(swap! selected get-prev-font fonts)))
|
||||||
|
|
||||||
|
on-key-down
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps fonts)
|
||||||
|
(fn [event]
|
||||||
|
(cond
|
||||||
|
(kbd/up-arrow? event) (select-prev event)
|
||||||
|
(kbd/down-arrow? event) (select-next event)
|
||||||
|
(kbd/esc? event) (on-close)
|
||||||
|
(kbd/enter? event) (on-close)
|
||||||
|
:else (dom/focus! (mf/ref-val input)))))
|
||||||
|
|
||||||
|
on-filter-change
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps)
|
||||||
|
(fn [event]
|
||||||
|
(let [value (dom/get-target-val event)]
|
||||||
|
(swap! state assoc :term value))))
|
||||||
|
|
||||||
|
on-select-and-close
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps on-select on-close)
|
||||||
|
(fn [font]
|
||||||
|
(on-select font)
|
||||||
|
(on-close)))
|
||||||
|
]
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps fonts)
|
||||||
|
(fn []
|
||||||
|
(let [key (events/listen js/document "keydown" on-key-down)]
|
||||||
|
#(events/unlistenByKey key))))
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps @selected)
|
||||||
|
(fn []
|
||||||
|
(when-let [inst (mf/ref-val flist)]
|
||||||
|
(when-let [index (:index @selected)]
|
||||||
|
(.scrollToRow ^js inst index)))))
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps @selected)
|
||||||
|
(fn []
|
||||||
|
(on-select @selected)))
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(fn []
|
||||||
|
(st/emit! (dsc/push-shortcuts :typography {}))
|
||||||
|
(fn []
|
||||||
|
(st/emit! (dsc/pop-shortcuts :typography)))))
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(fn []
|
||||||
|
(let [index (d/index-of-pred fonts #(= (:id %) (:id current-font)))
|
||||||
|
inst (mf/ref-val flist)]
|
||||||
|
(tm/schedule
|
||||||
|
#(let [offset (.getOffsetForRow ^js inst #js {:alignment "center" :index index})]
|
||||||
|
(.scrollToPosition ^js inst offset))))))
|
||||||
|
|
||||||
|
[:div.font-selector
|
||||||
|
[:div.font-selector-dropdown
|
||||||
|
[:header
|
||||||
|
[:input {:placeholder "Search font"
|
||||||
|
:value (:term @state)
|
||||||
|
:ref input
|
||||||
|
:spell-check false
|
||||||
|
:on-change on-filter-change}]
|
||||||
|
|
||||||
|
#_[:div.options
|
||||||
|
{:on-click #(swap! state assoc :show-options true)
|
||||||
|
:class (when (seq (:backends @state)) "active")}
|
||||||
|
i/picker-hsv]
|
||||||
|
|
||||||
|
#_[:& dropdown {:show (:show-options @state false)
|
||||||
|
:on-close #(swap! state dissoc :show-options)}
|
||||||
|
(let [backends (:backends @state)]
|
||||||
|
[:div.backend-filters.dropdown {:ref ddown}
|
||||||
|
[:div.backend-filter
|
||||||
|
{:class (when (backends :custom) "selected")
|
||||||
|
:on-click #(swap! state update :backends toggle-backend :custom)}
|
||||||
|
[:div.checkbox-icon i/tick]
|
||||||
|
[:div.backend-name (tr "labels.custom-fonts")]]
|
||||||
|
[:div.backend-filter
|
||||||
|
{:class (when (backends :google) "selected")
|
||||||
|
:on-click #(swap! state update :backends toggle-backend :google)}
|
||||||
|
[:div.checkbox-icon i/tick]
|
||||||
|
[:div.backend-name "Google Fonts"]]])]]
|
||||||
|
|
||||||
|
[:hr]
|
||||||
|
|
||||||
|
[:div.fonts-list
|
||||||
|
[:> rvt/AutoSizer {}
|
||||||
|
(fn [props]
|
||||||
|
(let [width (obj/get props "width")
|
||||||
|
height (obj/get props "height")
|
||||||
|
render #(row-renderer fonts @selected on-select-and-close %)]
|
||||||
|
(mf/html
|
||||||
|
[:> rvt/List #js {:height height
|
||||||
|
:ref flist
|
||||||
|
:width width
|
||||||
|
:rowCount (count fonts)
|
||||||
|
:rowHeight 32
|
||||||
|
:rowRenderer render}])))]]]]))
|
||||||
|
(defn row-renderer
|
||||||
|
[fonts selected on-select props]
|
||||||
|
(let [index (obj/get props "index")
|
||||||
|
key (obj/get props "key")
|
||||||
|
style (obj/get props "style")
|
||||||
|
font (nth fonts index)]
|
||||||
|
(mf/html
|
||||||
|
[:& font-item {:key key
|
||||||
|
:font font
|
||||||
|
:style style
|
||||||
|
:on-click on-select
|
||||||
|
:current? (= (:id font) (:id selected))}])))
|
||||||
|
|
||||||
(mf/defc font-options
|
(mf/defc font-options
|
||||||
[{:keys [editor ids values locale on-change] :as props}]
|
[{:keys [editor ids values on-change] :as props}]
|
||||||
(let [{:keys [font-id
|
(let [{:keys [font-id font-size font-variant-id]} values
|
||||||
font-size
|
|
||||||
font-variant-id]} values
|
|
||||||
|
|
||||||
font-id (or font-id (:font-id txt/default-text-attrs))
|
font-id (or font-id (:font-id txt/default-text-attrs))
|
||||||
font-size (or font-size (:font-size txt/default-text-attrs))
|
font-size (or font-size (:font-size txt/default-text-attrs))
|
||||||
font-variant-id (or font-variant-id (:font-variant-id txt/default-text-attrs))
|
font-variant-id (or font-variant-id (:font-variant-id txt/default-text-attrs))
|
||||||
|
|
||||||
fonts (mf/deref fonts/fontsdb)
|
fonts (mf/deref fonts/fontsdb)
|
||||||
font (get fonts font-id)
|
font (get fonts font-id)
|
||||||
|
|
||||||
|
open-selector? (mf/use-state false)
|
||||||
|
|
||||||
change-font
|
change-font
|
||||||
(fn [new-font-id]
|
(mf/use-callback
|
||||||
(let [{:keys [family] :as font} (get fonts new-font-id)
|
(mf/deps on-change fonts)
|
||||||
{:keys [id name weight style]} (fonts/get-default-variant font)]
|
(fn [new-font-id]
|
||||||
(on-change {:font-id new-font-id
|
(let [{:keys [family] :as font} (get fonts new-font-id)
|
||||||
:font-family family
|
{:keys [id name weight style]} (fonts/get-default-variant font)]
|
||||||
:font-variant-id (or id name)
|
(on-change {:font-id new-font-id
|
||||||
:font-weight weight
|
:font-family family
|
||||||
:font-style style})))
|
:font-variant-id (or id name)
|
||||||
|
:font-weight weight
|
||||||
|
:font-style style}))))
|
||||||
|
|
||||||
on-font-family-change
|
on-font-family-change
|
||||||
(fn [event]
|
(mf/use-callback
|
||||||
(let [new-font-id (dom/get-target-val event)]
|
(mf/deps fonts change-font)
|
||||||
(when-not (str/empty? new-font-id)
|
(fn [event]
|
||||||
(let [font (get fonts new-font-id)]
|
(let [new-font-id (dom/get-target-val event)]
|
||||||
(fonts/ensure-loaded! new-font-id (partial change-font new-font-id))))))
|
(when-not (str/empty? new-font-id)
|
||||||
|
(let [font (get fonts new-font-id)]
|
||||||
|
(fonts/ensure-loaded! new-font-id (partial change-font new-font-id)))))))
|
||||||
|
|
||||||
on-font-size-change
|
on-font-size-change
|
||||||
(fn [new-font-size]
|
(mf/use-callback
|
||||||
(when-not (str/empty? new-font-size)
|
(mf/deps on-change)
|
||||||
(on-change {:font-size (str new-font-size)})))
|
(fn [new-font-size]
|
||||||
|
(when-not (str/empty? new-font-size)
|
||||||
|
(on-change {:font-size (str new-font-size)}))))
|
||||||
|
|
||||||
on-font-variant-change
|
on-font-variant-change
|
||||||
(fn [event]
|
(mf/use-callback
|
||||||
(let [new-variant-id (dom/get-target-val event)
|
(mf/deps font on-change)
|
||||||
variant (d/seek #(= new-variant-id (:id %)) (:variants font))]
|
(fn [event]
|
||||||
(on-change {:font-id (:id font)
|
(let [new-variant-id (dom/get-target-val event)
|
||||||
:font-family (:family font)
|
variant (d/seek #(= new-variant-id (:id %)) (:variants font))]
|
||||||
:font-variant-id new-variant-id
|
(on-change {:font-id (:id font)
|
||||||
:font-weight (:weight variant)
|
:font-family (:family font)
|
||||||
:font-style (:style variant)})))]
|
:font-variant-id new-variant-id
|
||||||
|
:font-weight (:weight variant)
|
||||||
|
:font-style (:style variant)}))))
|
||||||
|
|
||||||
|
on-font-select
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps change-font)
|
||||||
|
(fn [font*]
|
||||||
|
(when (not= font font*)
|
||||||
|
(change-font (:id font*)))))
|
||||||
|
|
||||||
|
on-font-selector-close
|
||||||
|
(mf/use-callback
|
||||||
|
#(reset! open-selector? false))]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
|
(when @open-selector?
|
||||||
|
[:& font-selector
|
||||||
|
{:current-font font
|
||||||
|
:on-close on-font-selector-close
|
||||||
|
:on-select on-font-select}])
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:select.input-select.font-option
|
[:div.input-select.font-option
|
||||||
{:value (attr->string font-id)
|
{:on-click #(reset! open-selector? true)}
|
||||||
:on-change on-font-family-change}
|
(:name font)]]
|
||||||
(when (= font-id :multiple)
|
|
||||||
[:option {:value ""} (t locale "settings.multiple")])
|
|
||||||
[:& font-select-optgroups {:locale locale}]]]
|
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
(let [size-options [8 9 10 11 12 14 18 24 36 48 72]
|
(let [size-options [8 9 10 11 12 14 18 24 36 48 72]
|
||||||
|
@ -121,7 +336,7 @@
|
||||||
|
|
||||||
|
|
||||||
(mf/defc spacing-options
|
(mf/defc spacing-options
|
||||||
[{:keys [editor ids values locale on-change] :as props}]
|
[{:keys [editor ids values on-change] :as props}]
|
||||||
(let [{:keys [line-height
|
(let [{:keys [line-height
|
||||||
letter-spacing]} values
|
letter-spacing]} values
|
||||||
|
|
||||||
|
@ -136,7 +351,7 @@
|
||||||
[:div.spacing-options
|
[:div.spacing-options
|
||||||
[:div.input-icon
|
[:div.input-icon
|
||||||
[:span.icon-before.tooltip.tooltip-bottom
|
[:span.icon-before.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.line-height")}
|
{:alt (tr "workspace.options.text-options.line-height")}
|
||||||
i/line-height]
|
i/line-height]
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
{:type "number"
|
{:type "number"
|
||||||
|
@ -144,12 +359,12 @@
|
||||||
:min "0"
|
:min "0"
|
||||||
:max "200"
|
:max "200"
|
||||||
:value (attr->string line-height)
|
:value (attr->string line-height)
|
||||||
:placeholder (t locale "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-change #(handle-change % :line-height)}]]
|
:on-change #(handle-change % :line-height)}]]
|
||||||
|
|
||||||
[:div.input-icon
|
[:div.input-icon
|
||||||
[:span.icon-before.tooltip.tooltip-bottom
|
[:span.icon-before.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.letter-spacing")}
|
{:alt (tr "workspace.options.text-options.letter-spacing")}
|
||||||
i/letter-spacing]
|
i/letter-spacing]
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
{:type "number"
|
{:type "number"
|
||||||
|
@ -157,11 +372,11 @@
|
||||||
:min "0"
|
:min "0"
|
||||||
:max "200"
|
:max "200"
|
||||||
:value (attr->string letter-spacing)
|
:value (attr->string letter-spacing)
|
||||||
:placeholder (t locale "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-change #(handle-change % :letter-spacing)}]]]))
|
:on-change #(handle-change % :letter-spacing)}]]]))
|
||||||
|
|
||||||
(mf/defc text-transform-options
|
(mf/defc text-transform-options
|
||||||
[{:keys [editor ids values locale on-change] :as props}]
|
[{:keys [editor ids values on-change] :as props}]
|
||||||
(let [{:keys [text-transform]} values
|
(let [{:keys [text-transform]} values
|
||||||
|
|
||||||
text-transform (or text-transform "none")
|
text-transform (or text-transform "none")
|
||||||
|
@ -171,35 +386,32 @@
|
||||||
(on-change {:text-transform type}))]
|
(on-change {:text-transform type}))]
|
||||||
[:div.align-icons
|
[:div.align-icons
|
||||||
[:span.tooltip.tooltip-bottom
|
[:span.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.none")
|
{:alt (tr "workspace.options.text-options.none")
|
||||||
:class (dom/classnames :current (= "none" text-transform))
|
:class (dom/classnames :current (= "none" text-transform))
|
||||||
:on-click #(handle-change % "none")}
|
:on-click #(handle-change % "none")}
|
||||||
i/minus]
|
i/minus]
|
||||||
[:span.tooltip.tooltip-bottom
|
[:span.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.uppercase")
|
{:alt (tr "workspace.options.text-options.uppercase")
|
||||||
:class (dom/classnames :current (= "uppercase" text-transform))
|
:class (dom/classnames :current (= "uppercase" text-transform))
|
||||||
:on-click #(handle-change % "uppercase")}
|
:on-click #(handle-change % "uppercase")}
|
||||||
i/uppercase]
|
i/uppercase]
|
||||||
[:span.tooltip.tooltip-bottom
|
[:span.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.lowercase")
|
{:alt (tr "workspace.options.text-options.lowercase")
|
||||||
:class (dom/classnames :current (= "lowercase" text-transform))
|
:class (dom/classnames :current (= "lowercase" text-transform))
|
||||||
:on-click #(handle-change % "lowercase")}
|
:on-click #(handle-change % "lowercase")}
|
||||||
i/lowercase]
|
i/lowercase]
|
||||||
[:span.tooltip.tooltip-bottom
|
[:span.tooltip.tooltip-bottom
|
||||||
{:alt (t locale "workspace.options.text-options.titlecase")
|
{:alt (tr "workspace.options.text-options.titlecase")
|
||||||
:class (dom/classnames :current (= "capitalize" text-transform))
|
:class (dom/classnames :current (= "capitalize" text-transform))
|
||||||
:on-click #(handle-change % "capitalize")}
|
:on-click #(handle-change % "capitalize")}
|
||||||
i/titlecase]]))
|
i/titlecase]]))
|
||||||
|
|
||||||
(mf/defc typography-options
|
(mf/defc typography-options
|
||||||
[{:keys [ids editor values on-change]}]
|
[{:keys [ids editor values on-change]}]
|
||||||
(let [locale (mf/deref i18n/locale)
|
(let [opts #js {:editor editor
|
||||||
opts #js {:editor editor
|
|
||||||
:ids ids
|
:ids ids
|
||||||
:values values
|
:values values
|
||||||
:locale locale
|
|
||||||
:on-change on-change}]
|
:on-change on-change}]
|
||||||
|
|
||||||
[:div.element-set-content
|
[:div.element-set-content
|
||||||
[:> font-options opts]
|
[:> font-options opts]
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
|
@ -209,8 +421,7 @@
|
||||||
|
|
||||||
(mf/defc typography-entry
|
(mf/defc typography-entry
|
||||||
[{:keys [typography read-only? selected? on-click on-change on-detach on-context-menu editting? focus-name? file]}]
|
[{:keys [typography read-only? selected? on-click on-change on-detach on-context-menu editting? focus-name? file]}]
|
||||||
(let [locale (mf/deref i18n/locale)
|
(let [open? (mf/use-state editting?)
|
||||||
open? (mf/use-state editting?)
|
|
||||||
hover-detach (mf/use-state false)
|
hover-detach (mf/use-state false)
|
||||||
name-input-ref (mf/use-ref nil)
|
name-input-ref (mf/use-ref nil)
|
||||||
value (mf/use-state (cp/merge-path-item (:path typography) (:name typography)))
|
value (mf/use-state (cp/merge-path-item (:path typography) (:name typography)))
|
||||||
|
@ -255,7 +466,7 @@
|
||||||
{: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)}}
|
||||||
(t locale "workspace.assets.typography.sample")]
|
(tr "workspace.assets.typography.sample")]
|
||||||
[:div.typography-name (:name typography)]]
|
[:div.typography-name (:name typography)]]
|
||||||
[:div.element-set-actions
|
[:div.element-set-actions
|
||||||
(when on-detach
|
(when on-detach
|
||||||
|
@ -277,32 +488,32 @@
|
||||||
[:span (:name typography)]]
|
[:span (:name typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.font-id")]
|
[:span.label (tr "workspace.assets.typography.font-id")]
|
||||||
[:span (:font-id typography)]]
|
[:span (:font-id typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.font-variant-id")]
|
[:span.label (tr "workspace.assets.typography.font-variant-id")]
|
||||||
[:span (:font-variant-id typography)]]
|
[:span (:font-variant-id typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.font-size")]
|
[:span.label (tr "workspace.assets.typography.font-size")]
|
||||||
[:span (:font-size typography)]]
|
[:span (:font-size typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.line-height")]
|
[:span.label (tr "workspace.assets.typography.line-height")]
|
||||||
[:span (:line-height typography)]]
|
[:span (:line-height typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.letter-spacing")]
|
[:span.label (tr "workspace.assets.typography.letter-spacing")]
|
||||||
[:span (:letter-spacing typography)]]
|
[:span (:letter-spacing typography)]]
|
||||||
|
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:span.label (t locale "workspace.assets.typography.text-transform")]
|
[:span.label (tr "workspace.assets.typography.text-transform")]
|
||||||
[:span (:text-transform typography)]]
|
[:span (:text-transform typography)]]
|
||||||
|
|
||||||
[:div.go-to-lib-button
|
[:div.go-to-lib-button
|
||||||
{:on-click handle-go-to-edit}
|
{:on-click handle-go-to-edit}
|
||||||
(t locale "workspace.assets.typography.go-to-edit")]]
|
(tr "workspace.assets.typography.go-to-edit")]]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
[:div.element-set-content
|
[:div.element-set-content
|
||||||
|
|
|
@ -190,7 +190,6 @@
|
||||||
(defn setup-shortcuts
|
(defn setup-shortcuts
|
||||||
[path-editing? drawing-path?]
|
[path-editing? drawing-path?]
|
||||||
(hooks/use-shortcuts ::workspace wsc/shortcuts)
|
(hooks/use-shortcuts ::workspace wsc/shortcuts)
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps path-editing? drawing-path?)
|
(mf/deps path-editing? drawing-path?)
|
||||||
(fn []
|
(fn []
|
||||||
|
|
|
@ -46,6 +46,9 @@ msgstr "Style"
|
||||||
msgid "labels.custom-fonts"
|
msgid "labels.custom-fonts"
|
||||||
msgstr "Custom fonts"
|
msgstr "Custom fonts"
|
||||||
|
|
||||||
|
msgid "labels.manage-fonts"
|
||||||
|
msgstr "Manage fonts"
|
||||||
|
|
||||||
msgid "labels.search-font"
|
msgid "labels.search-font"
|
||||||
msgstr "Search font"
|
msgstr "Search font"
|
||||||
|
|
||||||
|
@ -55,13 +58,14 @@ msgstr "Font providers"
|
||||||
msgid "labels.upload-custom-fonts"
|
msgid "labels.upload-custom-fonts"
|
||||||
msgstr "Upload custom fonts"
|
msgstr "Upload custom fonts"
|
||||||
|
|
||||||
|
|
||||||
#, markdown
|
#, markdown
|
||||||
msgid "dashboard.fonts.hero-text1"
|
msgid "dashboard.fonts.hero-text1"
|
||||||
msgstr "Any web font you upload here will be added to the font family list available at the text properties of the files of this team. Fonts with the same font family name will be grouped as a **single font family**. You can upload fonts with the following formats: **TTF, OTF and WOFF** (only one will be needed)."
|
msgstr "Any web font you upload here will be added to the font family list available at the text properties of the files of this team. Fonts with the same font family name will be grouped as a **single font family**. You can upload fonts with the following formats: **TTF, OTF and WOFF** (only one will be needed)."
|
||||||
|
|
||||||
#, markdown
|
#, markdown
|
||||||
msgid "dashboard.fonts.hero-text2"
|
msgid "dashboard.fonts.hero-text2"
|
||||||
msgstr "You should only upload fonts you own or have license to use in Penpot. Find out more in the Content rights section of [Penpot's Terms of Service](https://penpot.app/terms.html). You also might want to read about [font licensing](2)."
|
msgstr "You should only upload fonts you own or have license to use in Penpot. Find out more in the Content rights section of [Penpot's Terms of Service](https://penpot.app/terms.html). You also might want to read about [font licensing](https://www.typography.com/faq)."
|
||||||
|
|
||||||
#: src/app/main/ui/auth/register.cljs
|
#: src/app/main/ui/auth/register.cljs
|
||||||
msgid "auth.already-have-account"
|
msgid "auth.already-have-account"
|
||||||
|
|
|
@ -47,6 +47,9 @@ msgstr "Estilo"
|
||||||
msgid "labels.custom-fonts"
|
msgid "labels.custom-fonts"
|
||||||
msgstr "Fuentes personalizadas"
|
msgstr "Fuentes personalizadas"
|
||||||
|
|
||||||
|
msgid "labels.manage-fonts"
|
||||||
|
msgstr "Administrar fuentes"
|
||||||
|
|
||||||
msgid "labels.search-font"
|
msgid "labels.search-font"
|
||||||
msgstr "Buscar fuente"
|
msgstr "Buscar fuente"
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
core-js-pure "^3.0.0"
|
core-js-pure "^3.0.0"
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
|
"@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7":
|
||||||
|
version "7.14.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
|
||||||
|
integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@dabh/diagnostics@^2.0.2":
|
"@dabh/diagnostics@^2.0.2":
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31"
|
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31"
|
||||||
|
@ -802,6 +809,11 @@ cloneable-readable@^1.0.0:
|
||||||
process-nextick-args "^2.0.0"
|
process-nextick-args "^2.0.0"
|
||||||
readable-stream "^2.3.5"
|
readable-stream "^2.3.5"
|
||||||
|
|
||||||
|
clsx@^1.0.4:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||||
|
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||||
|
|
||||||
coa@^2.0.2:
|
coa@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
|
resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
|
||||||
|
@ -1147,6 +1159,11 @@ cssom@^0.3.4:
|
||||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
|
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
|
||||||
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
|
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
|
||||||
|
|
||||||
|
csstype@^3.0.2:
|
||||||
|
version "3.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
||||||
|
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
||||||
|
|
||||||
currently-unhandled@^0.4.1:
|
currently-unhandled@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
|
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
|
||||||
|
@ -1302,6 +1319,14 @@ diffie-hellman@^5.0.0:
|
||||||
miller-rabin "^4.0.0"
|
miller-rabin "^4.0.0"
|
||||||
randombytes "^2.0.0"
|
randombytes "^2.0.0"
|
||||||
|
|
||||||
|
dom-helpers@^5.1.3:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||||
|
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.8.7"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
|
||||||
dom-serializer@0:
|
dom-serializer@0:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||||
|
@ -3049,7 +3074,7 @@ logform@^2.2.0:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
|
|
||||||
loose-envify@^1.0.0, loose-envify@^1.1.0:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||||
|
@ -4003,6 +4028,15 @@ promise@^7.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
asap "~2.0.3"
|
asap "~2.0.3"
|
||||||
|
|
||||||
|
prop-types@^15.7.2:
|
||||||
|
version "15.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
react-is "^16.8.1"
|
||||||
|
|
||||||
proto-list@~1.2.1:
|
proto-list@~1.2.1:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
|
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
|
||||||
|
@ -4119,6 +4153,28 @@ react-dom@~17.0.1:
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
scheduler "^0.20.2"
|
||||||
|
|
||||||
|
react-is@^16.8.1:
|
||||||
|
version "16.13.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-lifecycles-compat@^3.0.4:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-virtualized@^9.22.3:
|
||||||
|
version "9.22.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
|
||||||
|
integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.7.2"
|
||||||
|
clsx "^1.0.4"
|
||||||
|
dom-helpers "^5.1.3"
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-lifecycles-compat "^3.0.4"
|
||||||
|
|
||||||
react@~17.0.1:
|
react@~17.0.1:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue