diff --git a/CHANGES.md b/CHANGES.md index 241f593a73..f00188f3a1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # CHANGELOG -## 2.16.0 (Unreleased) +## 2.17.0 (Unreleased) ### :boom: Breaking changes & Deprecations @@ -72,7 +72,8 @@ - Fix copy to be more specific [Taiga #13990](https://tree.taiga.io/project/penpot/issue/13990) - Allow deleting the profile avatar after uploading [Github #9067](https://github.com/penpot/penpot/issues/9067) -## 2.15.0 (Unreleased) + +## 2.16.0 (Unreleased) ### :boom: Breaking changes & Deprecations @@ -96,6 +97,19 @@ - Fix text editor v1 focus [Taiga #13961](https://tree.taiga.io/project/penpot/issue/13961) +## 2.15.0 (Unreleased) + +### :sparkles: New features & Enhancements + +- Add MCP server integration [Taiga #13112](https://tree.taiga.io/project/penpot/us/13112) +- Add chunked upload API for large media and binary files (removes previous upload size limits) [Github #8909](https://github.com/penpot/penpot/pull/8909) + +### :bug: Bugs fixed + +- Fix incorrect handling of version restore operation [Github #9041](https://github.com/penpot/penpot/pull/9041) +- Fix removeChild errors from unmount race conditions [Github #8927](https://github.com/penpot/penpot/pull/8927) + + ## 2.14.3 ### :sparkles: New features & Enhancements @@ -186,6 +200,8 @@ - Optimize sidebar performance for deeply nested shapes [Taiga #13017](https://tree.taiga.io/project/penpot/task/13017) - Remove tokens path node and bulk remove tokens [Taiga #13007](https://tree.taiga.io/project/penpot/us/13007) - Replace themes management modal radio buttons for switches [Taiga #9215](https://tree.taiga.io/project/penpot/us/9215) +- [MCP server] Integrations section [Taiga #13112](https://tree.taiga.io/project/penpot/us/13112) +- [Access Tokens] Look & feel refinement [Taiga #13114](https://tree.taiga.io/project/penpot/us/13114) ### :bug: Bugs fixed diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index cc23f5aa24..461a611315 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -380,7 +380,6 @@ (rx/take 1) (rx/tap (fn [_] (perf/setup))))) - (->> stream (rx/filter (ptk/type? ::dps/persistence-notification)) (rx/take 1) @@ -488,8 +487,8 @@ :selected-before selected-before}] (rx/of (dwu/append-undo entry stack-undo?))) (rx/empty)))))) - (rx/take-until stoper-s)) + (rx/take-until stoper-s)) (rx/of (mcp/notify-other-tabs-disconnect))))) ptk/EffectEvent diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 8d57dc9361..eaaebedff2 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -545,7 +545,6 @@ (ex/print-throwable cause :prefix "Uncaught Rejection") (ts/asap #(flash :cause cause :type :unhandled))))))))] - (.addEventListener g/window "error" on-unhandled-error) (.addEventListener g/window "unhandledrejection" on-unhandled-rejection) (fn [] diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index 74f5d6901f..b23f818515 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -24,7 +24,7 @@ [app.main.ui.workspace.color-palette :refer [color-palette*]] [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]] [app.main.ui.workspace.text-palette :refer [text-palette*]] - [app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]] + [app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu*]] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.object :as obj] @@ -203,10 +203,10 @@ :ref container} (when text-palette? [:* - [:& text-palette-ctx-menu {:show-menu? show-menu? - :close-menu on-close-menu - :on-select-palette on-select-text-palette-menu - :selected selected-text}] + [:> text-palette-ctx-menu* {:show-menu show-menu? + :close-menu on-close-menu + :on-select-palette on-select-text-palette-menu + :selected selected-text}] [:> text-palette* {:size size :selected selected-text :width vport-width}]]) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs b/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs index 00aa75c462..885b38f1c3 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/text_edition_outline.cljs @@ -16,7 +16,7 @@ [app.render-wasm.api :as wasm.api] [rumext.v2 :as mf])) -(mf/defc text-edition-outline +(mf/defc text-edition-outline* [{:keys [shape zoom modifiers]}] (if (features/active-feature? @st/state "render-wasm/v1") (let [selrect-transform (mf/deref refs/workspace-selrect) diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.cljs b/frontend/src/app/main/ui/workspace/sidebar/history.cljs index 0581ff1878..366fc1715e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/history.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/history.cljs @@ -258,7 +258,7 @@ (map (resolve-shape-types entries objects)) (mapv select-entry))) -(mf/defc history-entry-details [{:keys [entry]}] +(mf/defc history-entry-details* [{:keys [entry]}] (let [{entries :items} (mf/deref workspace-undo) objects (mf/deref refs/workspace-page-objects)] @@ -319,7 +319,7 @@ deprecated-icon/arrow])] (when @show-detail? - [:& history-entry-details {:entry entry}])])) + [:> history-entry-details* {:entry entry}])])) (mf/defc history-toolbox* [] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index f1beba6eb0..077442c428 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -32,7 +32,7 @@ :value 4 :hidden false})) -(mf/defc blur-menu [{:keys [ids type values]}] +(mf/defc blur-menu* [{:keys [ids type values]}] (let [blur (:blur values) has-value? (not (nil? blur)) render-wasm? (features/use-feature "render-wasm/v1") diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs index a56843dce2..ee62bee93f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs @@ -28,7 +28,7 @@ :parent-id :frame-id]) -(mf/defc constraints-menu +(mf/defc constraints-menu* [{:keys [ids values] :as props}] (let [state* (mf/use-state true) open? (deref state*) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs index 326b5efa4a..f3f8619d56 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs @@ -33,7 +33,7 @@ :separator 18 12 10 8 6 4 3 2]) -(mf/defc grid-options +(mf/defc grid-options* {::mf/wrap [mf/memo]} [{:keys [shape-id index grid frame-width frame-height default-grid-params]}] (let [on-change (mf/use-fn (mf/deps shape-id index) #(st/emit! (dw/set-frame-grid shape-id index %))) @@ -296,7 +296,7 @@ [:button {:class (stl/css :option-btn) :on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]])]])])])) -(mf/defc frame-grid +(mf/defc frame-grid* [{:keys [shape]}] (let [state* (mf/use-state true) open? (deref state*) @@ -331,12 +331,12 @@ (when (and open? (seq frame-grids)) [:div {:class (stl/css :element-set-content)} (for [[index grid] (map-indexed vector frame-grids)] - [:& grid-options {:key (str id "-" index) - :shape-id id - :grid grid - :index index - :frame-width (:width shape) - :frame-height (:height shape) - :default-grid-params default-grid-params}])])])) + [:> grid-options* {:key (str id "-" index) + :shape-id id + :grid grid + :index index + :frame-width (:width shape) + :frame-height (:height shape) + :default-grid-params default-grid-params}])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index 491aef1343..154be987f7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -38,7 +38,7 @@ :stroke-cap-start :stroke-cap-end]) -(mf/defc stroke-menu +(mf/defc stroke-menu* {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "show-caps" "applied-tokens"]))]} [{:keys [ids type values show-caps disable-stroke-style applied-tokens shapes objects] :as props}] (let [label (case type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs index b50adf32bf..1928304502 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs @@ -17,7 +17,8 @@ [app.util.i18n :refer [tr]] [rumext.v2 :as mf])) -(mf/defc attribute-value [{:keys [attr value on-change on-delete] :as props}] +(mf/defc attribute-value* + [{:keys [attr value on-change on-delete]}] (let [last-value (mf/use-state value) handle-change* @@ -56,13 +57,14 @@ (str (d/name (last attr)))] (for [[key value] value] [:div {:class (stl/css :attr-row) :key key} - [:& attribute-value {:key key - :attr (conj attr key) - :value value - :on-change on-change - :on-delete on-delete}]])])])) + [:> attribute-value* {:key key + :attr (conj attr key) + :value value + :on-change on-change + :on-delete on-delete}]])])])) -(mf/defc svg-attrs-menu [{:keys [ids values]}] +(mf/defc svg-attrs-menu* + [{:keys [ids values]}] (let [state* (mf/use-state true) open? (deref state*) attrs (:svg-attrs values) @@ -103,8 +105,8 @@ (when open? [:div {:class (stl/css :element-set-content)} (for [[attr-key attr-value] attrs] - [:& attribute-value {:key attr-key - :attr [attr-key] - :value attr-value - :on-change handle-change - :on-delete handle-delete}])])]))) + [:> attribute-value* {:key attr-key + :attr [attr-key] + :value attr-value + :on-change handle-change + :on-delete handle-delete}])])]))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index 35e37a9db2..08c2e73869 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -79,7 +79,6 @@ (mf/defc text-direction-options* [{:keys [values on-change on-blur]}] (let [direction (:text-direction values) - handle-change (mf/use-fn (mf/deps on-change on-blur direction) @@ -103,7 +102,6 @@ (mf/defc vertical-align* [{:keys [values on-change on-blur]}] (let [vertical-align (or (:vertical-align values) "top") - handle-change (mf/use-fn (mf/deps on-change on-blur) @@ -135,11 +133,26 @@ handle-change (mf/use-fn - (mf/deps ids on-blur on-change editor-instance) + (mf/deps ids on-blur editor-instance) (fn [value] - (on-change {:grow-type (keyword value)}) - (when (some? on-blur) - (on-blur))))] + (on-blur) + (let [uid (js/Symbol) + grow-type (keyword value)] + (st/emit! (dwu/start-undo-transaction uid)) + (when (features/active-feature? @st/state "text-editor/v2") + (let [content (when editor-instance + (content/dom->cljs (dwt/get-editor-root editor-instance)))] + (when (some? content) + (st/emit! (dwt/v2-update-text-shape-content (first ids) content :finalize? true))))) + + (st/emit! (dwsh/update-shapes ids #(assoc % :grow-type grow-type))) + + (when (features/active-feature? @st/state "render-wasm/v1") + (st/emit! (dwwt/resize-wasm-text-all ids) + (ptk/data-event :layout/update {:ids ids}))) + ;; We asynchronously commit so every sychronous event is resolved first and inside the transaction + (ts/schedule #(st/emit! (dwu/commit-undo-transaction uid)))) + (when (some? on-blur) (on-blur))))] [:div {:class (stl/css :grow-options)} [:> radio-buttons* {:selected (d/name grow-type) @@ -410,9 +423,9 @@ (dom/focus! (txu/get-text-editor-content))))))) common-props - (mf/spread-props {} {:values values - :on-change on-change - :on-blur on-text-blur})] + (mf/props {:values values + :on-change on-change + :on-blur on-text-blur})] (hooks/use-stream expand-stream diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs index 8404baada7..b836aea6ce 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs @@ -9,8 +9,8 @@ [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -19,7 +19,7 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] [rumext.v2 :as mf])) (mf/defc options* @@ -118,8 +118,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -127,15 +127,15 @@ :values shape :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :show-caps true - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :show-caps true + :values stroke-values + :applied-tokens applied-tokens}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] [:> exports-menu* {:type type :ids ids diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs index 92c630b854..cf5f0cd9fa 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs @@ -9,8 +9,8 @@ [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -19,8 +19,8 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu*]] [rumext.v2 :as mf])) (mf/defc options* @@ -117,8 +117,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -126,15 +126,15 @@ :values shape :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :values stroke-values + :applied-tokens applied-tokens}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] - [:& svg-attrs-menu {:ids ids - :values (select-keys shape [:svg-attrs])}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] + [:> svg-attrs-menu* {:ids ids + :values (select-keys shape [:svg-attrs])}] [:> exports-menu* {:type type :ids ids :shapes shapes diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index d2051a051e..2948e11420 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -10,20 +10,20 @@ [app.common.types.component :as ctk] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]] [app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu* component-variant-main*]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] - [app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]] + [app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid*]] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu*]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] [rumext.v2 :as mf])) (mf/defc options* @@ -140,8 +140,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -149,18 +149,18 @@ :values shape :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type shape-type - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type shape-type + :values stroke-values + :applied-tokens applied-tokens}] [:> color-selection-menu* {:type shape-type :shapes shapes-with-children :file-id file-id :libraries libraries}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] - [:& frame-grid {:shape shape}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] + [:> frame-grid* {:shape shape}] [:> exports-menu* {:type shape-type :ids ids :shapes shapes diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs index f99364cbc9..4da35907b2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs @@ -11,9 +11,9 @@ [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -22,8 +22,8 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu*]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu*]] [app.main.ui.workspace.sidebar.options.menus.text :as ot] [app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]] [rumext.v2 :as mf])) @@ -143,7 +143,7 @@ :values layout-item-values}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids constraint-ids :values constraint-values}]) + [:> constraints-menu* {:ids constraint-ids :values constraint-values}]) (when-not (empty? fill-ids) [:> fill/fill-menu* @@ -153,10 +153,10 @@ :applied-tokens fill-tokens}]) (when-not (empty? stroke-ids) - [:& stroke-menu {:type type - :ids stroke-ids - :values stroke-values - :applied-tokens stroke-tokens}]) + [:> stroke-menu* {:type type + :ids stroke-ids + :values stroke-values + :applied-tokens stroke-tokens}]) [:> color-selection-menu* {:type type @@ -168,7 +168,7 @@ [:> shadow-menu* {:ids ids :values (get shape :shadow) :type type}]) (when-not (empty? blur-ids) - [:& blur-menu {:type type :ids blur-ids :values blur-values}]) + [:> blur-menu* {:type type :ids blur-ids :values blur-values}]) (when-not (empty? text-ids) [:> ot/text-menu* {:type type @@ -177,7 +177,7 @@ :applied-tokens text-tokens}]) (when-not (empty? svg-values) - [:& svg-attrs-menu {:ids ids :values svg-values}]) + [:> svg-attrs-menu* {:ids ids :values svg-values}]) [:> exports-menu* {:type type :ids ids diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index 45f8b994e4..70827abf97 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -20,10 +20,10 @@ [app.common.types.token :as tt] [app.common.weak :as weak] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu*]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]] [app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu*]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-attrs exports-menu*]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu*]] @@ -31,7 +31,7 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] [app.main.ui.workspace.sidebar.options.menus.text :as ot] [rumext.v2 :as mf])) @@ -478,7 +478,7 @@ :values layout-item-values}]) (when-not (or (empty? constraint-ids) ^boolean is-layout-child?) - [:& constraints-menu {:ids constraint-ids :values constraint-values}]) + [:> constraints-menu* {:ids constraint-ids :values constraint-values}]) (when-not (empty? text-ids) [:> ot/text-menu* @@ -494,12 +494,12 @@ :applied-tokens fill-tokens}]) (when-not (empty? stroke-ids) - [:& stroke-menu {:type type - :ids stroke-ids - :show-caps show-caps? - :values stroke-values - :disable-stroke-style has-text? - :applied-tokens stroke-tokens}]) + [:> stroke-menu* {:type type + :ids stroke-ids + :show-caps show-caps? + :values stroke-values + :disable-stroke-style has-text? + :applied-tokens stroke-tokens}]) (when-not (empty? shapes) [:> color-selection-menu* @@ -514,7 +514,7 @@ :values (get shadow-values :shadow)}]) (when-not (empty? blur-ids) - [:& blur-menu {:type type :ids blur-ids :values blur-values}]) + [:> blur-menu* {:type type :ids blur-ids :values blur-values}]) (when-not (empty? exports-ids) [:> exports-menu* {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs index 98cd626d17..79c2788d24 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs @@ -9,8 +9,8 @@ [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -19,8 +19,8 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu*]] [rumext.v2 :as mf])) (mf/defc options* @@ -117,8 +117,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -126,16 +126,16 @@ :values shape :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :show-caps true - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :show-caps true + :values stroke-values + :applied-tokens applied-tokens}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] - [:& svg-attrs-menu {:ids ids - :values (select-keys shape [:svg-attrs])}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] + [:> svg-attrs-menu* {:ids ids + :values (select-keys shape [:svg-attrs])}] [:> exports-menu* {:type type :ids ids :shapes shapes diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs index 4113de291c..ccfadbb62d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs @@ -9,8 +9,8 @@ [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -19,8 +19,8 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu*]] [rumext.v2 :as mf])) (mf/defc options* @@ -117,8 +117,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -126,18 +126,18 @@ :values shape :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :values stroke-values + :applied-tokens applied-tokens}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] - [:& svg-attrs-menu {:ids ids - :values (select-keys shape [:svg-attrs])}] + [:> svg-attrs-menu* {:ids ids + :values (select-keys shape [:svg-attrs])}] [:> exports-menu* {:type type :ids ids :shapes shapes diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs index c71448aaa3..8bb599f3ff 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs @@ -11,8 +11,8 @@ [app.common.types.color :as cc] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -20,8 +20,8 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu*]] [cuerdas.core :as str] [rumext.v2 :as mf])) @@ -184,8 +184,8 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu {:ids ids - :values constraint-values}]) + [:> constraints-menu* {:ids ids + :values constraint-values}]) [:> fill/fill-menu* {:ids ids @@ -193,18 +193,18 @@ :values fill-values :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :values stroke-values - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :values stroke-values + :applied-tokens applied-tokens}] [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] + [:> blur-menu* {:ids ids + :values (select-keys shape [:blur])}] - [:& svg-attrs-menu {:ids ids - :values (select-keys shape [:svg-attrs])}] + [:> svg-attrs-menu* {:ids ids + :values (select-keys shape [:svg-attrs])}] [:> exports-menu* {:type type :ids ids :shapes shapes diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs index 0a19ee1ec1..5825af579a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -14,9 +14,9 @@ [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu*]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]] - [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] + [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu*]] [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu* exports-attrs]] [app.main.ui.workspace.sidebar.options.menus.fill :as fill] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] @@ -25,7 +25,7 @@ [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] - [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu*]] [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu*]] [rumext.v2 :as mf])) @@ -172,7 +172,7 @@ :shape shape}]) (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?) - [:& constraints-menu + [:> constraints-menu* {:ids ids :values (select-keys shape constraint-attrs)}]) @@ -188,11 +188,11 @@ :values fill-values :applied-tokens applied-tokens}] - [:& stroke-menu {:ids ids - :type type - :values stroke-values - :disable-stroke-style true - :applied-tokens applied-tokens}] + [:> stroke-menu* {:ids ids + :type type + :values stroke-values + :disable-stroke-style true + :applied-tokens applied-tokens}] (when (= :multiple (:fills fill-values)) [:> color-selection-menu* @@ -203,7 +203,7 @@ [:> shadow-menu* {:ids ids :values (get shape :shadow)}] - [:& blur-menu + [:> blur-menu* {:ids ids :values (select-keys shape [:blur])}] diff --git a/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs b/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs index c2767a27eb..004f50e36d 100644 --- a/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs +++ b/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs @@ -14,11 +14,11 @@ [app.util.i18n :refer [tr]] [rumext.v2 :as mf])) -(mf/defc text-palette-ctx-menu - [{:keys [show-menu? close-menu on-select-palette selected]}] +(mf/defc text-palette-ctx-menu* + [{:keys [show-menu close-menu on-select-palette selected]}] (let [typographies (mf/deref refs/workspace-file-typography) libraries (mf/deref refs/libraries)] - [:& dropdown {:show show-menu? + [:& dropdown {:show show-menu :on-close close-menu} [:ul {:class (stl/css :text-context-menu)} (for [[idx cur-library] (map-indexed vector (vals libraries))] diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index 54a6bca3e0..5635365543 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -27,7 +27,7 @@ [potok.v2.core :as ptk] [rumext.v2 :as mf])) -(mf/defc image-upload +(mf/defc image-upload* {::mf/wrap [mf/memo]} [] (let [ref (mf/use-ref nil) @@ -181,7 +181,7 @@ :data-tool "text"} deprecated-icon/text]] - [:& image-upload] + [:> image-upload*] [:li [:button diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 6807834d87..a7bb343fb4 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -30,7 +30,7 @@ [app.main.ui.workspace.shapes :as shapes] [app.main.ui.workspace.shapes.path.editor :refer [path-editor*]] [app.main.ui.workspace.shapes.text.editor :as editor-v1] - [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]] + [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline*]] [app.main.ui.workspace.shapes.text.v2-editor :as editor-v2] [app.main.ui.workspace.shapes.text.viewport-texts-html :as stvh] [app.main.ui.workspace.top-toolbar :refer [top-toolbar*]] @@ -489,7 +489,7 @@ :on-context-menu on-menu-selected}]) (when show-text-editor? - [:& text-edition-outline + [:> text-edition-outline* {:shape (get base-objects edition) :zoom zoom :modifiers modifiers}]) diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index 5b15c06f7e..151d380e7d 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -28,7 +28,7 @@ [app.main.ui.measurements :as msr] [app.main.ui.workspace.shapes.path.editor :refer [path-editor*]] [app.main.ui.workspace.shapes.text.editor :as editor-v1] - [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]] + [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline*]] [app.main.ui.workspace.shapes.text.v2-editor :as editor-v2] [app.main.ui.workspace.shapes.text.v3-editor :as editor-v3] [app.main.ui.workspace.top-toolbar :refer [top-toolbar*]] @@ -587,7 +587,7 @@ :on-context-menu on-menu-selected}]) (when show-text-editor? - [:& text-edition-outline + [:> text-edition-outline* {:shape (get base-objects edition) :zoom zoom}]) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 9b0bbc2ad7..577b480347 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -7591,11 +7591,14 @@ msgid "workspace.plugins.empty-plugins" msgstr "No plugins installed yet" #: src/app/main/ui/workspace/plugins.cljs:193 -msgid "workspace.plugins.error.manifest" -msgstr "The plugin manifest is incorrect." + msgid "workspace.plugins.error.manifest" + msgstr "The plugin manifest is incorrect." + +msgid "plugins.validation.message" +msgstr "Field %s is invalid: %s" #: src/app/main/data/plugins.cljs:105, src/app/main/ui/workspace/main_menu.cljs:766, src/app/main/ui/workspace/plugins.cljs:84 -msgid "workspace.plugins.error.need-editor" + msgid "workspace.plugins.error.need-editor" msgstr "You need to be an editor to use this plugin" #: src/app/main/ui/workspace/plugins.cljs:189 diff --git a/mcp/packages/server/data/initial_instructions.md b/mcp/packages/server/data/initial_instructions.md index 3f6c19bd10..dbd2f565b7 100644 --- a/mcp/packages/server/data/initial_instructions.md +++ b/mcp/packages/server/data/initial_instructions.md @@ -374,7 +374,7 @@ Applying tokens: - The actual shape properties that the tokens control will reflect the token's resolved value. Removing tokens: - Simply set the respective property directly - token binding is automatically removed, e.g. + Simply set the respective property directly - token binding is automatically removed, e.g. shape.fills = [{ fillColor: "#000000", fillOpacity: 1 }]; // Removes fill token # Visual Inspection of Designs @@ -386,7 +386,7 @@ For many tasks, it can be critical to visually inspect the design. Remember to u * When transferring styles from a Penpot design to code, make sure that you strictly adhere to the design. NEVER make assumptions about missing values and don't get overly creative (e.g. don't pick your own colours and stick to non-creative defaults such as white/black if you are lacking information). -* When creating new designs, +* When creating new designs, - ensure a clean internal structure by applying flex and grid layouts when appropriate - ensure proper semantic naming of elements.