Add per-group add button for typographies (#8895)

*  Add per-group add button for typographies

Add a "+" button to each typography group header, allowing users to
create new typographies directly inside a group instead of only at
the top level. The button only appears for local, editable files.

Closes #5275

* 📚 Add changelog entry for typography group add button

* 🐛 Fix typography group title button layout wrapping

* ♻️ Address review feedback for typography group add button

Signed-off-by: eureka928 <meobius123@gmail.com>
This commit is contained in:
Dream 2026-04-09 03:32:56 -04:00 committed by GitHub
parent e51e0c7933
commit 21217c5622
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 66 additions and 43 deletions

View File

@ -23,6 +23,7 @@
- Add drag-to-change for numeric inputs in workspace sidebar [Github #2466](https://github.com/penpot/penpot/issues/2466)
- Add CSS linter [Taiga #13790](https://tree.taiga.io/project/penpot/us/13790)
- Save and restore selection state in undo/redo (by @eureka928) [Github #6007](https://github.com/penpot/penpot/issues/6007)
- Add per-group add button for typographies (by @eureka928) [Github #5275](https://github.com/penpot/penpot/issues/5275)
### :bug: Bugs fixed

View File

@ -859,50 +859,55 @@
"A higher level version of dwl/add-typography, and has mainly two
responsabilities: add the typography to the library and apply it to
the currently selected text shapes (being aware of the open text
editors."
[file-id]
(ptk/reify ::add-typography
ptk/WatchEvent
(watch [_ state _]
(let [selected (dsh/lookup-selected state)
objects (dsh/lookup-page-objects state)
editors.
Optionally accepts a group-path to place the new typography inside
a specific group."
([file-id] (add-typography file-id nil))
([file-id group-path]
(ptk/reify ::add-typography
ptk/WatchEvent
(watch [_ state _]
(let [selected (dsh/lookup-selected state)
objects (dsh/lookup-page-objects state)
xform (comp (keep (d/getf objects))
(filter cfh/text-shape?))
shapes (into [] xform selected)
shape (first shapes)
xform (comp (keep (d/getf objects))
(filter cfh/text-shape?))
shapes (into [] xform selected)
shape (first shapes)
values (current-text-values
{:editor-state (dm/get-in state [:workspace-editor-state (:id shape)])
:shape shape
:attrs txt/text-node-attrs})
values (current-text-values
{:editor-state (dm/get-in state [:workspace-editor-state (:id shape)])
:shape shape
:attrs txt/text-node-attrs})
multiple? (or (> 1 (count shapes))
(d/seek (partial = :multiple)
(vals values)))
multiple? (or (> 1 (count shapes))
(d/seek (partial = :multiple)
(vals values)))
values (-> (d/without-nils values)
(select-keys
(d/concat-vec txt/text-font-attrs
txt/text-spacing-attrs
txt/text-transform-attrs)))
values (-> (d/without-nils values)
(select-keys
(d/concat-vec txt/text-font-attrs
txt/text-spacing-attrs
txt/text-transform-attrs)))
typ-id (uuid/next)
typ (-> (if multiple?
txt/default-typography
(merge txt/default-typography values))
(generate-typography-name)
(assoc :id typ-id))]
typ-id (uuid/next)
typ (-> (if multiple?
txt/default-typography
(merge txt/default-typography values))
(generate-typography-name)
(assoc :id typ-id)
(cond-> (string? group-path)
(update :name #(str group-path " / " %))))]
(rx/concat
(rx/of (dwl/add-typography typ)
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
:asset-type "typography"}))
(rx/concat
(rx/of (dwl/add-typography typ)
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
:asset-type "typography"}))
(when (not multiple?)
(rx/of (update-attrs (:id shape)
{:typography-ref-id typ-id
:typography-ref-file file-id}))))))))
(when (not multiple?)
(rx/of (update-attrs (:id shape)
{:typography-ref-id typ-id
:typography-ref-file file-id})))))))))
;; -- New Editor

View File

@ -23,7 +23,7 @@
[rumext.v2 :as mf]))
(mf/defc asset-group-title*
[{:keys [file-id section path is-group-open on-rename on-ungroup on-group-combine-variants is-can-combine]}]
[{:keys [file-id section path is-group-open on-rename on-ungroup on-group-combine-variants is-can-combine on-add]}]
(when-not (empty? path)
(let [[other-path last-path truncated] (cpn/compact-path path 35 true)
menu-state (mf/use-state cmm/initial-context-menu-state)
@ -76,6 +76,11 @@
:handler #(on-group-combine-variants path)}))}]]
[:div {:class (stl/css :title-menu)}
(when on-add
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.typography.add-typography")
:on-click on-add
:icon i/add}])
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.component-group-options")
:on-click on-context-menu

View File

@ -25,6 +25,7 @@
}
.title-menu {
display: flex;
visibility: hidden;
}

View File

@ -133,7 +133,7 @@
{::mf/wrap-props false}
[{:keys [file-id prefix groups open-groups force-open? file local? selected local-data
editing-id renaming-id on-asset-click handle-change on-rename-group
on-ungroup on-context-menu selected-full]}]
on-ungroup on-context-menu selected-full is-read-only]}]
(let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that
false
(get open-groups prefix true))
@ -164,7 +164,14 @@
(mf/use-fn
(mf/deps dragging* prefix selected-paths selected-full move-typography)
(fn [event]
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full move-typography)))]
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full move-typography)))
add-typography-to-group
(mf/use-fn
(mf/deps file-id prefix)
(fn [_]
(st/emit! (dw/set-assets-section-open file-id :typographies true)
(dwt/add-typography file-id prefix))))]
[:div {:class (stl/css :typographies-group)
:on-drag-enter on-drag-enter
@ -176,7 +183,9 @@
:path prefix
:is-group-open group-open?
:on-rename on-rename-group
:on-ungroup on-ungroup}]
:on-ungroup on-ungroup
:on-add (when (and local? (not is-read-only))
add-typography-to-group)}]
(when group-open?
[:*
@ -229,7 +238,8 @@
:on-rename-group on-rename-group
:on-ungroup on-ungroup
:on-context-menu on-context-menu
:selected-full selected-full}]))])]))
:selected-full selected-full
:is-read-only is-read-only}]))])]))
(mf/defc typographies-section*
[{:keys [file file-id typographies open-status-ref selected
@ -431,7 +441,8 @@
:on-rename-group on-rename-group
:on-ungroup on-ungroup
:on-context-menu on-context-menu
:selected-full selected-full}]
:selected-full selected-full
:is-read-only read-only?}]
(if is-local
[:> cmm/assets-context-menu*