diff --git a/backend/deps.edn b/backend/deps.edn index 3d9f7a8353..8955477424 100644 --- a/backend/deps.edn +++ b/backend/deps.edn @@ -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 diff --git a/common/deps.edn b/common/deps.edn index 04dda628b4..f15f313030 100644 --- a/common/deps.edn +++ b/common/deps.edn @@ -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 diff --git a/docs/img/design-tokens/24-tokens-type-number.webp b/docs/img/design-tokens/24-tokens-type-number.webp new file mode 100644 index 0000000000..6f1cdc0c6c Binary files /dev/null and b/docs/img/design-tokens/24-tokens-type-number.webp differ diff --git a/docs/img/design-tokens/25-tokens-type-font-family.webp b/docs/img/design-tokens/25-tokens-type-font-family.webp new file mode 100644 index 0000000000..89fdb1dd06 Binary files /dev/null and b/docs/img/design-tokens/25-tokens-type-font-family.webp differ diff --git a/docs/img/design-tokens/26-tokens-type-font-family-select.webp b/docs/img/design-tokens/26-tokens-type-font-family-select.webp new file mode 100644 index 0000000000..3f49865fbc Binary files /dev/null and b/docs/img/design-tokens/26-tokens-type-font-family-select.webp differ diff --git a/docs/img/design-tokens/27-tokens-type-font-family-edit.webp b/docs/img/design-tokens/27-tokens-type-font-family-edit.webp new file mode 100644 index 0000000000..f0be58f463 Binary files /dev/null and b/docs/img/design-tokens/27-tokens-type-font-family-edit.webp differ diff --git a/docs/img/design-tokens/28-tokens-type-font-family-resolved.webp b/docs/img/design-tokens/28-tokens-type-font-family-resolved.webp new file mode 100644 index 0000000000..d524ee6e1a Binary files /dev/null and b/docs/img/design-tokens/28-tokens-type-font-family-resolved.webp differ diff --git a/docs/img/design-tokens/29-tokens-type-font-family-missing.webp b/docs/img/design-tokens/29-tokens-type-font-family-missing.webp new file mode 100644 index 0000000000..523ba4ac13 Binary files /dev/null and b/docs/img/design-tokens/29-tokens-type-font-family-missing.webp differ diff --git a/docs/img/design-tokens/30-tokens-type-font-size-scale.webp b/docs/img/design-tokens/30-tokens-type-font-size-scale.webp new file mode 100644 index 0000000000..01ed2fd2e7 Binary files /dev/null and b/docs/img/design-tokens/30-tokens-type-font-size-scale.webp differ diff --git a/docs/img/design-tokens/31-tokens-type-font-size-function.webp b/docs/img/design-tokens/31-tokens-type-font-size-function.webp new file mode 100644 index 0000000000..84bfacd699 Binary files /dev/null and b/docs/img/design-tokens/31-tokens-type-font-size-function.webp differ diff --git a/docs/img/design-tokens/32-tokens-base-font-size.webp b/docs/img/design-tokens/32-tokens-base-font-size.webp new file mode 100644 index 0000000000..b497b359b8 Binary files /dev/null and b/docs/img/design-tokens/32-tokens-base-font-size.webp differ diff --git a/docs/img/design-tokens/33-tokens-settings.webp b/docs/img/design-tokens/33-tokens-settings.webp new file mode 100644 index 0000000000..8b2c957a76 Binary files /dev/null and b/docs/img/design-tokens/33-tokens-settings.webp differ diff --git a/docs/img/variants/01-variants-create.webp b/docs/img/variants/01-variants-create.webp new file mode 100644 index 0000000000..fe757e60c2 Binary files /dev/null and b/docs/img/variants/01-variants-create.webp differ diff --git a/docs/img/variants/02-variants-created.webp b/docs/img/variants/02-variants-created.webp new file mode 100644 index 0000000000..a11b3abf1d Binary files /dev/null and b/docs/img/variants/02-variants-created.webp differ diff --git a/docs/img/variants/03-variants-property-add.webp b/docs/img/variants/03-variants-property-add.webp new file mode 100644 index 0000000000..c41f78e445 Binary files /dev/null and b/docs/img/variants/03-variants-property-add.webp differ diff --git a/docs/img/variants/04-variants-properties-edit.webp b/docs/img/variants/04-variants-properties-edit.webp new file mode 100644 index 0000000000..f71d194135 Binary files /dev/null and b/docs/img/variants/04-variants-properties-edit.webp differ diff --git a/docs/img/variants/05-variants-use.webp b/docs/img/variants/05-variants-use.webp new file mode 100644 index 0000000000..51eaf1c1e2 Binary files /dev/null and b/docs/img/variants/05-variants-use.webp differ diff --git a/docs/img/variants/06-variants-combine.webp b/docs/img/variants/06-variants-combine.webp new file mode 100644 index 0000000000..fa4103568e Binary files /dev/null and b/docs/img/variants/06-variants-combine.webp differ diff --git a/docs/img/variants/variants-connections-conditions.png b/docs/img/variants/variants-connections-conditions.png new file mode 100644 index 0000000000..1cb504e19b Binary files /dev/null and b/docs/img/variants/variants-connections-conditions.png differ diff --git a/docs/user-guide/components/index.njk b/docs/user-guide/components/index.njk index 6aa8ba78c6..ecd68c7ab8 100644 --- a/docs/user-guide/components/index.njk +++ b/docs/user-guide/components/index.njk @@ -7,19 +7,20 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c

Speed your workflow with the reusable power of components.

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.

-

A component has two parts:

+

Components basics

+

A component consists of two elements:

Components main and copy
Mains and copies have different icons. Mains also have a title header at the viewport.

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.

-

Creating components

-

Create a component

+

