Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2026-04-24 14:16:03 +02:00
commit 01d68ec09b
21 changed files with 183 additions and 96 deletions

View File

@ -0,0 +1,27 @@
---
name: commiter
description: Git commit assistant following CONTRIBUTING.md commit rules
mode: primary
---
Role: You are responsible for creating git commits for Penpot and must follow
the repository commit-format rules exactly.
Requirements:
* Read `CONTRIBUTING.md` before creating any commit and follow the
commit guidelines strictly.
* Use commit messages in the form `:emoji: <imperative subject>`.
* Keep the subject capitalized, concise, 70 characters or fewer, and
without a trailing period.
* Keep the description (commit body) with maximum line length of 80
characters. Use manual line breaks to wrap text before it exceeds
this limit.
* Separate the subject from the body with a blank line.
* Write a clear and concise body when needed.
* Use `git commit -s` so the commit includes the required
`Signed-off-by` line.
* Do not guess or hallucinate git author information (Name or
Email). Never include the `--author` flag in git commands unless
specifically instructed by the user for a unique case; assume the
local environment is already configured.

View File

@ -32,6 +32,36 @@ precision while maintaining a strong focus on maintainability and performance.
5. When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects 5. When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects
`.gitignore` by default. `.gitignore` by default.
## GitHub Operations
To obtain the list of repository members/collaborators:
```bash
gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login'
```
To obtain the list of open PRs authored by members:
```bash
MEMBERS=$(gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login' | tr '\n' '|' | sed 's/|$//')
gh pr list --state open --limit 200 --json author,title,number | jq -r --arg members "$MEMBERS" '
($members | split("|")) as $m |
.[] | select(.author.login as $a | $m | index($a)) |
"\(.number)\t\(.author.login)\t\(.title)"
'
```
To obtain the list of open PRs from external contributors (non-members):
```bash
MEMBERS=$(gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login' | tr '\n' '|' | sed 's/|$//')
gh pr list --state open --limit 200 --json author,title,number | jq -r --arg members "$MEMBERS" '
($members | split("|")) as $m |
.[] | select(.author.login as $a | $m | index($a) | not) |
"\(.number)\t\(.author.login)\t\(.title)"
'
```
## Architecture Overview ## Architecture Overview
Penpot is an open-source design tool composed of several modules: Penpot is an open-source design tool composed of several modules:

View File

@ -109,6 +109,7 @@
- Fix dashboard navigation tabs overlap with projects content when scrolling [Taiga #13962](https://tree.taiga.io/project/penpot/issue/13962) - Fix dashboard navigation tabs overlap with projects content when scrolling [Taiga #13962](https://tree.taiga.io/project/penpot/issue/13962)
- Fix text editor v1 focus [Taiga #13961](https://tree.taiga.io/project/penpot/issue/13961) - Fix text editor v1 focus [Taiga #13961](https://tree.taiga.io/project/penpot/issue/13961)
- Fix color dropdown option update [Taiga #14035](https://tree.taiga.io/project/penpot/issue/14035) - Fix color dropdown option update [Taiga #14035](https://tree.taiga.io/project/penpot/issue/14035)
- Fix themes modal height [Taiga #14046](https://tree.taiga.io/project/penpot/issue/14046)
## 2.15.0 (Unreleased) ## 2.15.0 (Unreleased)
@ -160,6 +161,7 @@
- Fix wrong `mapcat` call in `collect-main-shapes` - Fix wrong `mapcat` call in `collect-main-shapes`
- Fix stale accumulator in `get-children-in-instance` recursion - Fix stale accumulator in `get-children-in-instance` recursion
- Fix typo `:podition` in swap-shapes grid cell - Fix typo `:podition` in swap-shapes grid cell
- Fix multiple selection on shapes with token applied to stroke color
## 2.14.2 ## 2.14.2

View File

@ -40,8 +40,8 @@
[promesa.util :as pu] [promesa.util :as pu]
[yetti.adapter :as yt]) [yetti.adapter :as yt])
(:import (:import
com.github.luben.zstd.ZstdIOException
com.github.luben.zstd.ZstdInputStream com.github.luben.zstd.ZstdInputStream
com.github.luben.zstd.ZstdIOException
com.github.luben.zstd.ZstdOutputStream com.github.luben.zstd.ZstdOutputStream
java.io.DataInputStream java.io.DataInputStream
java.io.DataOutputStream java.io.DataOutputStream

View File

@ -36,11 +36,11 @@
java.sql.Connection java.sql.Connection
java.sql.PreparedStatement java.sql.PreparedStatement
java.sql.Savepoint java.sql.Savepoint
org.postgresql.PGConnection
org.postgresql.geometric.PGpoint org.postgresql.geometric.PGpoint
org.postgresql.jdbc.PgArray org.postgresql.jdbc.PgArray
org.postgresql.largeobject.LargeObject org.postgresql.largeobject.LargeObject
org.postgresql.largeobject.LargeObjectManager org.postgresql.largeobject.LargeObjectManager
org.postgresql.PGConnection
org.postgresql.util.PGInterval org.postgresql.util.PGInterval
org.postgresql.util.PGobject)) org.postgresql.util.PGobject))

