0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-22 23:06:08 -05:00

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

This commit is contained in:
Andrey Antukh 2025-02-11 11:25:40 +01:00
commit a3a757f842
16 changed files with 121 additions and 29 deletions

View file

@ -38,6 +38,8 @@
(def r-mentions-split #"@\[[^\]]*\]\([^\)]*\)")
(def r-mentions #"@\[([^\]]*)\]\(([^\)]*)\)")
(def comment-max-length 750)
(defn- format-comment
[{:keys [content]}]
(->> (d/interleave-all
@ -442,7 +444,7 @@
[:map {:title "create-comment-thread"}
[:file-id ::sm/uuid]
[:position ::gpt/point]
[:content [:string {:max 750}]]
[:content [:string {:max comment-max-length}]]
[:page-id ::sm/uuid]
[:frame-id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]
@ -585,7 +587,7 @@
schema:create-comment
[:map {:title "create-comment"}
[:thread-id ::sm/uuid]
[:content [:string {:max 250}]]
[:content [:string {:max comment-max-length}]]
[:share-id {:optional true} [:maybe ::sm/uuid]]
[:mentions {:optional true} [::sm/set ::sm/uuid]]])
@ -655,7 +657,7 @@
schema:update-comment
[:map {:title "update-comment"}
[:id ::sm/uuid]
[:content [:string {:max 250}]]
[:content [:string {:max comment-max-length}]]
[:share-id {:optional true} [:maybe ::sm/uuid]]
[:mentions {:optional true} [::sm/set ::sm/uuid]]])

View file

@ -275,7 +275,7 @@
[_ _ _ {:keys [::logger ::props ::level ::cause ::trace ::message]}]
(when (enabled? logger level)
(let [hstyles (str/ffmt "font-weight: 600; color: %" (level->color level))
mstyles (str/ffmt "font-weight: 300; color: %" "#282a2e")
mstyles (str/ffmt "font-weight: 300; color: %" (level->color level))
header (str/concat "%c" (level->name level) " [" logger "] ")
message (str/concat header "%c" @message)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -130,6 +130,21 @@ title: Shortcuts
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>Z</kbd></td>
<td style="text-align: center;"><kbd>⌘</kbd><kbd>Z</kbd></td>
</tr>
<tr>
<td>Copy link to board</td>
<td style="text-align: center;"><kbd>Shift</kbd><kbd>Alt</kbd><kbd>C</kbd></td>
<td style="text-align: center;"><kbd>⇧</kbd><kbd>Alt</kbd><kbd>C</kbd></td>
</tr>
<tr>
<td>Copy properties</td>
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>C</kbd></td>
<td style="text-align: center;"><kbd>⌘</kbd><kbd>⌥</kbd><kbd>C</kbd></td>
</tr>
<tr>
<td>Paste properties</td>
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>V</kbd></td>
<td style="text-align: center;"><kbd>⌘</kbd><kbd>⌥</kbd><kbd>V</kbd></td>
</tr>
</tbody>
</table>

View file

@ -103,7 +103,6 @@ title: 04· Layer basics
<p>At the dropdown menu (right click on a layer to show it) there's the option "Select layer" that allows the user to select one layer among the ones that are under the cursor's location.</p>
<p><img src="/img/layers-select-menu.gif" alt="layers select" /></p>
<h2 id="group-layers">Group layers</h2>
<p>Grouped layers can be moved, transformed or styled at the same time. </p>
<ul>
@ -128,7 +127,6 @@ title: 04· Layer basics
</video>
</figure>
<h2 id="move-layers">Move layers</h2>
<p>To move one or more layers on the viewport you have to select them first and then click and drag the selection where you want to place them. You can also use the design panel to set a precise position relative to the viewport or the board.</p>
<figure>
@ -137,7 +135,6 @@ title: 04· Layer basics
</video>
</figure>
<h2 id="resize-layers">Resize layers</h2>
<p>To resize a selected layer you can use the handles at the edges of the selection box. Make sure the cursor is in resizing mode. You can also use the design panel where you can link width and height.</p>
<ul>
@ -204,6 +201,18 @@ title: 04· Layer basics
</video>
</figure>
<h2 id="scale-elements">Copy CSS properties</h2>
<p>To copy CSS properties from layers:</p>
<ol>
<li>Select one or more layers.</li>
<li>Right click to show the layer menu.</li>
<li>Press <strong>Copy/Paste as... > Copy as CSS</strong> in case you only want to get the CSS properties from the selected layer/s.</li>
<li>Press <strong>Copy/Paste as... > Copy as CSS (nested layers)</strong> in case you only want to get the CSS properties from the selected layer/s and all the contained layers.</li>
</ol>
<figure>
<img alt="Copy CSS properties" src="/img/layers/copy-css.webp"/>
</figure>
<h2 id="collapse-groups">Collapse groups and boards</h2>
<p>Groups and boards can have their contents expanded and collapsed. Click on the arrow at the
right side to toggle the visibility of their contents. </p>

View file

@ -60,6 +60,17 @@ are shown by default at the <a href="/user-guide/view-mode">View mode</a>, actin
</video>
</figure>
<h3>Copy link to board</h3>
<p>You can get the link to each individual board, making it easy to share them with team members or include direct links in documentation.</p>
<figure>
<img src="/img/objects/board-copy-link.webp" alt="copy link to board">
</figure>
<p>There are two ways to copy a direct link to a board:</p>
<ul>
<li>Using the menu: Select the board, right click and select the "Copy link" option.</li>
<li>Using the shortcut: Select the board and press <kbd>Shift/⇧</kbd> + <kbd>Alt/⌥</kbd> + <kbd>C</kbd>.</li>
</ul>
<h3>Clip content</h3>
<p>Boards offer the option to clip its content (or not).</p>
<figure>

View file

@ -181,4 +181,29 @@ title: 06· Styling
<li><strong>Saturation</strong></li>
<li><strong>Color</strong></li>
<li><strong>Luminosity</strong></li>
</ul>
</ul>
<h2 id="copy-paste-properties">Copy/Paste properties</h2>
<p>You can copy and apply properties, including fills, strokes, shadows, and others from one layer to another—or multiple layers with just a few clicks. You can do it using the layer's menu or shortcuts.</p>
<figure>
<video title="Apply blur to a layer" muted="" playsinline="" controls="" width="100%" poster="/img/styling/copy-properties.webp" height="auto">
<source src="/img/styling/copy-properties.mp4" type="video/mp4">
</video>
</figure>
<p>Using the layer menu</p>
<ol>
<li>Select one layer.</li>
<li>Right click to show the layer menu.</li>
<li>Press <strong>Copy/Paste as... > Copy properties</strong>.</li>
<li>Select one or more other layers.</li>
<li>Right click to show the layer/s menu.</li>
<li>Press <strong>Copy/Paste as... > Paste properties</strong>.</li>
</ol>
<p>Using Shortcuts</p>
<ul>
<li><strong>Copy properties</strong>: <kbd>Ctrl/⌘</kbd> + <kbd>Alt/⌥</kbd> + <kbd>C</kbd></li>
<li><strong>Paste properties</strong>: <kbd>Ctrl/⌘</kbd> + <kbd>Alt/⌥</kbd> + <kbd>V</kbd></li>
</ul>

View file

@ -146,7 +146,7 @@
;; Input text for comments with mentions
(mf/defc comment-input*
{::mf/private true}
[{:keys [value placeholder max-length autofocus on-focus on-blur on-change on-esc on-ctrl-enter]}]
[{:keys [value placeholder autofocus on-focus on-blur on-change on-esc on-ctrl-enter]}]
(let [value (d/nilv value "")
prev-value (h/use-previous value)
@ -196,7 +196,7 @@
(dom/append-child! node (create-text-node)))
(let [new-input (parse-nodes node)]
(when (and on-change (<= (count new-input) max-length))
(when on-change
(on-change new-input))))))
handle-select
@ -637,6 +637,10 @@
:disabled is-disabled}
(tr "labels.post")]]))
(defn- exceeds-length?
[content]
(> (count content) 750))
(mf/defc comment-reply-form*
{::mf/props :obj
::mf/private true}
@ -644,7 +648,8 @@
(let [show-buttons? (mf/use-state false)
content (mf/use-state "")
disabled? (blank-content? @content)
disabled? (or (blank-content? @content)
(exceeds-length? @content))
on-focus
(mf/use-fn
@ -678,8 +683,10 @@
:on-blur on-blur
:on-focus on-focus
:on-ctrl-enter on-submit*
:on-change on-change
:max-length 750}]
:on-change on-change}]
(when (exceeds-length? @content)
[:div {:class (stl/css :error-text)}
(tr "errors.character-limit-exceeded")])
(when (or @show-buttons? (seq @content))
[:> comment-form-buttons* {:on-submit on-submit*
:on-cancel on-cancel
@ -690,7 +697,8 @@
[{:keys [content on-submit on-cancel]}]
(let [content (mf/use-state content)
disabled? (blank-content? @content)
disabled? (or (blank-content? @content)
(exceeds-length? @content))
on-change
(mf/use-fn
@ -706,8 +714,10 @@
{:value @content
:autofocus true
:on-ctrl-enter on-submit*
:on-change on-change
:max-length 750}]
:on-change on-change}]
(when (exceeds-length? @content)
[:div {:class (stl/css :error-text)}
(tr "errors.character-limit-exceeded")])
[:> comment-form-buttons* {:on-submit on-submit*
:on-cancel on-cancel
:is-disabled disabled?}]]))
@ -726,7 +736,8 @@
pos-x (* (:x position) zoom)
pos-y (* (:y position) zoom)
disabled? (blank-content? content)
disabled? (or (blank-content? content)
(exceeds-length? content))
on-esc
(mf/use-fn
@ -769,8 +780,10 @@
:autofocus true
:on-esc on-esc
:on-change on-change
:on-ctrl-enter on-submit*
:max-length 750}]
:on-ctrl-enter on-submit*}]
(when (exceeds-length? content)
[:div {:class (stl/css :error-text)}
(tr "errors.character-limit-exceeded")])
[:> comment-form-buttons* {:on-submit on-submit*
:on-cancel on-esc
:is-disabled disabled?}]]