Create components

+

Create a component

  1. Select an object or a group of them.
  2. Press Ctrl + K or right click and select the option “Create component” at the object menu.
  3. @@ -30,10 +31,10 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c -

    Duplicate a component

    +

    Duplicate a component

    You can duplicate a component the same way you can duplicate any other layer. When duplicating a component, you are creating a component copy that will be linked to its main component.

    -

    Duplicate as main component

    +

    Duplicate as main component

    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".

    -

    Delete a main component

    +

    Delete a main component

    You can delete main components and its copies anytime the same way you can delete any other layer.

    Deleting a main component at the viewport means deleting it at the assets library and viceversa, so be careful!

    @@ -50,7 +51,7 @@ desc: Streamline your design workflow with Penpot's Components guide! Learn to c
    -

    Restore a main component

    +

    Restore a main component

    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:

    -

    Stroke Width

    +

    Stroke Width

    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.

    +

    Number token

    +

    Number tokens define the numeric value of properties that don’t require a unit of measurement.

    +

    The difference between a number token and a dimension token is that the first one has to be unitless.

    +

    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.

    +

    Number token is especially useful as a reference in other tokens, for math equations (operands), to create scales, for example font-size scales, or grid scales.

    +

    It can also be applied to Line Height –since this property works as a multiplier of the font size– or rotation property.

    +
    + Number token applied +
    + +

    Typography tokens

    +

    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.

    +

    Font Family

    +
    + Font family +
    +
    + Font family selector +
    +

    As in other tokens, Font Family accepts references to other font family tokens.

    +

    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.

    +
    +  
    +  font-family: Lucida Console, Courier, monospace
    +  
    +
    +
    + Font family edit +
    +

    When writing the string values of a Font Family Token, pay close attention to:

    + +

    Note: You can quote font family names — especially those that contain spaces or special characters — + to follow CSS best practices or to align with the conventions used by your development team: +

    +
    +  
    +  font-family: "DM Sans", sans-serif;
    +  
    +
    +
    + Font family resolved +
    +

    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:

    +
    + Font family missing +
    + + +

    Font Size

    +

    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.

    +

    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.

    +

    Tip: Use Number Tokens (unitless token) to create stunning typographic scales though design tokens:

    +
    + Font size scale +
    +

    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.

    +

    You can use any dimension token as a reference in a font size token. Math operations are also allowed.

    +

    Tip: 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:

    +

    roundTo({values}, decimals)

    +
    + Font size function +
    + + +

    Font Weight

    +

    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.

    +

    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.

    +

    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.

    +

    Note: 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.

    +

    This token can be applied to text layers but the result depends on the Font Family in use.

    +
    Accepted values
    +

    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:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Numeric ValueString Value
    100Thin, Hairline
    200Extra Light, ExtraLight, extra-light, Ultra Light, UltraLight, ultra-light, extraleicht
    300Light, leicht
    400Regular, Normal, Book, buch
    500Medium, kraeftig, kräftig
    600Semibold, SemiBold, Semi Bold, semi-bold, DemiBold, Demi Bold, demi-bold, halbfett
    700Bold, dreiviertelfett
    800ExtraBold, Extra Bold, extra-bold, ultra-bold, UltraBold, Ultra Bold, fett
    900Black, Heavy, extrafett
    950Extra Black, extra-black, Ultra Black, ultra-black
    + +

    Note: values are case insensitive so for example Regular and regular will both work.

    + +

    Any of these values can also include the Font Style Italic, if needed. Some examples of accepted values:

    + +
    regular
    +Normal Italic
    +700
    +400 italic
    +Bold italic
    +ExtraBold Italic
    +
    + +

    Letter Spacing

    +

    Letter Spacing, also known as kerning, defines the horizontal distance between individual characters.

    +

    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.

    +

    This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.

    + +

    Text Case

    +

    Text Case defines that the system should transform the capitalization of letters in a text element regardless of how they are typed.

    +

    This property corresponds to text-transform in CSS.

    +

    Accepted values are none, uppercase, lowercase and capitalize. It also accepts references to another Text Case token.

    +

    This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.

    + +

    Text Decoration

    +

    Text Decoration defines an optional line as part of font styling properties, typically used to communicate the visual emphasis of a text.

    +

    Accepted values are none, underline and strike-through. It also accepts references to another Text Decoration token.

    +

    This token can be applied directly to a text element or be used as a reference in a Typography Composite Token.

    + +

    Token Sets

    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.

    @@ -289,7 +443,7 @@ title: 10· Design Tokens

    When a token set is selected, the tokens within the selected set are displayed on the panel below.

    -

    Deleting, Duplicating and Renaming a Token Set

    +

    Editing Token Sets

    Right-click a token set to perform these quick actions:

    1. Rename: Give the set a new name and press Enter.
    2. @@ -464,12 +618,31 @@ title: 10· Design Tokens
      Exporting tokens as a single file.
    + \ No newline at end of file diff --git a/docs/user-guide/introduction/shortcuts.njk b/docs/user-guide/introduction/shortcuts.njk index 00fdadf777..0f9a317bdd 100644 --- a/docs/user-guide/introduction/shortcuts.njk +++ b/docs/user-guide/introduction/shortcuts.njk @@ -263,6 +263,11 @@ desc: Get quickstart tips, shortcuts, and tutorials for Penpot! Learn interface CtrlShiftK K + + Create Variant + CtrlK + K + Flip horizontal CtrlH diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 6cc9da2aa8..087f62e74a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -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} diff --git a/frontend/src/app/main/ui/workspace/tokens/management/create/form.cljs b/frontend/src/app/main/ui/workspace/tokens/management/create/form.cljs index 4095638147..3c83ac9c72 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/create/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/create/form.cljs @@ -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))