View File

@ -22,13 +22,13 @@
[cuerdas.core :as str] [cuerdas.core :as str]
[integrant.core :as ig]) [integrant.core :as ig])
(:import (:import
jakarta.mail.Message$RecipientType
jakarta.mail.Session
jakarta.mail.Transport
jakarta.mail.internet.InternetAddress jakarta.mail.internet.InternetAddress
jakarta.mail.internet.MimeBodyPart jakarta.mail.internet.MimeBodyPart
jakarta.mail.internet.MimeMessage jakarta.mail.internet.MimeMessage
jakarta.mail.internet.MimeMultipart jakarta.mail.internet.MimeMultipart
jakarta.mail.Message$RecipientType
jakarta.mail.Session
jakarta.mail.Transport
java.util.Properties)) java.util.Properties))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -31,8 +31,8 @@
(:import (:import
clojure.lang.XMLHandler clojure.lang.XMLHandler
java.io.InputStream java.io.InputStream
javax.xml.XMLConstants
javax.xml.parsers.SAXParserFactory javax.xml.parsers.SAXParserFactory
javax.xml.XMLConstants
org.apache.commons.io.IOUtils org.apache.commons.io.IOUtils
org.im4java.core.ConvertCmd org.im4java.core.ConvertCmd
org.im4java.core.IMOperation)) org.im4java.core.IMOperation))

View File

@ -15,16 +15,16 @@
io.prometheus.client.CollectorRegistry io.prometheus.client.CollectorRegistry
io.prometheus.client.Counter io.prometheus.client.Counter
io.prometheus.client.Counter$Child io.prometheus.client.Counter$Child
io.prometheus.client.exporter.common.TextFormat
io.prometheus.client.Gauge io.prometheus.client.Gauge
io.prometheus.client.Gauge$Child io.prometheus.client.Gauge$Child
io.prometheus.client.Histogram io.prometheus.client.Histogram
io.prometheus.client.Histogram$Child io.prometheus.client.Histogram$Child
io.prometheus.client.hotspot.DefaultExports
io.prometheus.client.SimpleCollector io.prometheus.client.SimpleCollector
io.prometheus.client.Summary io.prometheus.client.Summary
io.prometheus.client.Summary$Builder io.prometheus.client.Summary$Builder
io.prometheus.client.Summary$Child io.prometheus.client.Summary$Child
io.prometheus.client.exporter.common.TextFormat
io.prometheus.client.hotspot.DefaultExports
java.io.StringWriter)) java.io.StringWriter))
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)

View File

