mirror of
https://github.com/penpot/penpot.git
synced 2026-06-11 18:02:06 +00:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
70cbb65f9c
@ -848,6 +848,9 @@ a[href].post-tag:visited {
|
||||
.illus-techguide {
|
||||
background-image: url(/img/home-technical-guide.webp);
|
||||
}
|
||||
.illus-mcp {
|
||||
background-image: url(/img/home-mcp-server.webp);
|
||||
}
|
||||
.illus-plugins {
|
||||
background-image: url(/img/home-plugins.webp);
|
||||
}
|
||||
|
||||
@ -18,24 +18,30 @@ eleventyNavigation:
|
||||
<p>Everything you need to know about how Penpot works.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-contributing">
|
||||
<a href="/contributing-guide/">
|
||||
<h2>Contributing guide →</h2>
|
||||
<p>How to report bugs, add translations and more.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-techguide">
|
||||
<a href="/technical-guide/">
|
||||
<h2>Technical guide →</h2>
|
||||
<p>Installation, configuration and architecture.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-mcp">
|
||||
<a href="/mcp/">
|
||||
<h2>MCP server →</h2>
|
||||
<p>Connect AI agents to your Penpot files for design and development workflows.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-plugins">
|
||||
<a href="/plugins/">
|
||||
<h2>Plugins →</h2>
|
||||
<p>All about Penpot plugins.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-contributing">
|
||||
<a href="/contributing-guide/">
|
||||
<h2>Contributing guide →</h2>
|
||||
<p>How to report bugs, add translations and more.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-faq">
|
||||
<a href="https://community.penpot.app/c/faq/17">
|
||||
<h2>FAQs →</h2>
|
||||
|
||||
@ -309,6 +309,38 @@ For client-specific setup, use the shared section **Connect your MCP client**.
|
||||
|
||||
For remote mode, use the URL shown in **Your account → Integrations → MCP Server**, which includes your `userToken`.
|
||||
|
||||
### Setup videos
|
||||
|
||||
<figure>
|
||||
<iframe
|
||||
width="672px"
|
||||
height="378px"
|
||||
src="https://www.youtube.com/embed/hBn1iutWSq4?rel=0"
|
||||
title="Penpot MCP Server: Remote Setup in 5 Min | OpenCode + OpenRouter"
|
||||
frameborder="0"
|
||||
loading="lazy"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
<figcaption>Penpot MCP Server – Remote setup with OpenCode and OpenRouter</figcaption>
|
||||
</figure>
|
||||
|
||||
<figure>
|
||||
<iframe
|
||||
width="672px"
|
||||
height="378px"
|
||||
src="https://www.youtube.com/embed/QeSFO0h7GGY?rel=0"
|
||||
title="Penpot MCP Server Remote Setup in 1 Minute | Cursor"
|
||||
frameborder="0"
|
||||
loading="lazy"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
<figcaption>Penpot MCP Server – Remote setup with Cursor</figcaption>
|
||||
</figure>
|
||||
|
||||
<a id="use-remote"></a>
|
||||
### Use
|
||||
|
||||
@ -391,6 +423,23 @@ Leave this terminal running while you use MCP.
|
||||
|
||||
For advanced or repository-based workflows, see the [MCP README](https://github.com/penpot/penpot/blob/main/mcp/README.md) in the Penpot repository.
|
||||
|
||||
### Setup video
|
||||
|
||||
<figure>
|
||||
<iframe
|
||||
width="672px"
|
||||
height="378px"
|
||||
src="https://www.youtube.com/embed/xfgf0kKGOoc?rel=0"
|
||||
title="Penpot MCP Server Local Setup"
|
||||
frameborder="0"
|
||||
loading="lazy"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
<figcaption>Penpot MCP Server – Local setup</figcaption>
|
||||
</figure>
|
||||
|
||||
<a id="connect-local"></a>
|
||||
### Connect
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ rm -rf target
|
||||
pnpm run build;
|
||||
|
||||
cp pnpm-lock.yaml target/;
|
||||
cp pnpm-workspace.yaml target/;
|
||||
cp package.json target/;
|
||||
touch target/pnpm-workspace.yaml;
|
||||
|
||||
|
||||
@ -208,53 +208,28 @@
|
||||
[:and
|
||||
[:map {:title "QuestionsFormStep3"}
|
||||
[:team-size
|
||||
[:enum "more-than-50" "31-50" "11-30" "2-10" "freelancer" "personal-project"]]
|
||||
|
||||
[:planning ::sm/text]
|
||||
|
||||
[:planning-other {:optional true}
|
||||
[::sm/text {:max 512}]]]
|
||||
|
||||
[:fn {:error/field :planning-other}
|
||||
(fn [{:keys [planning planning-other]}]
|
||||
(or (not= planning "other")
|
||||
(and (= planning "other")
|
||||
(not (str/blank? planning-other)))))]])
|
||||
[:enum "1" "2-100" "101-500" "501-1000" "1001-5000" "5001+"]]]])
|
||||
|
||||
(mf/defc step-3
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next on-prev form show-step-3]}]
|
||||
(let [team-size-options
|
||||
(mf/with-memo []
|
||||
[{:label (tr "labels.select-option") :value "" :key "team-size" :disabled true}
|
||||
{:label (tr "onboarding.questions.team-size.more-than-50") :value "more-than-50" :key "more-than-50"}
|
||||
{:label (tr "onboarding.questions.team-size.31-50") :value "31-50" :key "31-50"}
|
||||
{:label (tr "onboarding.questions.team-size.11-30") :value "11-30" :key "11-30"}
|
||||
{:label (tr "onboarding.questions.team-size.2-10") :value "2-10" :key "2-10"}
|
||||
{:label (tr "onboarding.questions.team-size.freelancer") :value "freelancer" :key "freelancer"}
|
||||
{:label (tr "onboarding.questions.team-size.personal-project") :value "personal-project" :key "personal-project"}])
|
||||
|
||||
planning-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "labels.select-option")
|
||||
:value "" :key "questions:what-brings-you-here"
|
||||
:disabled true}
|
||||
{:label (tr "onboarding.questions.reasons.exploring")
|
||||
:value "discover-more-about-penpot"
|
||||
:key "discover-more-about-penpot"}
|
||||
{:label (tr "onboarding.questions.reasons.fit")
|
||||
:value "test-penpot-to-see-if-its-a-fit-for-team"
|
||||
:key "test-penpot-to-see-if-its-a-fit-for-team"}
|
||||
{:label (tr "onboarding.questions.reasons.alternative")
|
||||
:value "alternative-to-figma"
|
||||
:key "alternative-to-figma"}
|
||||
{:label (tr "onboarding.questions.reasons.testing")
|
||||
:value "try-out-before-using-penpot-on-premise"
|
||||
:key "try-out-before-using-penpot-on-premise"}])
|
||||
(conj {:label (tr "labels.other-short") :value "other"})))
|
||||
|
||||
current-planning
|
||||
(dm/get-in @form [:data :planning])]
|
||||
[{:label (tr "labels.select-option")
|
||||
:value "" :key "team-size"
|
||||
:disabled true}
|
||||
{:label (tr "onboarding.questions.team-size.just-me")
|
||||
:value "1" :key "1"}
|
||||
{:label (tr "onboarding.questions.team-size.2-100")
|
||||
:value "2-100" :key "2-100"}
|
||||
{:label (tr "onboarding.questions.team-size.101-500")
|
||||
:value "101-500" :key "101-500"}
|
||||
{:label (tr "onboarding.questions.team-size.501-1000")
|
||||
:value "501-1000" :key "501-1000"}
|
||||
{:label (tr "onboarding.questions.team-size.1001-5000")
|
||||
:value "1001-5000" :key "1001-5000"}
|
||||
{:label (tr "onboarding.questions.team-size.more-than-5001")
|
||||
:value "5001+" :key "5001+"}])]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 3
|
||||
@ -267,26 +242,8 @@
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding.questions.step3.title")]
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.questions.step1.question2")]
|
||||
|
||||
[:& fm/select
|
||||
{:options planning-options
|
||||
:select-class (stl/css :select-class)
|
||||
:default ""
|
||||
:name :planning
|
||||
:dropdown-class (stl/css :question-dropdown)}]]
|
||||
|
||||
(when (= current-planning "other")
|
||||
[:& fm/input {:name :planning-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "labels.other")
|
||||
:show-error false
|
||||
:label ""}])
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "onboarding.questions.step3.question3")]
|
||||
[:& fm/select {:options team-size-options
|
||||
:default ""
|
||||
:select-class (stl/css :select-class)
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
// STEP-3
|
||||
.step-3 {
|
||||
grid-template-rows: deprecated.$s-20 auto auto auto auto deprecated.$s-32;
|
||||
grid-template-rows: deprecated.$s-20 auto auto deprecated.$s-32;
|
||||
}
|
||||
|
||||
.image-radio {
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
[app.main.data.workspace.versions :as dwv]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown-menu :refer [dropdown-menu*
|
||||
dropdown-menu-item*]]
|
||||
@ -938,15 +939,29 @@
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(let [renderer (or (-> profile :props :renderer) :svg)
|
||||
next-renderer (if (= renderer :wasm) :svg :wasm)]
|
||||
(st/emit! (ev/event {::ev/name (if (= next-renderer :wasm)
|
||||
"enable-webgl-rendering"
|
||||
"disable-webgl-rendering")
|
||||
::ev/origin "workspace:menu"})
|
||||
(du/update-profile-props {:renderer next-renderer})
|
||||
(ntf/success (tr (if (= next-renderer :wasm)
|
||||
"webgl.toast.webgl-render-enabled"
|
||||
"webgl.toast.webgl-render-disabled")))))))
|
||||
next-renderer (if (= renderer :wasm) :svg :wasm)
|
||||
ev-name (if (= next-renderer :wasm)
|
||||
"enable-webgl-rendering"
|
||||
"disable-webgl-rendering")]
|
||||
(if (cf/external-feature-flag "renderer-hard-reload" "test")
|
||||
;; Bare RPC + hard reload: skips `du/update-profile-props`, so
|
||||
;; `features/recompute-features` is not run here; bootstrap
|
||||
;; after reload resolves render-wasm/v1 from the saved profile.
|
||||
(do
|
||||
(st/emit! (ev/event {::ev/name ev-name
|
||||
::ev/origin "workspace:menu"}))
|
||||
(->> (rp/cmd! :update-profile-props {:props {:renderer next-renderer}})
|
||||
(rx/subs! (fn [_] (dom/reload-current-window true))
|
||||
(fn [_]
|
||||
(st/emit! (ntf/error (tr "errors.generic")))))))
|
||||
;; `update-profile-props` WatchEvent calls
|
||||
;; `features/recompute-features`.
|
||||
(st/emit! (ev/event {::ev/name ev-name
|
||||
::ev/origin "workspace:menu"})
|
||||
(du/update-profile-props {:renderer next-renderer})
|
||||
(ntf/success (tr (if (= next-renderer :wasm)
|
||||
"webgl.toast.webgl-render-enabled"
|
||||
"webgl.toast.webgl-render-disabled"))))))))
|
||||
|
||||
open-plugins-manager
|
||||
(mf/use-fn
|
||||
|
||||
@ -4873,7 +4873,7 @@ msgstr "What's the size of your company?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:269
|
||||
msgid "onboarding.questions.step3.title"
|
||||
msgstr "Tell us about your job"
|
||||
msgstr "What is your company size?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:344
|
||||
msgid "onboarding.questions.step4.title"
|
||||
@ -4884,7 +4884,25 @@ msgstr "Where would you like to get started?"
|
||||
msgid "onboarding.questions.step5.title"
|
||||
msgstr "How did you hear about Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:232
|
||||
msgid "onboarding.questions.team-size.just-me"
|
||||
msgstr "Just me"
|
||||
|
||||
msgid "onboarding.questions.team-size.2-100"
|
||||
msgstr "2-100"
|
||||
|
||||
msgid "onboarding.questions.team-size.101-500"
|
||||
msgstr "101-500"
|
||||
|
||||
msgid "onboarding.questions.team-size.501-1000"
|
||||
msgstr "501-1,000"
|
||||
|
||||
msgid "onboarding.questions.team-size.1001-5000"
|
||||
msgstr "1,001-5,000"
|
||||
|
||||
msgid "onboarding.questions.team-size.more-than-5001"
|
||||
msgstr "5,001+"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:233
|
||||
msgid "onboarding.questions.team-size.11-30"
|
||||
msgstr "11-30"
|
||||
|
||||
|
||||
@ -4742,7 +4742,7 @@ msgstr "¿Cuál es el tamaño de tu empresa?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:269
|
||||
msgid "onboarding.questions.step3.title"
|
||||
msgstr "Háblanos de tu trabajo"
|
||||
msgstr "¿Cuál es el tamaño de tu empresa?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:344
|
||||
msgid "onboarding.questions.step4.title"
|
||||
@ -4753,7 +4753,25 @@ msgstr "¿Por dónde te apetecería empezar?"
|
||||
msgid "onboarding.questions.step5.title"
|
||||
msgstr "¿Cómo nos has descubierto?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:232
|
||||
msgid "onboarding.questions.team-size.just-me"
|
||||
msgstr "Sólo yo"
|
||||
|
||||
msgid "onboarding.questions.team-size.2-100"
|
||||
msgstr "2-100"
|
||||
|
||||
msgid "onboarding.questions.team-size.101-500"
|
||||
msgstr "101-500"
|
||||
|
||||
msgid "onboarding.questions.team-size.501-1000"
|
||||
msgstr "501-1000"
|
||||
|
||||
msgid "onboarding.questions.team-size.1001-5000"
|
||||
msgstr "1001-5000"
|
||||
|
||||
msgid "onboarding.questions.team-size.more-than-5001"
|
||||
msgstr "5001+"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs:233
|
||||
msgid "onboarding.questions.team-size.11-30"
|
||||
msgstr "11-30"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user