View file

@ -22,6 +22,11 @@
color: var(--comment-subtitle-color);
}
.error-text {
@include bodySmallTypography;
color: var(--color-foreground-error);
}
.location {
color: var(--comment-subtitle-color);
display: flex;
@ -246,6 +251,7 @@
grid-template-columns: 1fr auto auto;
justify-content: flex-end;
gap: $s-8;
margin-top: $s-8;
}
.open-mentions-button {
@ -321,7 +327,6 @@
border: $s-1 solid var(--input-border-color);
color: var(--input-foreground-color);
height: $s-36;
margin-bottom: $s-8;
max-width: $s-260;
overflow-y: auto;
padding: $s-8;

View file

@ -73,10 +73,11 @@ export function mapContentFragmentFromDocument(document, root, styleDefaults) {
currentParagraph = createParagraph(undefined, currentStyle);
}
}
const inline = createInline(new Text(currentNode.nodeValue), currentStyle);
const fontSize = inline.style.getPropertyValue("font-size");
if (!fontSize) console.warn("font-size", fontSize);
const fontFamily = inline.style.getPropertyValue("font-family");
if (!fontFamily) console.warn("font-family", fontFamily);
currentParagraph.appendChild(inline);
currentNode = nodeIterator.nextNode();

View file

@ -23,7 +23,8 @@ export function mergeStyleDeclarations(target, source) {
// for (const styleName of source) {
for (let index = 0; index < source.length; index++) {
const styleName = source.item(index);
target.setProperty(styleName, source.getPropertyValue(styleName));
const styleValue = source.getPropertyValue(styleName);
target.setProperty(styleName, styleValue);
}
return target
}
@ -108,9 +109,10 @@ export function getComputedStyle(element) {
inertElement.style.setProperty(styleName, newValue);
}
} else {
const newValue = currentElement.style.getPropertyValue(styleName);
inertElement.style.setProperty(
styleName,
currentElement.style.getPropertyValue(styleName)
newValue
);
}
}
@ -130,9 +132,10 @@ export function getComputedStyle(element) {
* @returns {CSSStyleDeclaration}
*/
export function normalizeStyles(node, styleDefaults = getStyleDefaultsDeclaration()) {
const computedStyle = getComputedStyle(node.parentElement);
const styleDeclaration = mergeStyleDeclarations(
styleDefaults,
getComputedStyle(node.parentElement)
computedStyle
);
// If there's a color property, we should convert it to
@ -149,7 +152,7 @@ export function normalizeStyles(node, styleDefaults = getStyleDefaultsDeclaratio
// If there's a font-family property and not a --font-id, then
// we remove the font-family because it will not work.
const fontFamily = styleDeclaration.getPropertyValue("font-family");
const fontId = styleDeclaration.getPropertyPriority("--font-id");
const fontId = styleDeclaration.getPropertyValue("--font-id");
if (fontFamily && !fontId) {
styleDeclaration.removeProperty("font-family");
}

View file

@ -1152,6 +1152,10 @@ msgstr "The fonts %s could not be loaded"
msgid "errors.cannot-upload"
msgstr "Cannot upload the media file."
#: src/app/main/ui/comments.cljs:689
msgid "errors.character-limit-exceeded"
msgstr "Character limit exceeded"
#: src/app/main/data/workspace.cljs:1463, src/app/main/data/workspace.cljs:1660
msgid "errors.clipboard-not-implemented"
msgstr "Your browser cannot do this operation"
@ -3528,7 +3532,7 @@ msgstr "Copy"
#: src/app/main/ui/workspace/sidebar/shortcuts.cljs:94
msgid "shortcuts.copy-link"
msgstr "Copy link to clipboard"
msgstr "Copy link"
#: src/app/main/ui/workspace/sidebar/shortcuts.cljs:106
msgid "shortcuts.copy-props"
@ -6188,7 +6192,7 @@ msgstr "Copy as CSS (nested layers)"
#: src/app/main/ui/workspace/context_menu.cljs:188
msgid "workspace.shape.menu.copy-link"
msgstr "Copy link to clipboard"
msgstr "Copy link"
#: src/app/main/ui/workspace/context_menu.cljs:201
msgid "workspace.shape.menu.copy-paste-as"

View file

@ -1160,6 +1160,10 @@ msgstr "No se han podido cargar las fuentes %s"
msgid "errors.cannot-upload"
msgstr "No se puede cargar el archivo multimedia."
#: src/app/main/ui/comments.cljs:689
msgid "errors.character-limit-exceeded"
msgstr "Se ha superado el límite de caracteres"
#: src/app/main/data/workspace.cljs:1463, src/app/main/data/workspace.cljs:1660
msgid "errors.clipboard-not-implemented"
msgstr "Tu navegador no puede realizar esta operación"
@ -3524,7 +3528,7 @@ msgstr "Copiar"
#: src/app/main/ui/workspace/sidebar/shortcuts.cljs:94
msgid "shortcuts.copy-link"
msgstr "Copiar enlace al portapapeles"
msgstr "Copiar enlace"
#: src/app/main/ui/workspace/sidebar/shortcuts.cljs:95
msgid "shortcuts.create-component"
@ -6186,7 +6190,7 @@ msgstr "Copiar como CSS (capas anidadas)"
#: src/app/main/ui/workspace/context_menu.cljs:188
msgid "workspace.shape.menu.copy-link"
msgstr "Copiar enlace al portapapeles"
msgstr "Copiar enlace"
#: src/app/main/ui/workspace/context_menu.cljs:201
msgid "workspace.shape.menu.copy-paste-as"