@ -24,28 +24,28 @@
[integrant.core :as ig]) [integrant.core :as ig])
(:import (:import
clojure.lang.MapEntry clojure.lang.MapEntry
io.lettuce.core.KeyValue
io.lettuce.core.RedisClient
io.lettuce.core.RedisCommandInterruptedException
io.lettuce.core.RedisCommandTimeoutException
io.lettuce.core.RedisException
io.lettuce.core.RedisURI
io.lettuce.core.ScriptOutputType
io.lettuce.core.SetArgs
io.lettuce.core.api.StatefulRedisConnection io.lettuce.core.api.StatefulRedisConnection
io.lettuce.core.api.sync.RedisCommands io.lettuce.core.api.sync.RedisCommands
io.lettuce.core.api.sync.RedisScriptingCommands io.lettuce.core.api.sync.RedisScriptingCommands
io.lettuce.core.codec.RedisCodec io.lettuce.core.codec.RedisCodec
io.lettuce.core.codec.StringCodec io.lettuce.core.codec.StringCodec
io.lettuce.core.KeyValue
io.lettuce.core.pubsub.api.sync.RedisPubSubCommands
io.lettuce.core.pubsub.RedisPubSubListener io.lettuce.core.pubsub.RedisPubSubListener
io.lettuce.core.pubsub.StatefulRedisPubSubConnection io.lettuce.core.pubsub.StatefulRedisPubSubConnection
io.lettuce.core.pubsub.api.sync.RedisPubSubCommands io.lettuce.core.RedisClient
io.lettuce.core.RedisCommandInterruptedException
io.lettuce.core.RedisCommandTimeoutException
io.lettuce.core.RedisException
io.lettuce.core.RedisURI
io.lettuce.core.resource.ClientResources io.lettuce.core.resource.ClientResources
io.lettuce.core.resource.DefaultClientResources io.lettuce.core.resource.DefaultClientResources
io.lettuce.core.ScriptOutputType
io.lettuce.core.SetArgs
io.netty.channel.nio.NioEventLoopGroup io.netty.channel.nio.NioEventLoopGroup
io.netty.util.concurrent.EventExecutorGroup
io.netty.util.HashedWheelTimer io.netty.util.HashedWheelTimer
io.netty.util.Timer io.netty.util.Timer
io.netty.util.concurrent.EventExecutorGroup
java.lang.AutoCloseable java.lang.AutoCloseable
java.time.Duration)) java.time.Duration))

View File

@ -30,21 +30,18 @@
java.nio.file.Path java.nio.file.Path
java.time.Duration java.time.Duration
java.util.Collection java.util.Collection
java.util.Optional
java.util.concurrent.atomic.AtomicLong java.util.concurrent.atomic.AtomicLong
java.util.Optional
org.reactivestreams.Subscriber org.reactivestreams.Subscriber
software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider
software.amazon.awssdk.core.ResponseBytes
software.amazon.awssdk.core.async.AsyncRequestBody software.amazon.awssdk.core.async.AsyncRequestBody
software.amazon.awssdk.core.async.AsyncResponseTransformer software.amazon.awssdk.core.async.AsyncResponseTransformer
software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody
software.amazon.awssdk.core.client.config.ClientAsyncConfiguration software.amazon.awssdk.core.client.config.ClientAsyncConfiguration
software.amazon.awssdk.core.ResponseBytes
software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient
software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup
software.amazon.awssdk.regions.Region software.amazon.awssdk.regions.Region
software.amazon.awssdk.services.s3.S3AsyncClient
software.amazon.awssdk.services.s3.S3AsyncClientBuilder
software.amazon.awssdk.services.s3.S3Configuration
software.amazon.awssdk.services.s3.model.Delete software.amazon.awssdk.services.s3.model.Delete
software.amazon.awssdk.services.s3.model.DeleteObjectRequest software.amazon.awssdk.services.s3.model.DeleteObjectRequest
software.amazon.awssdk.services.s3.model.DeleteObjectsRequest software.amazon.awssdk.services.s3.model.DeleteObjectsRequest
@ -54,9 +51,12 @@
software.amazon.awssdk.services.s3.model.ObjectIdentifier software.amazon.awssdk.services.s3.model.ObjectIdentifier
software.amazon.awssdk.services.s3.model.PutObjectRequest software.amazon.awssdk.services.s3.model.PutObjectRequest
software.amazon.awssdk.services.s3.model.S3Error software.amazon.awssdk.services.s3.model.S3Error
software.amazon.awssdk.services.s3.presigner.S3Presigner
software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest
software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest)) software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest
software.amazon.awssdk.services.s3.presigner.S3Presigner
software.amazon.awssdk.services.s3.S3AsyncClient
software.amazon.awssdk.services.s3.S3AsyncClientBuilder
software.amazon.awssdk.services.s3.S3Configuration))
(def ^:private max-retries (def ^:private max-retries
"A maximum number of retries on internal operations" "A maximum number of retries on internal operations"

View File

@ -17,11 +17,11 @@
java.util.List java.util.List
linked.map.LinkedMap linked.map.LinkedMap
linked.set.LinkedSet linked.set.LinkedSet
org.fressian.handlers.ReadHandler
org.fressian.handlers.WriteHandler
org.fressian.Reader org.fressian.Reader
org.fressian.StreamingWriter org.fressian.StreamingWriter
org.fressian.Writer org.fressian.Writer))
org.fressian.handlers.ReadHandler
org.fressian.handlers.WriteHandler))
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)

