Merge remote-tracking branch 'origin/staging' into develop
@@ -38,7 +38,7 @@
|
||||
metosin/reitit-core {:mvn/version "0.9.1"}
|
||||
nrepl/nrepl {:mvn/version "1.3.1"}
|
||||
|
||||
org.postgresql/postgresql {:mvn/version "42.7.6"}
|
||||
org.postgresql/postgresql {:mvn/version "42.7.7"}
|
||||
org.xerial/sqlite-jdbc {:mvn/version "3.49.1.0"}
|
||||
|
||||
com.zaxxer/HikariCP {:mvn/version "6.3.0"}
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
;; Pretty Print specs
|
||||
pretty-spec/pretty-spec {:mvn/version "0.1.4"}
|
||||
software.amazon.awssdk/s3 {:mvn/version "2.31.55"}}
|
||||
software.amazon.awssdk/s3 {:mvn/version "2.33.8"}}
|
||||
|
||||
:paths ["src" "resources" "target/classes"]
|
||||
:aliases
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
frankiesardo/linked {:mvn/version "1.3.0"}
|
||||
|
||||
com.sun.mail/jakarta.mail {:mvn/version "2.0.1"}
|
||||
com.sun.mail/jakarta.mail {:mvn/version "2.0.2"}
|
||||
org.la4j/la4j {:mvn/version "0.6.0"}
|
||||
|
||||
;; exception printing
|
||||
|
||||
BIN
docs/img/design-tokens/24-tokens-type-number.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/img/design-tokens/25-tokens-type-font-family.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/img/design-tokens/26-tokens-type-font-family-select.webp
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
docs/img/design-tokens/27-tokens-type-font-family-edit.webp
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
docs/img/design-tokens/28-tokens-type-font-family-resolved.webp
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
docs/img/design-tokens/29-tokens-type-font-family-missing.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
docs/img/design-tokens/30-tokens-type-font-size-scale.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/img/design-tokens/31-tokens-type-font-size-function.webp
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
docs/img/design-tokens/32-tokens-base-font-size.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
docs/img/design-tokens/33-tokens-settings.webp
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
docs/img/variants/01-variants-create.webp
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
docs/img/variants/02-variants-created.webp
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
docs/img/variants/03-variants-property-add.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/img/variants/04-variants-properties-edit.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/img/variants/05-variants-use.webp
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
docs/img/variants/06-variants-combine.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/img/variants/variants-connections-conditions.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
@@ -7,19 +7,20 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
<p class="main-paragraph">Speed your workflow with the reusable power of components.</p>
|
||||
<p>A component is an object or group of objects that can be reused multiple times across files. This can help you maintain consistency across a group of designs.</p>
|
||||
|
||||
<p>A component has two parts:</p>
|
||||
<h2 id="components-basics">Components basics</h2>
|
||||
<p>A component consists of two elements:</p>
|
||||
<ul>
|
||||
<li><strong>Main component</strong>: This is the source of truth, a single object in which the main properties of the component are defined.</li>
|
||||
<li><strong>Component copy</strong> (also known as instance): These are duplicates of Main components that inherit its properties.</li>
|
||||
</ol>
|
||||
<li><strong>Main component</strong>: The original source of truth. It defines the core properties of the component.</li>
|
||||
<li><strong>Component copy</strong> (also known as instance): A duplicate of the main component that inherits its properties.</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/components/components-main-copy.webp" alt="Components main and copy" />
|
||||
<figcaption>Mains and copies have different icons. Mains also have a title header at the viewport.</figcaption>
|
||||
</figure>
|
||||
<p>All component copies used in a file are linked in a way that updates made to the Main component can reflect in their component copies. You can override properties for component copies, so that you can manage singularities while maintaining properties in common.</p>
|
||||
|
||||
<h2 id="component-create">Creating components</h2>
|
||||
<h3>Create a component</h3>
|
||||
<h3 id="component-create">Create components</h3>
|
||||
<h4>Create a component</h4>
|
||||
<ol>
|
||||
<li>Select an object or a group of them.</li>
|
||||
<li>Press <kbd>Ctrl</kbd> + <kbd>K</kbd> or right click and select the option “Create component” at the object menu.</li>
|
||||
@@ -30,10 +31,10 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3>Duplicate a component</h3>
|
||||
<h4>Duplicate a component</h4>
|
||||
<p>You can duplicate a component <a href="/user-guide/layer-basics/#duplicating-layers">the same way</a> you can duplicate any other layer. When duplicating a component, you are creating a component copy that will be linked to its main component.</p>
|
||||
|
||||
<h3>Duplicate as main component</h3>
|
||||
<h4>Duplicate as main component</h4>
|
||||
<p>You can duplicate a component as a new main component from the assets sidebar. Just select the component at the library, open the menu with right click and select the option "Duplicate main".</p>
|
||||
<figure>
|
||||
<video title="Duplicate main component" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-duplicate-main.webp" height="auto">
|
||||
@@ -41,7 +42,7 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3>Delete a main component</h3>
|
||||
<h4>Delete a main component</h4>
|
||||
<p>You can delete main components and its copies anytime <a href="/user-guide/layer-basics/#deleting-layers">the same way</a> you can delete any other layer.</p>
|
||||
<p>Deleting a main component at the viewport means deleting it at the assets library and viceversa, so be careful!</p>
|
||||
<figure>
|
||||
@@ -50,7 +51,7 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3>Restore a main component</h3>
|
||||
<h4>Restore a main component</h4>
|
||||
<p>If a main component has been deleted and you have access to a copy of it, you can use the copy to restore its main. There are two ways to do it:</p>
|
||||
<ul>
|
||||
<li>From the <strong>viewport menu</strong>: Select the component copy of a deleted main component, right click and press the option "Restore main component".</li>
|
||||
@@ -61,11 +62,36 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
<figcaption>Mains and copies have different icons. Mains also have a title header at the viewport.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h2 id="component-group">Group components</h2>
|
||||
<h3>Create component groups</h3>
|
||||
<h3 id="component-find">Find main components</h3>
|
||||
<p>Where's my component? There are ways to find main components at the assets panel and at the design viewport.</p>
|
||||
|
||||
<h4>Find a main component at the assets panel</h4>
|
||||
<p>Select a main component at the viewport and then press "Show in assets panel" at the options of the right sidebar.</p>
|
||||
<figure>
|
||||
<video title="Show main component in the assets library" muted="" playsinline="" controls="" width="100%" poster="/img/components/components-show-asset.webp" height="auto">
|
||||
<source src="/img/components/components-show-asset.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h4>Find a main component at the viewport</h4>
|
||||
<p>Select a component copy and then press "Show main component" at the viewport menu or the right sidebar menu.</p>
|
||||
<figure>
|
||||
<video title="Show main component" muted="" playsinline="" controls="" width="100%" poster="/img/components/components-show-main.webp" height="auto">
|
||||
<source src="/img/components/components-show-main.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3 id="component-main-components-page">Main components page</h3>
|
||||
<p>If you find a page at a file called "Main components" this will probably mean that the file had assets with the previous components system and has been migrated to the current components system. The previous system didn't have the components as layers at the design file, only at the assets library, so when migrating a file to the new version Penpot automatically creates a page where to place all the components, grouping them using the library groups structure.</p>
|
||||
<figure>
|
||||
<img src="/img/components/components-page-main.webp" alt="Main components page" />
|
||||
</figure>
|
||||
|
||||
<h2 id="working-with-components">Working with components</h2>
|
||||
<h3 id="component-group">Group components</h3>
|
||||
<p>At the Components section from the Assets library, there are two ways to create groups in a components library.</p>
|
||||
<ol>
|
||||
<li><strong>Using slashes (/):</strong> Select one component and rename it as follows: "FOLDER NAME/COMPONENT NAME". For example, "Buttons/Alert Button".</li>
|
||||
<li><strong>Using slashes (/):</strong> Select one component and rename it as follows: "<i>FOLDER NAME/COMPONENT NAME</i>". For example, "<i>Buttons/Alert Button</i>".</li>
|
||||
<li><strong>Using the "Group" option:</strong> Select one or more components at the Assets library, right click to show the menu and then select "Group".</li>
|
||||
</ol>
|
||||
<figure>
|
||||
@@ -74,10 +100,10 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3>Ungroup components</h3>
|
||||
<h4>Ungroup components</h4>
|
||||
<p>You can ungroup the components the same ways you can group them, via the menu option ("Ungroup" in this case) or renaming them.</p>
|
||||
|
||||
<h3>Drag components to groups</h3>
|
||||
<h4>Drag components to groups</h4>
|
||||
<p>One very direct way to move components between groups at the assets library is by dragging them.</p>
|
||||
<figure>
|
||||
<video title="Drag components" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-drag.webp" height="auto">
|
||||
@@ -85,26 +111,40 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h2 id="component-find">Find components</h2>
|
||||
<p>Where's my component? There are ways to find some components at the assets panel and at the design viewport.</p>
|
||||
<h3 id="component-detach">Detach components</h3>
|
||||
<p>Detach a component copy to unlink it from its Main component and transform it into a group layer. Press <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd> or right click and select the option “Detach instance” at the component menu.</p>
|
||||
<p>You can also detach components in bulk by selecting several components and performing the same action.</p>
|
||||
|
||||
<h3>Find a main component at the assets panel</h3>
|
||||
<p>Select a main component at the viewport and then press "Show in assets panel" at the options of the right sidebar.</p>
|
||||
<h3 id="component-annotate">Annotate components</h3>
|
||||
<p>You can add text annotations to main components. The annotations are shown in every component copy. It is extremely useful to attach specifications that can be read at each component copy.</p>
|
||||
<figure>
|
||||
<video title="Show main component in the assets library" muted="" playsinline="" controls="" width="100%" poster="/img/components/components-show-asset.webp" height="auto">
|
||||
<source src="/img/components/components-show-asset.mp4" type="video/mp4">
|
||||
<video title="Annotating components at Penpot" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-annotation.webp" height="auto">
|
||||
<source src="/img/components/components-annotation.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h3>Find a main component at the viewport</h3>
|
||||
<p>Select a component copy and then press "Show main component" at the viewport menu or the right sidebar menu.</p>
|
||||
<p>The annotations are also shown at the <a href="/user-guide/inspect">Inspect tab</a>, as another option to improve communication between designers and developers.</p>
|
||||
<figure>
|
||||
<video title="Show main component" muted="" playsinline="" controls="" width="100%" poster="/img/components/components-show-main.webp" height="auto">
|
||||
<source src="/img/components/components-show-main.mp4" type="video/mp4">
|
||||
<img src="/img/components/components-annotations-inspect.webp" alt="Annotations at inspect tab" />
|
||||
</figure>
|
||||
|
||||
<h2 id="component-overrides-relationships">Component Overrides & Relationships</h2>
|
||||
<h3 id="component-overrides">Component overrides</h3>
|
||||
<p>Main components represent the more generic information of an element in a design system. You will usually need to change specific things (like a text, a color or an icon) in a component while maintaining the inheritance of the rest of it properties. Component overrides allows you to do that in Penpot.</p>
|
||||
<p>Overrides are modifications made in a specific copy that are not in its main component. With overrides you can keep changes at the component copies while maintaining synchronization with the Main component.</p>
|
||||
<figure>
|
||||
<img src="/img/components/components-overrides.webp" alt="Components overrides" />
|
||||
</figure>
|
||||
|
||||
<h4>Reset overrides</h4>
|
||||
<p>Right click and select the option “Reset overrides” at the component menu to get it to the state of the Main component.</p>
|
||||
<figure>
|
||||
<video title="Reset component overrides" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-reset-overrides.webp" height="auto">
|
||||
<source src="/img/components/components-reset-overrides.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h2 id="component-update">Update main component from copy</h2>
|
||||
<h3 id="component-update">Update main from copies</h3>
|
||||
<p>You can push changes made at a component copy to a main component:</p>
|
||||
<ol>
|
||||
<li>Select a component copy that has changes that override one or more properties of its main component.</li>
|
||||
@@ -118,27 +158,7 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
<img src="/img/components/components-update-shared.webp" alt="Prompt shown to update a main component that is in a shared library" />
|
||||
</figure>
|
||||
|
||||
<h2 id="component-overrides">Component overrides</h2>
|
||||
<p>Main components represent the more generic information of an element in a design system. You will usually need to change specific things (like a text, a color or an icon) in a component while maintaining the inheritance of the rest of it properties. Component overrides allows you to do that in Penpot.</p>
|
||||
<p>Overrides are modifications made in a specific copy that are not in its main component. With overrides you can keep changes at the component copies while maintaining synchronization with the Main component.</p>
|
||||
<figure>
|
||||
<img src="/img/components/components-overrides.webp" alt="Components overrides" />
|
||||
</figure>
|
||||
|
||||
<h3>Reset overrides</h3>
|
||||
<p>Right click and select the option “Reset overrides” at the component menu to get it to the state of the Main component.</p>
|
||||
<figure>
|
||||
<video title="Reset component overrides" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-reset-overrides.webp" height="auto">
|
||||
<source src="/img/components/components-reset-overrides.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
<h2 id="component-detach">Detach component</h2>
|
||||
<p>Detach a component copy to unlink it from its Main component and transform it into a group layer. Press <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd> or right click and select the option “Detach instance” at the component menu.</p>
|
||||
<p>You can also detach components in bulk by selecting several components and performing the same action.</p>
|
||||
|
||||
|
||||
<h2 id="component-swap">Swap components</h2>
|
||||
<h3 id="component-swap">Swap components</h3>
|
||||
<p>Penpot allows you to easily substitute component copies with other component copies.</p>
|
||||
<ol>
|
||||
<li>Select a component <strong>copy</strong>. You can not swap main components.</li>
|
||||
@@ -153,21 +173,166 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
|
||||
</figure>
|
||||
|
||||
|
||||
<h2 id="component-annotate">Annotate components</h2>
|
||||
<p>You can add text annotations to main components. The annotations are shown in every component copy. It is extremely useful to attach specifications that can be read at each component copy.</p>
|
||||
|
||||
<h2 id="component-variants">Component Variants</h2>
|
||||
<p>Variants allow you to group similar components, such as buttons, icons, or toggles, into a single, customizable component. Rather than navigating through separate components for every possible state, size, or style, you can manage them all from one unified component using clearly defined properties.</p>
|
||||
<p>Imagine a single button component that can switch between primary and secondary styles, active and disabled states, and small to large sizes. Useful, right? That’s the power of Variants.</p>
|
||||
|
||||
<h3 id="component-variants-why-are-variants-important">Why are Variants Important?</h3>
|
||||
<ul>
|
||||
<li><strong>Cleaner libraries</strong><br>
|
||||
Keep related designs organized in the Design viewport, Layers panel, and swap menu. Variants streamline your components into tidy, manageable sets, allowing you to retain overrides when switching between them.
|
||||
</li>
|
||||
<li><strong>Faster design workflows</strong><br>
|
||||
Make it easier to find and select the right version by quickly switching between states or styles using simple property controls.
|
||||
</li>
|
||||
<li><strong>Better team collaboration</strong><br>
|
||||
With variants, you can match the way states are handled in code, helping designers and developers stay in sync, fostering better collaboration between design and development teams.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<figure>
|
||||
<video title="Annotating components at Penpot" muted="" playsinline="" controls="" width="auto" poster="/img/components/components-annotation.webp" height="auto">
|
||||
<source src="/img/components/components-annotation.mp4" type="video/mp4">
|
||||
</video>
|
||||
<iframe
|
||||
width="672px"
|
||||
height="378px"
|
||||
src="https://www.youtube.com/embed/3iWc-dwjA30?start=6"
|
||||
title="Penpot Variants Demo"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
<figcaption>Penpot – Variants sneak peek</figcaption>
|
||||
</figure>
|
||||
|
||||
<p>The annotations are also shown at the <a href="/user-guide/inspect">Inspect tab</a>, as another option to improve communication between designers and developers.</p>
|
||||
<h3 id="component-understanding-variants-properties-and-values">Understanding variants: properties and values</h3>
|
||||
<p>A component’s variants are organized by properties and their values.</p>
|
||||
<ul>
|
||||
<li><strong>Properties</strong> define the dimensions that distinguish your variants (for example: <em>Color</em>, <em>Size</em>, <em>State</em>).</li>
|
||||
<li><strong>Values</strong> are the specific options within a property (for example: <em>Primary/Secondary</em>, <em>Small/Large, Default/Hover/Pressed</em>)</li>
|
||||
</ul>
|
||||
<p>Each variant is simply one unique combination of values across all properties (for example, <code class="language-js">Color=Primary + Size=Small + State=Hover</code>).</p>
|
||||
<p>Variants must have at least one property, and property values should be kept consistent to make switching predictable and to preserve overrides across connected layers.</p>
|
||||
|
||||
<h3 id="component-create-and-modify-variants">Create and modify variants</h3>
|
||||
|
||||
<h4 id="component-create-variants">Create variants</h4>
|
||||
<p>You can create variants from an existing component or from another variant:</p>
|
||||
<ul>
|
||||
<li><strong>From a component:</strong> Press Ctrl + K or right-click and select the menu option <strong>Create variant</strong>.</li>
|
||||
<li><strong>From a variant:</strong> Select the variant and press Ctrl + K or right-click and select the menu option <strong>Create variant</strong>.</li>
|
||||
<li><strong>By dragging:</strong> Drag a main component into an existing component with variants to add it as a new variant.</li>
|
||||
<li><strong>From the Design tab</strong> (right sidebar): Select a component or a variant, open the context menu next to the component name and select the menu option <strong>Create variant</strong>.</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/components/components-annotations-inspect.webp" alt="Annotations at inspect tab" />
|
||||
<img src="/img/variants/01-variants-create.webp" alt="Variants creation button" />
|
||||
</figure>
|
||||
<p><strong>When a variant is created:</strong></p>
|
||||
<ul>
|
||||
<li>It appears next to the original in a dedicated variant area (by default in horizontal flex layout).</li>
|
||||
<li>Shared layers between variants are automatically connected (<a href="#component-understanding-overrides">connection conditions</a>) so that overrides can be preserved.</li>
|
||||
<li>Variants are named using their property values (e.g., <em>Primary / Hover</em>).</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/variants/02-variants-created.webp" alt="Variant created" />
|
||||
</figure>
|
||||
|
||||
<h2 id="component-main-components-page">Main components page</h2>
|
||||
<p>If you find a page at a file called "Main components" this will probably mean that the file had assets with the previous components system and has been migrated to the current components system. The previous system didn't have the components as layers at the design file, only at the assets library, so when migrating a file to the new version Penpot automatically creates a page where to place all the components, grouping them using the library groups structure.</p>
|
||||
<h4 id="component-manage-variant-properties">Manage variant properties</h4>
|
||||
<p>Properties are key to defining and differentiating your variants. They appear in the Design tab when a variant or component with variants is selected.</p>
|
||||
<figure>
|
||||
<img src="/img/components/components-page-main.webp" alt="Main components page" />
|
||||
<img src="/img/variants/03-variants-property-add.webp" alt="Add variant property" />
|
||||
</figure>
|
||||
<h5>Add new properties</h5>
|
||||
<ul>
|
||||
<li><strong>From the Design tab:</strong> When the component or one of its variants is selected, you can add a new property via a menu. This property will be added to all existing variants with a default value (e.g., <em>Value 1</em>).</li>
|
||||
<li><strong>From the Layers panel:</strong> using the formula <code class="language-js">[property_name]=[value]</code>.</li>
|
||||
</ul>
|
||||
|
||||
<h5>Edit properties</h5>
|
||||
<ul>
|
||||
<li><strong>From the Design tab:</strong> Select a component or a variant, then click on the property name to edit its name and/or value.</li>
|
||||
<li><strong>From the Layers panel:</strong> using the formula <code class="language-js">[property_name]=[value]</code>.</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/variants/04-variants-properties-edit.webp" alt="Edit variant property" />
|
||||
</figure>
|
||||
|
||||
<h5>Delete properties</h5>
|
||||
<ul>
|
||||
<li><strong>From the Design tab:</strong> Select the main component (not an individual variant) and press the minus button next to the property.</li>
|
||||
<li><strong>From the Layers panel:</strong> You can delete a property by editing the names of all variants so that none of them contain that property in their formula.</li>
|
||||
</ul>
|
||||
<p class="advice">Variants must have at least one property. You can’t delete the last one.</p>
|
||||
<p>When <strong>multiple variants are selected</strong>, the Design tab will show all their properties and values. If a property has different values across the selected variants, it will display “Mixed,” allowing you to override them collectively.</p>
|
||||
|
||||
<h4 id="component-delete-variants">Delete Variants</h4>
|
||||
<ul>
|
||||
<li>Select the variant, press right-click, and select the menu option <strong>Delete</strong>.</li>
|
||||
<li><strong>Dragging</strong> a variant outside its component turns it into an independent component instead of deleting it.</li>
|
||||
</ul>
|
||||
<p class="advice">If you delete the last variant, the entire component is removed.</p>
|
||||
|
||||
<h4 id="component-restore-variants">Restore Variants</h4>
|
||||
<p>If you have a copy of a variant whose original was deleted, you can restore it:</p>
|
||||
<ul>
|
||||
<li>Select the variant copy, press right-click, and select the menu option <strong>Restore variant</strong> (will show if the main component still exists).</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="component-use-variants">Use variants</h3>
|
||||
<p>Once you have created your variants, you can place a copy of a component with variants into your design and then switch between its different versions.</p>
|
||||
|
||||
<h4 id="component-from-the-assets-tab">From the Assets tab</h4>
|
||||
<p>Drag and drop a component with variants from the Assets tab onto the design viewport, just like you would with any other component. Once placed, you can then use its properties in the Design tab to switch to the desired variant.</p>
|
||||
|
||||
<h4 id="component-from-the-design-tab">From the Design tab</h4>
|
||||
<p>When a variant is selected:</p>
|
||||
<ul>
|
||||
<li>You’ll see its properties and values.</li>
|
||||
<li>Change one or more property values to switch to another variant.</li>
|
||||
<li>If your chosen combination doesn’t exist, Penpot will suggest the closest match.</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/variants/05-variants-use.webp" alt="Using variants" />
|
||||
</figure>
|
||||
|
||||
<h4 id="component-understanding-overrides">Understanding overrides</h4>
|
||||
<p>A key benefit of variants is the ability to <strong>preserve overrides when you switch between them</strong>. An override is a specific change you make to a component instance that diverges from its original definition (e.g., changing text content or a specific color).</p>
|
||||
<p>Layers between variants are considered connected if they:</p>
|
||||
<ol>
|
||||
<li>Share the <strong>same name</strong>.</li>
|
||||
<li><strong>Are the same type</strong>. Rectangle, ellipse, paths, and boolean operations count as the same type.</li>
|
||||
<li><strong>Have the same hierarchy level.</strong> Groups, boards, and layouts are considered equivalent.</li>
|
||||
</ol>
|
||||
<figure>
|
||||
<img src="/img/variants/variants-connections-conditions.png" alt="Variants connections conditions" />
|
||||
</figure>
|
||||
<p><strong>Example:</strong> If <code class="language-js">Variant 1</code> has a text layer named <em>label</em> with red color, and you change its content to <em>Click here</em> in an instance, then switch to <code class="language-js">Variant 2</code> (which also has a <em>label</em> text layer), the <em>Click here</em> content will be preserved, and <code class="language-js">Variant 2</code>’s color will be applied.</p>
|
||||
<p><strong>Changing any of these</strong> (e.g., renaming or grouping a layer) breaks the connection, but reverting the change will restore it.</p>
|
||||
|
||||
<h4 id="component-bulk-converting-components-to-variants">Bulk converting components to variants</h4>
|
||||
<p>If you already have multiple related components, you can combine them into a single component with variants:</p>
|
||||
<ul>
|
||||
<li><strong>From Assets tab</strong>: Select components in the same group and right-click → <strong>Combine as variants</strong>.</li>
|
||||
<li><strong>From viewport</strong>: Select multiple components → Right-click → <strong>Combine as variants</strong>.</li>
|
||||
<li><strong>From Design tab</strong>: If conditions are met, a Combine as variants button appears on the component card.</li>
|
||||
</ul>
|
||||
<figure>
|
||||
<img src="/img/variants/06-variants-combine.webp" alt="Combining components as variants" />
|
||||
</figure>
|
||||
<p><strong>Conditions:</strong></p>
|
||||
<ul>
|
||||
<li>Components must be on the same page.</li>
|
||||
<li>Components that already have variants cannot be combined.</li>
|
||||
</ul>
|
||||
<p><strong>When combined:</strong></p>
|
||||
<ul>
|
||||
<li>A variant area is created containing all former components.</li>
|
||||
<li>Property names and values are generated from the component names.</li>
|
||||
</ul>
|
||||
|
||||
<h4 id="component-transforming-variants-back-into-components">Transforming Variants Back into Components</h4>
|
||||
<p>To turn a variant into an independent component:</p>
|
||||
<ul>
|
||||
<li>Drag it outside the variant area (Design viewport or Layers panel).</li>
|
||||
<li>Cut and paste it outside the variant area.</li>
|
||||
</ul>
|
||||
<p>The new component’s name includes the original component name and the variant’s property values.</p>
|
||||
@@ -118,7 +118,7 @@ title: 10· Design Tokens
|
||||
<img src="/img/design-tokens/08-tokens-color.webp" alt="Tokens color" />
|
||||
</figure>
|
||||
|
||||
<h3 id="design-tokens-dimensions">Dimensions</h3>
|
||||
<h3 id="design-tokens-dimensions">Dimension</h3>
|
||||
<p>Dimension tokens allow you to define an amount of distance that can be used to set the size, space, radius or position of specific elements within a design.</p>
|
||||
<h4>Applying Dimension Tokens</h4>
|
||||
<p>To apply a dimension token, select the element and choose the token from the list:</p>
|
||||
@@ -205,10 +205,6 @@ title: 10· Design Tokens
|
||||
<h4>Y Position (dimension)</h4>
|
||||
<p>The Y property specifies the position of the element on the Y axis of the canvas.</p>
|
||||
|
||||
<h3 id="design-tokens-font-size">Font Size</h3>
|
||||
<p>Font size tokens allow you to define and standardize font-size values across your design system. These tokens can be applied to the <strong>font-size</strong> property in text layers, ensuring consistent typography throughout your designs.</p>
|
||||
<p class="advice">Font size token values are always computed as <strong>px</strong> (pixels).</p>
|
||||
|
||||
<h3 id="design-tokens-opacity">Opacity</h3>
|
||||
<p>Opacity tokens allow you to define the opacity of a layer, ranging from fully opaque to fully transparent.</p>
|
||||
<p>Opacity tokens can be applied to any design element that supports transparency. You can use any decimal value between 0 and 1 to set varying levels of opacity or you can use any value between 0 and 100 with <strong>`%`</strong> sign at the end of the value. For example, you can use <strong>45%</strong> which would resolve to <strong>.45</strong>.</p>
|
||||
@@ -265,10 +261,168 @@ title: 10· Design Tokens
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Stroke Width</h4>
|
||||
<h3 id="design-tokens-stroke-width">Stroke Width</h3>
|
||||
<p>The stroke width token, also known as the border width token, defines the thickness of a stroke around a design element. It can be applied to boards, groups, rectangles and text elements.</p>
|
||||
|
||||
|
||||
<h3 id="design-tokens-number">Number token</h3>
|
||||
<p>Number tokens define the numeric value of properties that don’t require a unit of measurement.</p>
|
||||
<p>The difference between a number token and a dimension token is that the first one has to be unitless.</p>
|
||||
<p class="advice">The Number Token does not have a default property to apply to, so it can only be applied by right-clicking and selecting the specific property.</p>
|
||||
<p>Number token is especially useful as a reference in other tokens, for math equations (<strong>operands</strong>), to create scales, for example font-size scales, or grid scales.</p>
|
||||
<p>It can also be applied to Line Height –since this property works as a multiplier of the font size– or rotation property.</p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/24-tokens-type-number.webp" alt="Number token applied" />
|
||||
</figure>
|
||||
|
||||
<h3 id="design-tokens-typography">Typography tokens</h3>
|
||||
<p class="advice">Typography tokens can only be applied to a text layer, but not to individual elements inside a text layer.
|
||||
Applying a Typography Token will detach any Typography Style previously applied, and vice versa.</p>
|
||||
<h4>Font Family</h4>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/25-tokens-type-font-family.webp" alt="Font family" />
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/26-tokens-type-font-family-select.webp" alt="Font family selector" />
|
||||
</figure>
|
||||
<p>As in other tokens, Font Family accepts references to other font family tokens.</p>
|
||||
<p>Additionally, you can specify a prioritized list of Font Family names or generic names separated by commas (,), as in CSS. Penpot will use only the first font in the list, but this helps define your font fallbacks so developers can implement them accordingly.</p>
|
||||
<pre>
|
||||
<code class="language-css">
|
||||
font-family: Lucida Console, Courier, monospace
|
||||
</code>
|
||||
</pre>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/27-tokens-type-font-family-edit.webp" alt="Font family edit" />
|
||||
</figure>
|
||||
<p>When writing the string values of a <strong>Font Family Token</strong>, pay close attention to:</p>
|
||||
<ul>
|
||||
<li>Spelling</li>
|
||||
<li>Spacing</li>
|
||||
<li>Punctuation</li>
|
||||
<li>Use of capital letters</li>
|
||||
</ul>
|
||||
<p><strong>Note:</strong> You can quote font family names — especially those that contain spaces or special characters —
|
||||
to follow <strong>CSS best practices</strong> or to align with the conventions used by your development team:
|
||||
</p>
|
||||
<pre>
|
||||
<code class="language-css">
|
||||
font-family: "DM Sans", sans-serif;
|
||||
</code>
|
||||
</pre>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/28-tokens-type-font-family-resolved.webp" alt="Font family resolved" />
|
||||
</figure>
|
||||
<p>If the Font Family does not exist in Penpot, when you apply the token you will see a “Missing font” message in the design panel input:</p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/29-tokens-type-font-family-missing.webp" alt="Font family missing" />
|
||||
</figure>
|
||||
|
||||
|
||||
<h4 id="design-tokens-font-size">Font Size</h4>
|
||||
<p>Font size tokens define the vertical size of glyphs/characters as an individual property. In typography, the letter spacing and line height properties are related to the font size.</p>
|
||||
<p>Font sizes are typically defined using a proportional scale. You can use math operations with references in order to create dynamic typography scales that follow a particular multiplier, like Golden Ratio.</p>
|
||||
<p><strong>Tip:</strong> Use <a href="/user-guide/design-tokens/#design-tokens-number" target="_blank">Number Tokens</a> (unitless token) to create stunning typographic scales though design tokens:</p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/30-tokens-type-font-size-scale.webp" alt="Font size scale" />
|
||||
</figure>
|
||||
<p>Font size is a dimension-type token and should be defined in px (unitless values are computed as px) for now. To follow the DTGC format, in upcoming releases, units will be mandatory and rem units will be allowed.</p>
|
||||
<p>You can use any dimension token as a reference in a font size token. Math operations are also allowed.</p>
|
||||
<p><strong>Tip:</strong> You can use a rounding function to round your resolved values and reduce decimals in math operations, since decimals are not ideal when using px:</p>
|
||||
<p><code class="language-js">roundTo({values}, decimals)</code></p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/31-tokens-type-font-size-function.webp" alt="Font size function" />
|
||||
</figure>
|
||||
|
||||
|
||||
<h4 id="design-tokens-font-weight">Font Weight</h4>
|
||||
<p>Font Weight defines the thickness of each character/glyph in the Font Family. Font Weight design decisions are typically used to communicate visual hierarchy or emphasize text elements.</p>
|
||||
<p>Penpot combines Font Weight and Style as a single property written as a string value and it requires a match to the Font Family it is paired with, since not all font families have the same weight / styles.</p>
|
||||
<p>The Token can be defined with a numeric value (100, 400, 900, etc) or a string name (Bold, Black, Thin, etc), and the font style (Italic), if needed.</p>
|
||||
<p><strong>Note:</strong> Font Family and Font Weight Tokens work as a pair in Penpot. This means you must consider the current Font Family in order to decide the Font Weight you want to use in your designs.</p>
|
||||
<p>This token can be applied to text layers but the result depends on the Font Family in use.</p>
|
||||
<h5>Accepted values</h5>
|
||||
<p>Font Weight Token can be defined in numeric values or string values. Both values are accepted. When applied, a conversion will occur, transforming any string value to its corresponding numeric value:</p>
|
||||
<table border="1" cellpadding="6" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Numeric Value</th>
|
||||
<th>String Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>100</td>
|
||||
<td>Thin, Hairline</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>200</td>
|
||||
<td>Extra Light, ExtraLight, extra-light, Ultra Light, UltraLight, ultra-light, extraleicht</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>300</td>
|
||||
<td>Light, leicht</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>400</td>
|
||||
<td>Regular, Normal, Book, buch</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>500</td>
|
||||
<td>Medium, kraeftig, kräftig</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>600</td>
|
||||
<td>Semibold, SemiBold, Semi Bold, semi-bold, DemiBold, Demi Bold, demi-bold, halbfett</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>700</td>
|
||||
<td>Bold, dreiviertelfett</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>800</td>
|
||||
<td>ExtraBold, Extra Bold, extra-bold, ultra-bold, UltraBold, Ultra Bold, fett</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>900</td>
|
||||
<td>Black, Heavy, extrafett</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>950</td>
|
||||
<td>Extra Black, extra-black, Ultra Black, ultra-black</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong>Note:</strong> values are case insensitive so for example <code>Regular</code> and <code>regular</code> will both work.</p>
|
||||
|
||||
<p>Any of these values can also include the Font Style <em>Italic</em>, if needed. Some examples of accepted values:</p>
|
||||
|
||||
<pre><code class="language-css">regular
|
||||
Normal Italic
|
||||
700
|
||||
400 italic
|
||||
Bold italic
|
||||
ExtraBold Italic
|
||||
</code></pre>
|
||||
|
||||
<h4 id="design-tokens-font-letter-spacing">Letter Spacing</h4>
|
||||
<p>Letter Spacing, also known as kerning, defines the horizontal distance between individual characters.</p>
|
||||
<p>The default value is 0. In Penpot letter spacing is defined in px. In the token, you can use values in px or any reference to a Dimension / Spacing / Sizing / Letter Spacing Token.</p>
|
||||
<p>This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.</p>
|
||||
|
||||
<h4 id="design-tokens-font-text-case">Text Case</h4>
|
||||
<p>Text Case defines that the system should transform the capitalization of letters in a text element regardless of how they are typed.</p>
|
||||
<p>This property corresponds to <code class="language-css">text-transform</code> in CSS.</p>
|
||||
<p>Accepted values are <code class="language-css">none</code>, <code class="language-css">uppercase</code>, <code class="language-css">lowercase</code> and <code class="language-css">capitalize</code>. It also accepts references to another Text Case token.</p>
|
||||
<p>This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.</p>
|
||||
|
||||
<h4 id="design-tokens-font-text-decoration">Text Decoration</h4>
|
||||
<p>Text Decoration defines an optional line as part of font styling properties, typically used to communicate the visual emphasis of a text.</p>
|
||||
<p>Accepted values are <code class="language-css">none</code>, <code class="language-css">underline</code> and <code class="language-css">strike-through</code>. It also accepts references to another Text Decoration token.</p>
|
||||
<p>This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.</p>
|
||||
|
||||
|
||||
<h2 id="design-tokens-sets">Token Sets</h2>
|
||||
<p>Token Sets allow you to split your tokens up into multiple files in order to create organized groups or collections of tokens. It enables efficient management and customization within design files. For example you can group all your color sets, sizing sets or platform-specific sets. The purpose of tokens sets is to organize them in a way that matches your needs.</p>
|
||||
<figure>
|
||||
@@ -289,7 +443,7 @@ title: 10· Design Tokens
|
||||
<p>When a token set is selected, the tokens within the selected set are displayed on the panel below.</p>
|
||||
|
||||
|
||||
<h3 id="design-tokens-sets-edit">Deleting, Duplicating and Renaming a Token Set</h3>
|
||||
<h3 id="design-tokens-sets-edit">Editing Token Sets</h3>
|
||||
<p>Right-click a token set to perform these quick actions:</p>
|
||||
<ol>
|
||||
<li><strong>Rename</strong>: Give the set a new name and press Enter.</li>
|
||||
@@ -464,12 +618,31 @@ title: 10· Design Tokens
|
||||
<figcaption>Exporting tokens as a single file.</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- Leaving this section as a comment as the feature will be released very soon
|
||||
<h2 id="design-tokens-settings">Tokens settings</h2>
|
||||
|
||||
<h3 id="design-tokens-base-font-size">Base font size</h3>
|
||||
<p>The Base Font Size provides the value for <code class="language-css">1rem</code>.</p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/32-tokens-base-font-size.webp" alt="Tokens base font size" />
|
||||
</figure>
|
||||
<p>This feature not only supports responsive design decisions but also ensures the adaptability of the design, similar to how engineers work in code.</p>
|
||||
<p>When you assign a Token's value in rem units, the property is related to the Base Font Size, which the user of your product or website can adjust.</p>
|
||||
<ul>
|
||||
<li>For example, if the user increases the font size or uses a zoom feature, all design properties defined in <code class="language-css">rem</code> units will respond accordingly.</li>
|
||||
</ul>
|
||||
<p>In contrast, design elements defined in <code class="language-css">pixels</code> will remain the same regardless of the user settings.</p>
|
||||
<p><strong>This feature is only supported on Tokens</strong>. When applying Tokens set in rem to any design element, it will convert the rem units to pixels, taking into account the value of this setting. The default value assumes <code class="language-css">1rem = 16px</code>.</p>
|
||||
<ul>
|
||||
<li><code class="language-css">rem</code> units can be used in all <a href="/user-guide/design-tokens/#design-tokens-dimensions" target="_blank">dimension token</a> types: Dimension, Spacing, Sizing, Border radius, Stroke Width, Font size, letter spacing, and line height.</li>
|
||||
</ul>
|
||||
<p>This value is not shared across files so you can have different values in different files, allowing you to use different rem values with the same Tokens structure.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 id="design-tokens-change-base-font-size">View and change the current base font size setting</h4>
|
||||
<p>Navigate to the Settings modal with the <strong>settings button</strong> on the bottom of the tokens tab:</p>
|
||||
<figure>
|
||||
<img src="/img/design-tokens/33-tokens-settings.webp" alt="Tokens settings" />
|
||||
</figure>
|
||||
<p>Here you can view and change the value.</p>
|
||||
<p>The input accepts values with px and unitless, which will be interpreted as pixels.</p>
|
||||
-->
|
||||
@@ -263,6 +263,11 @@ desc: Get quickstart tips, shortcuts, and tutorials for Penpot! Learn interface
|
||||
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>K</kbd></td>
|
||||
<td style="text-align: center;"><kbd>⌘</kbd><kbd>⇧</kbd><kbd>K</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Create Variant</td>
|
||||
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>K</kbd></td>
|
||||
<td style="text-align: center;"><kbd>⌘</kbd><kbd>K</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Flip horizontal</td>
|
||||
<td style="text-align: center;"><kbd>Ctrl</kbd><kbd>H</kbd></td>
|
||||
|
||||
@@ -1016,12 +1016,6 @@
|
||||
(when swap-opened?
|
||||
[:> component-swap* {:shapes copies}])
|
||||
|
||||
(when (and (not swap-opened?) (not multi))
|
||||
[:> component-annotation* {:id id
|
||||
:shape shape
|
||||
:component component
|
||||
:rerender-fn rerender-fn}])
|
||||
|
||||
(when (and is-variant?
|
||||
(not main-instance?)
|
||||
(not (:deleted component))
|
||||
@@ -1037,6 +1031,12 @@
|
||||
:shapes shapes
|
||||
:data data}])
|
||||
|
||||
(when (and (not swap-opened?) (not multi))
|
||||
[:> component-annotation* {:id id
|
||||
:shape shape
|
||||
:component component
|
||||
:rerender-fn rerender-fn}])
|
||||
|
||||
(when (and multi all-main? (not any-variant?))
|
||||
[:button {:class (stl/css :combine-variant-button)
|
||||
:on-click on-combine-as-variants}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :as c]
|
||||
[app.common.types.token :as ctt]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
@@ -121,10 +122,10 @@
|
||||
(defn validate-resolve-token
|
||||
[token prev-token tokens]
|
||||
(let [token (cond-> token
|
||||
;; When creating a new token we dont have a name yet,
|
||||
;; When creating a new token we dont have a name yet or invalid name,
|
||||
;; but we still want to resolve the value to show in the form.
|
||||
;; So we use a temporary token name that hopefully doesn't clash with any of the users token names
|
||||
(str/empty? (:name token)) (assoc :name "__PENPOT__TOKEN__NAME__PLACEHOLDER__"))
|
||||
(not (sm/valid? ctt/token-name-ref (:name token))) (assoc :name "__PENPOT__TOKEN__NAME__PLACEHOLDER__"))
|
||||
tokens' (cond-> tokens
|
||||
;; Remove previous token when renaming a token
|
||||
(not= (:name token) (:name prev-token))
|
||||
|
||||