View File

@ -8,11 +8,11 @@
(:refer-clojure :exclude [get]) (:refer-clojure :exclude [get])
(:import (:import
java.lang.AutoCloseable java.lang.AutoCloseable
org.apache.commons.pool2.impl.DefaultPooledObject
org.apache.commons.pool2.impl.SoftReferenceObjectPool
org.apache.commons.pool2.ObjectPool org.apache.commons.pool2.ObjectPool
org.apache.commons.pool2.PooledObject org.apache.commons.pool2.PooledObject
org.apache.commons.pool2.PooledObjectFactory org.apache.commons.pool2.PooledObjectFactory))
org.apache.commons.pool2.impl.DefaultPooledObject
org.apache.commons.pool2.impl.SoftReferenceObjectPool))
(defn pool? (defn pool?
[o] [o]

View File

@ -32,7 +32,7 @@ RUN set -ex; \
FROM base AS setup-node FROM base AS setup-node
ENV NODE_VERSION=v22.22.0 \ ENV NODE_VERSION=v24.15.0 \
PATH=/opt/node/bin:$PATH PATH=/opt/node/bin:$PATH
RUN set -eux; \ RUN set -eux; \
@ -67,7 +67,7 @@ RUN set -eux; \
FROM base AS setup-caddy FROM base AS setup-caddy
ENV CADDY_VERSION=2.10.2 ENV CADDY_VERSION=2.11.2
RUN set -eux; \ RUN set -eux; \
ARCH="$(dpkg --print-architecture)"; \ ARCH="$(dpkg --print-architecture)"; \
@ -99,18 +99,18 @@ RUN set -eux; \
FROM base AS setup-jvm FROM base AS setup-jvm
# https://clojure.org/releases/tools # https://clojure.org/releases/tools
ENV CLOJURE_VERSION=1.12.4.1602 ENV CLOJURE_VERSION=1.12.4.1618
RUN set -eux; \ RUN set -eux; \
ARCH="$(dpkg --print-architecture)"; \ ARCH="$(dpkg --print-architecture)"; \
case "${ARCH}" in \ case "${ARCH}" in \
aarch64|arm64) \ aarch64|arm64) \
ESUM='9903c6b19183a33725ca1dfdae5b72400c9d00995c76fafc4a0d31c5152f33f7'; \ ESUM='cc1b459dc442d7422b46a3b5fe52acaea54879fa7913e29a05650cef54687f5f'; \
BINARY_URL='https://cdn.azul.com/zulu/bin/zulu25.32.21-ca-jdk25.0.2-linux_aarch64.tar.gz'; \ BINARY_URL='https://cdn.azul.com/zulu/bin/zulu26.30.11-ca-jdk26.0.1-linux_aarch64.tar.gz'; \
;; \ ;; \
amd64|x86_64) \ amd64|x86_64) \
ESUM='946ad9766d98fc6ab495a1a120072197db54997f6925fb96680f1ecd5591db4e'; \ ESUM='7d6663ea8d4298df65de065e32f9f449745ff607d30ba5d13777cb92e9d4613d'; \
BINARY_URL='https://cdn.azul.com/zulu/bin/zulu25.32.21-ca-jdk25.0.2-linux_x64.tar.gz'; \ BINARY_URL='https://cdn.azul.com/zulu/bin/zulu26.30.11-ca-jdk26.0.1-linux_x64.tar.gz'; \
;; \ ;; \
*) \ *) \
echo "Unsupported arch: ${ARCH}"; \ echo "Unsupported arch: ${ARCH}"; \
@ -181,10 +181,10 @@ RUN set -eux; \
FROM base AS setup-utils FROM base AS setup-utils
ENV CLJKONDO_VERSION=2026.01.19 \ ENV CLJKONDO_VERSION=2026.04.15 \
BABASHKA_VERSION=1.12.208 \ BABASHKA_VERSION=1.12.208 \
CLJFMT_VERSION=0.15.6 \ CLJFMT_VERSION=0.16.4 \
PIXI_VERSION=0.63.2 PIXI_VERSION=0.67.2
RUN set -ex; \ RUN set -ex; \
ARCH="$(dpkg --print-architecture)"; \ ARCH="$(dpkg --print-architecture)"; \

View File

@ -31,9 +31,10 @@
.project-tree { .project-tree {
position: relative; position: relative;
flex-grow: 1; flex-grow: 1;
flex-shrink: 1;
min-width: 0;
height: deprecated.$s-32; height: deprecated.$s-32;
min-height: deprecated.$s-32; min-height: deprecated.$s-32;
max-width: calc(100% - deprecated.$s-64);
} }
.project-name, .project-name,

View File

@ -49,16 +49,16 @@
• :prop → the property type (:fill, :stroke, :shadow, etc.) • :prop → the property type (:fill, :stroke, :shadow, etc.)
• :shape-id → the UUID of the shape using this color • :shape-id → the UUID of the shape using this color
• :index → index of the color in the shape's fill/stroke list • :index → index of the color in the shape's fill/stroke list
Example of groups: Example of groups:
{ {
{:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true} {:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true}
[{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}] [{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}]
{:color \"#1b54b6\", :opacity 1} {:color \"#1b54b6\", :opacity 1}
[{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}] [{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}]
} }
This structure allows fast lookups of all shapes using the same visual color, This structure allows fast lookups of all shapes using the same visual color,
regardless of whether it comes from local fills, strokes or shadow-colors." regardless of whether it comes from local fills, strokes or shadow-colors."
@ -106,12 +106,11 @@
open? (deref open*) open? (deref open*)
has-colors? (or (some? (seq colors)) (some? (seq library-colors))) has-colors? (or (some? (seq colors)) (some? (seq library-colors)))
toggle-content (mf/use-fn #(swap! open* not)) toggle-content (mf/use-fn #(swap! open* not))
expand-lib-color (mf/use-state false) expand-lib-color (mf/use-state false)
expand-color (mf/use-state false) expand-color (mf/use-state false)
expand-token-color (mf/use-state false) expand-token-color (mf/use-state false)
;; TODO: Review if this is still necessary. ;; TODO: Review if this is still necessary.
prev-colors-ref (mf/use-ref nil) prev-colors-ref (mf/use-ref nil)

View File

@ -203,7 +203,9 @@
[:div {:class (stl/css-case :stroke-content true [:div {:class (stl/css-case :stroke-content true
:stroke-content-empty (not has-strokes?))} :stroke-content-empty (not has-strokes?))}
(cond (cond
(= :multiple strokes) (or (= :multiple (:stroke-color applied-tokens))
(= :multiple (:stroke-width applied-tokens))
(= :multiple strokes))
[:div {:class (stl/css :stroke-multiple)} [:div {:class (stl/css :stroke-multiple)}
[:div {:class (stl/css :stroke-multiple-label)} [:div {:class (stl/css :stroke-multiple-label)}
(tr "settings.multiple")] (tr "settings.multiple")]

View File

@ -71,12 +71,13 @@
[{:keys [active-tokens applied-token-name color on-swatch-click-token detach-token open-modal-from-token]}] [{:keys [active-tokens applied-token-name color on-swatch-click-token detach-token open-modal-from-token]}]
(let [;; `active-tokens` may be provided as a `delay` (lazy computation). (let [;; `active-tokens` may be provided as a `delay` (lazy computation).
;; In that case we must deref it (`@active-tokens`) to force evaluation ;; In that case we must deref it (`@active-tokens`) to force evaluation
;; and obtain the actual value. If its already realized (not a delay), ;; and obtain the actual value. If it's already realized (not a delay),
;; we just use it directly. ;; we just use it directly.
active-tokens (if (delay? active-tokens) active-tokens (if (delay? active-tokens)
@active-tokens @active-tokens
active-tokens) active-tokens)
active-color-tokens (:color active-tokens) active-color-tokens (:color active-tokens)
token (some #(when (= (:name %) applied-token-name) %) active-color-tokens) token (some #(when (= (:name %) applied-token-name) %) active-color-tokens)
@ -351,6 +352,10 @@
:dnd-over-top (= (:over dprops) :top) :dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot))] :dnd-over-bot (= (:over dprops) :bot))]
(when (= applied-token :multiple)
;; (js/console.trace "color-row*")
(prn "color-row*" index color applied-token))
(mf/with-effect [color prev-color disable-picker] (mf/with-effect [color prev-color disable-picker]
(when (and (not disable-picker) (not= prev-color color)) (when (and (not disable-picker) (not= prev-color color))
(modal/update-props! :colorpicker {:data (parse-color color)}))) (modal/update-props! :colorpicker {:data (parse-color color)})))

View File

@ -205,6 +205,8 @@
(when (some? on-reorder) (when (some? on-reorder)
[:> reorder-handler* {:ref dref}]) [:> reorder-handler* {:ref dref}])
(prn "stroke-row*" applied-tokens)
;; Stroke Color ;; Stroke Color
;; FIXME: memorize stroke color ;; FIXME: memorize stroke color
[:div {:class (stl/css :stroke-color-actions)} [:div {:class (stl/css :stroke-color-actions)}

View File

@ -98,11 +98,13 @@
on-delete on-delete
(mf/use-fn (mf/use-fn
(mf/deps id) (mf/deps id)
#(st/emit! (modal/show (fn [event]
{:type :confirm (dom/stop-propagation event)
:title (tr "modals.delete-page.title") (st/emit! (modal/show
:message (tr "modals.delete-page.body") {:type :confirm
:on-accept delete-fn}))) :title (tr "modals.delete-page.title")
:message (tr "modals.delete-page.body")
:on-accept delete-fn}))))
on-double-click on-double-click
(mf/use-fn (mf/use-fn

View File

@ -4,19 +4,36 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "ds/_utils.scss" as *;
@use "ds/_sizes.scss" as *; @use "ds/_sizes.scss" as *;
@use "refactor/common-refactor.scss" as deprecated; @use "ds/_borders.scss" as *;
@use "ds/mixins.scss" as *;
@use "ds/z-index.scss" as *;
.modal-overlay { .modal-overlay {
@extend %modal-overlay-base; display: flex;
justify-content: center;
align-items: center;
position: fixed;
inset-inline-start: 0;
inset-block-start: 0;
block-size: 100%;
inline-size: 100%;
z-index: var(--z-index-set);
background-color: var(--color-overlay-default);
} }
.modal-dialog { .modal-dialog {
@extend %modal-container-base; position: relative;
inline-size: 100%;
width: 100%; min-inline-size: $sz-364;
max-width: deprecated.$s-512; min-block-size: $sz-192;
max-height: unset; max-inline-size: $sz-512;
max-block-size: calc(100dvh - #{px2rem(192)});
padding: var(--sp-xxxl);
border-radius: $br-8;
border: $b-2 solid var(--color-background-quaternary);
background-color: var(--color-background-primary);
user-select: none; user-select: none;
} }
@ -25,14 +42,15 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: deprecated.$s-12; gap: var(--sp-m);
padding: deprecated.$s-72 0; padding-block: px2rem(72);
padding-inline: 0;
} }
.themes-modal-wrapper { .themes-modal-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-16; gap: var(--sp-l);
} }
.edit-theme-form { .edit-theme-form {
@ -52,10 +70,10 @@
border: none; border: none;
appearance: none; appearance: none;
color: var(--color-foreground-secondary); color: var(--color-foreground-secondary);
width: fit-content; inline-size: fit-content;
display: grid; display: grid;
grid-template-columns: auto auto; grid-template-columns: auto auto;
gap: deprecated.$s-4; gap: var(--sp-xs);
align-items: center; align-items: center;
padding: 0; padding: 0;
@ -66,9 +84,9 @@
.button-footer { .button-footer {
display: flex; display: flex;
margin-left: auto; margin-inline-start: auto;
justify-content: flex-end; justify-content: flex-end;
gap: deprecated.$s-6; gap: px2rem(6);
} }
.edit-theme-footer { .edit-theme-footer {
@ -97,18 +115,19 @@
.create-theme-wrapper { .create-theme-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-24; gap: var(--sp-xxl);
} }
.close-btn { .close-btn {
position: absolute; position: absolute;
top: deprecated.$s-8; inset-block-start: var(--sp-s);
right: deprecated.$s-6; inset-inline-end: px2rem(6);
} }
.theme-group-label { .theme-group-label {
color: var(--color-foreground-secondary); color: var(--color-foreground-secondary);
margin: 0 0 deprecated.$s-12 0; margin-block: 0 var(--sp-m);
margin-inline: 0;
padding: 0; padding: 0;
} }
@ -116,7 +135,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
gap: deprecated.$s-4; gap: var(--sp-xs);
} }
.group-title-icon { .group-title-icon {
@ -124,35 +143,36 @@
} }
.group-title-name { .group-title-name {
flex-grow: 1; @include textEllipsis;
@include deprecated.text-ellipsis; flex-grow: 1;
} }
.theme-group-rows-wrapper { .theme-group-rows-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-6; gap: px2rem(6);
margin: 0; margin: 0;
} }
.theme-group-wrapper { .theme-group-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-block-start: deprecated.$s-6; margin-block-start: px2rem(6);
overflow-y: auto; overflow-y: auto;
gap: deprecated.$s-32; gap: var(--sp-xxxl);
max-block-size: calc(100dvh - #{px2rem(448)});
} }
.theme-row { .theme-row {
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: deprecated.$s-16; gap: var(--sp-l);
} }
.theme-name-row { .theme-name-row {
@include deprecated.text-ellipsis; @include textEllipsis;
flex-grow: 1; flex-grow: 1;
} }
@ -164,13 +184,13 @@
.theme-actions-row { .theme-actions-row {
align-items: center; align-items: center;
display: flex; display: flex;
gap: deprecated.$s-6; gap: px2rem(6);
flex-shrink: 0; flex-shrink: 0;
} }
.sets-count-button { .sets-count-button {
padding: deprecated.$s-6; padding: px2rem(6);
padding-left: deprecated.$s-12; padding-inline-start: var(--sp-m);
} }
.label-wrapper { .label-wrapper {
@ -183,32 +203,32 @@
.edit-theme-wrapper { .edit-theme-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-24; gap: var(--sp-xxl);
inline-size: 100%; inline-size: 100%;
} }
.sets-list-wrapper { .sets-list-wrapper {
border: deprecated.$s-1 solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent); border: $b-1 solid color-mix(in hsl, var(--color-foreground-secondary) 30%, transparent);
border-radius: deprecated.$s-8; border-radius: $br-8;
overflow-y: auto; overflow-y: auto;
max-height: deprecated.$s-452; max-block-size: px2rem(452);
} }
.sets-count-empty-button { .sets-count-empty-button {
text-transform: lowercase; text-transform: lowercase;
padding: deprecated.$s-6; padding: px2rem(6);
padding-left: deprecated.$s-12; padding-inline-start: var(--sp-m);
} }
.group-input-wrapper { .group-input-wrapper {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-4; gap: var(--sp-xs);
} }
.edit-theme-inputs-wrapper { .edit-theme-inputs-wrapper {
display: grid; display: grid;
grid-template-columns: 0.6fr 1fr; grid-template-columns: 0.6fr 1fr;
gap: deprecated.$s-12; gap: var(--sp-m);
} }

View File

@ -309,9 +309,6 @@
(let [el (dom/get-element "app")] (let [el (dom/get-element "app")]
(mf/create-root el))) (mf/create-root el)))
(declare ^:private render-single-object)
(declare ^:private render-components)
(declare ^:private render-objects)
(defn- parse-params (defn- parse-params
[loc] [loc]