Updates

Follow @plasmicapp on Twitter to stay up to date with our progress.

2020-09-29 Publishing, importing, and versioning projects

Publishing project versions

When working on Plasmic projects, it can be hard to keep track of all your changes over time. When your changes impact a production codebase, the ability to explicitly choose when you want to publish changes, reproduce historical snapshots, document the evolution of a design, and integrate with the codebase’s version control—these are all requirements for any tool that expects to fit within existing workflows.

We’re excited to introduce versioning into Plasmic! With project versions, you can now save snapshots of Plasmic projects as published versions. Each of these versions is visible in a navigable version history, giving you the ability to view and restore previous versions.

With project versions, we are laying the foundation for many more capabilities, including:

  • Cross-project imports: import assets from other projects to use in your designs.
  • Versioned sync: when syncing to code, you can specify which versions of each project you want.

Cross-project imports

We’ve made it even easier to share your work with others, using cross-project imports. Often, users want to be able to use components from another project, without having to maintain their own copy—for instance, the same design system may be reused across many projects. Simply copying components between projects quickly leads to inconsistencies that are difficult to replicate and keep in sync.

With cross-project imports, you can now publish a project (such as a design system) that can be used in any number of downstream projects. When you import another project, its components, tokens, mixins, and images show up in your assets panel and can be directly used in your designs.

Versioning helps isolate in-progress changes without affecting downstream projects. For example, maintainers of a design system project can continue to iterate on the design system, while these changes are not exposed to downstream projects importing the design system until the maintainer chooses to publish a new version. Downstream projects are notified when new versions are available, and also have the choice on when to upgrade to the new imported version.

Check out the documentation for more details on how to use imports.

Versioned sync

Currently, when you sync code from the Studio into your local codebase, the generated code always reflects the very latest edits made in Studio. This is often simplest to start with, and it keeps your code tightly in sync with your design.

However, as a project grows and more team members collaborate on a project, you may want greater control over what is considered ready for syncing vs. work-in-progress. Additionally, you may want to distinguish between major and minor design changes (such as styling changes )based on whether they can require any code changes.

Project versions come again to the rescue! You can now specify a semantic version range in plasmic.json to sync only published project versions to code (rather than any latest edits). Plasmic now uses a separate plasmic.lock file to track the specific version that is currently synced into the codebase.

Semantic version numbers are automatically computed by Plasmic when publishing a project. They’re based on your Studio edits and whether they can require any code changes—whether the generated component interfaces are backward compatible.

Check out the documentation for more details on how to use versioned sync.

And more

  • You can now right-click on your style controls in the right panel to extract style settings into spacing tokens.
  • You can now specify negative margins and fractional dimension values.
  • As usual, lots of bug fixes and performance improvements — please keep the bug reports coming!

2020-09-22 Plume component system, component explorer, more design tokens

We’re hiring for engineering roles! Join us in shaping the future of how software is created. Learn more.

Introducing the Plume component system

Plasmic makes it easy for you to design your components in a powerful UI, generate presentational React components, attach behavior and data in code, and ship it to production. This division of labor, where Plasmic controls how components look, and developers control how components work, makes it possible to build any component you want with any behavior you need using Plasmic.

But defining how components work is not always straightforward; even building a humble button, with the right pressing, hovering, and focusing behavior, can get quite complicated. Building a library of components for your design system is a huge undertaking if you care about getting all the subtle interaction and accessibility right. Unsurprisingly, teams often opt to theme an existing component library instead, crossing their fingers that their library of choice supports the variants and behaviors that they want, and has all the right hooks for customizing how they look.

What if you can design your components exactly the way you want, and easily add in all the interactivity and accessibility that you expect from a first-class component library?

Today, we’re introducing a preview for the Plume Component System. It is a set of React hooks, built on top of the great React-Aria framework, that makes it easy for you to turn your Plasmic designs into functioning and accessible React components! You just have to:

  1. Design the component in Plasmic.
  2. Generate the presentational React code as usual.
  3. Use Plume React hooks to bring your design to life.
  4. Use your resulting Plume components in your application!

Plume is not a specific set of pre-designed components you can use, or even a set of pre-built components that you can theme. You have almost total control over how your component looks, what variants are supported, what information is displayed, and how it behaves. It is a new way to build a custom component library from scratch.

Today, Plume supports building Button, Checkbox, Radio, Select, Slider, Switch, and TextField. We have plans to add more components, and to build tighter integration between Plume and the Plasmic editor. And we are looking for feedback—please take a look at the docs, try it out, and tell us what components are missing for you, and how we can make this better!

CodeSandbox component explorer

We’ve just made your CodeSandbox more useful! Now when you export to CodeSandbox, you’ll see a panel on the right for toggling the different component variants. Each component now also lives at its own route, so you can send links directly to a specific component.

With this new component explorer, you can quickly let anyone interact and play with your components outside of Plasmic.

More design tokens

We’ve streamlined using spacing tokens in Plasmic. Now you can easily create, edit, and select spacing tokens from style inputs on the right. You’ll also see the full name and value on hover.

We’ve also added brand-new token types for font sizes, line heights, and opacity. These are numeric token types that go beyond spacing tokens.

And more

  • When importing things from Figma with drop shadows, we more correctly detect and use filter: drop-shadow instead of box-shadow.
  • You can now drag images and components from the left panel to the canvas, and also drag to reorder them by using a new drag handle when you hover over each item.
  • As usual, lots of bug fixes and performance improvements — please keep the bug reports coming!

2020-09-01 Tue: Spacing tokens, new insert menu, simpler blackbox code

Spacing tokens

We’re excited to announce that Plasmic now supports spacing tokens!

Plasmic has always supported both:

  • Color tokens, which can be used for any color styles (backgrounds, text colors, border colors, shadow colors, etc.), and
  • Mixins, which are reusable bundles of any combination of styles, from typography to layout to shadows.

Now with spacing tokens, you can define a small set of spacing values which can be flexibly used in any style setting that takes spacing dimensions, including margin, padding, and size.

Like color tokens, spacing tokens can also be defined recursively in terms of other spacing tokens. And of course, they can be used in mixins, so you can more easily create a family of “utility mixins.”

We’d love to hear your thoughts on spacing tokens, and if there are other token types you’d like to see!

New “Add” menu

We’ve streamlined how you can insert things into your artboards with the new “Add” menu!

The new “Add” menu replaces the old “Add to artboard” tab, and provides much better keyboard ergonomics — shortcut key “Q” to bring up the menu, type to filter, arrow keys to select, and enter to insert. You can even “tab” to other insertion options, like wrapping the current selection! Plus, using the “Add” menu no longer requires switching away from the tree panel on the left, so you can always have it in view. As before, you can still drag and drop things directly out of the Add menu onto your artboards as well. You can still view and manage your components — renaming, duplicating, and deleting — in the new “Components” tab on the left.

Please give this a try and let us know what you think!

Significantly simpler generated code for blackbox

We have made the generated code in your “Plasmic*” blackbox files a lot simpler and more readable. The code used to be broken up across many functional components, but now the blackbox code has a single coherent JSX tree.

The net result: it should now be much more pleasant to dig into them to debug your components, or just to see all the JSX tags in your component tree.

And more…

  • CodeSandboxes now have a directory path structure consistent with the CLI. User components that the user edits are generated into src/components, while Plasmic components are generated into src/components/plasmic/.
  • You can now specify pointer-events: none css property in the Effects section.
  • More HTML tags are now available in the tag drop-down in the right panel.
  • As usual, lots of bug fixes and performance improvements — please keep the bug reports coming!

2020-08-11 Tue: New focus states, end-to-end tutorial

New focus states

Showing the proper focus state is a huge part of designing a form control component; it gives users the confidence that they’re editing the right things, and provides important accessibility affordance to keyboard navigation.

We’re introducing a few new focus interaction variants for your components that you can use to make more usable and accessible components.

Focus Within

Some form control components have focusable html elements wrapped in containers. For example, a Textbox component might have a containing div element wrapping an input element and an icon. You’d like to style the component whenever the input element receives focus, but the usual Focused interaction variant isn’t enough—the focus styling needs to go onto the containing div, not just the input element.

For that, we’re introducing Focused Within, which you can apply as a component interaction variant or an element state. This interaction variant will be triggered whenever a descendant element receives focus—perfect for our Textbox container!

Focus Visible

A form control can actually have two subtly different focus states—one where the element is “focused”, and another where the element is focused by you “tabbing” to it via the keyboard. The latter form—where the element is focused, and focused by the keyboard—is called “Focus Visible”, and you can now use it in your Plasmic components as well!

Putting it all together

Here’s a super quick demo of a Textbox component, making use of both “Focus Visible” and “Focus Visible Within” (which is the combination of Focus Visible and Focused Within that you’ve always wanted!). Note how we’re able to make the “input” element transparent, put the styling on the containing div, and still have all the focus styling and behavior that you’d want!

Technical Note

As usual with our interaction variants, we are doing more than “just” generating a CSS rule for :focus-visible or :focus-within; after all, CSS rules only work for style-only changes, and :focus-visible doesn’t even have widespread browser support yet. Instead, Plasmic interaction variants work even when you make non-style changes like text changes or DOM changes. Under the hood, Plasmic defaults to generating just CSS rules whenever that’s sufficient—but when necessary, Plasmic will automatically generate event hooks to implement the interaction variants, so that the generated components look and behave just as you’d expect.

For these new interaction variants, we are using React Aria, an exciting new framework from Adobe that provides awesome accessibility implementations for many different kinds of components without specifying a pre-canned style or DOM structure. We are very excited about what’s possible when you put Plasmic and React Aria together; stay tuned! 🙂

End-to-end tutorial

We just published a new end-to-end beginner tutorial for Plasmic, where you make a very simple app. It features a video that covers designing the app while exploring the core concepts in Plasmic, and a second section that covers implementing the code for the app.

Check out the new end-to-end tutorial

We also just updated the TodoMVC tutorial, which is an intermediate code-only tutorial—the latest version of the component API helps simplify much of the code.

Check out the TodoMVC tutorial

We hope these are helpful. Please let us know your thoughts and what else you’d like to see!

And more

  • Figma import now preserves image transforms/cropping.
  • Figma import now preserves arbitrary SVG masks (?).
  • Figma import now preserves SVG image sizes.
  • Live preview mode now loads much faster, near-instantaneously. It still performs end-to-end codegen, but no longer needs to live-fetch npm dependencies.
  • plasmic sync” now writes to files only once and all together at the end. This both yields more atomic sync operations and prevents webpack-dev-server from becoming confused about updated files.
  • Plasmic* components now have better type safety; you will now get a Typescript error when you pass in unexpected props!
  • As usual, lots of bug fixes and smaller improvements—thanks for all the reports, please keep them coming!

2020-08-04 Tue: Simplified component API, cleaner codegen, overhauled docs

Welcome to all our new users! And thank you to our wonderful initial community for helping us spread the word. We’re thrilled by the volume of signups we received, and by the feedback so far from users in-product.

For those on the waitlist: we’re still working through the list of signups, while trying to stay responsive to users and issues—thank you for bearing with us. We’re excited to start sharing our progress publicly and iterating with your feedback.

Simpler API for blackbox Plasmic* components

We have simplified the API for using Plasmic* components in the blackbox library scheme. Now you can pass variants and slots directly into the Plasmic* components as props, rather than using the variants and args props:

<PlasmicButton
  // Activate variants
  type={props.type}
  size={props.size}
  withIcons={{
    prefix: !!props.prefixIcon,
    suffix: !!props.suffixIcon
  }}

  // Fill in the slots
  children={props.children}
  prefixIcon={props.prefixIcon}
  suffixIcon={props.suffixIcon}

  // Attach overrides; each named element is a prop
  // here, e.g. to add onClick to the element named
  // "root". Same as API before.
  root={{
    onClick: props.onClick
  }}
/> 

Furthermore, wrapper components now by default take the same variant and slot props. These changes culminate in the wrapper components starting out as very simple proxies for the presentational components:

interface ButtonProps extends DefaultButtonProps {}
function Button(props: ButtonProps) {
  return <PlasmicButton {...props} />;
}

Any additional props you pass into the Plasmic* components will now also be interpreted as override props for the root node. So for the above, where we override the onClick prop for the root element, we could also just do:

<PlasmicButton
  // Any prop that's not a named element, not a variant, and not a slot, are 
  // interpreted as an override prop for the root element.
  onClick={props.onClick}
/>

You can find more details on how to use the Plasmic* components on the blackbox documentation page, which has been significantly updated!

Cleaner codegen

plasmic sync now uses your project’s prettier configuration to format the generated code.

Additionally, you can now add arbitrary commands to run at the end of each plasmic sync by adding postSyncCommands into plasmic.json. For example, the following configuration will run yarn lint-fix after each sync.

{
  ...
  "postSyncCommands": ["yarn lint-fix"]
}

These commands will also be invoked after each sync incurred when plasmic watch is running.

The CLI now also removes // plasmic-import comments; you no longer need this annotation in your component files, keeping them clean of generated annotations.

Additionally, for files that don’t require syncing, the CLI will no longer touch or regenerate those files.

Updated development docs

We have significantly updated development documentation all over the place. Highlights include:

Please let us know if there’s anything you’d like to see more documentation of!

And more

  • When you click Share to invite a new user, they can skip the waitlist/survey and directly create an account.
  • More robust SVG import—when you paste or upload an SVG file, we’re no longer as picky about how that SVG file was exported from your vector illustration tool. Anything should Just Work! If you run into issues, please send problematic SVGs our way.
  • Cmd+R now lets you rename the currently-selected element.
  • You can now reorder screen variants to control cascade order. If for instance you have a mobile-first base design, a Tablet screen variant, and a Desktop screen variant, you’ll want to ensure Desktop comes last, so that it overrides any Tablet settings.
  • Images and icons can now be dragged into the canvas area from the Image Assets panel in the left sidebar.
  • Figma import now translates masks in groups to the correct hierarchy to replicate the masking effect in the CSS/DOM:
  • Figma import now deduplicates images and imports them as image assets.
  • Using the Figma plugin from the browser should no longer fail on exporting large designs.
  • Many bug fixes; thanks for bringing them to our attention!

2020-07-10 Fri: Figma integration, layer locking, UI refresh

Figma plugin

We’re thrilled to share that you can now import Figma designs into Plasmic! This means you can use Plasmic to convert your designs into real websites and React apps.

It’s as simple as installing the plugin, pressing Export, and pasting into a Plasmic project:

The importer fully automates the low-level details of converting Figma’s document representation to standard DOM representations. A few highlights:

  • Supports constraints and auto-layout.
  • Translates blend modes.
  • Adapts border styles including centered borders.
  • Handles filter effects like background blur and layer blur.
  • Preserves affine transformations like scales and rotations.
  • Handles all fill types including linear and radial gradients and images.
  • Imports vector and compound shapes as SVGs.
  • Mirrors the original hierarchical structure.
  • Carries over most type styles.

Once in Plasmic, the design could immediately be published as a standalone static website in CodeSandbox or your own codebase. But you will often also want to refactor the design into a more hygienic and lasting structure, suitable for production and for integrating with code. That’s where the rest of Plasmic’s toolset comes in, letting you take advantage of the richer layout, component structure (variants/slots), interactions, style abstractions (mixins/tokens), and element types (such as form elements) for functionality and accessibility. Plasmic’s core philosophy is to enable you to incrementally refine the messy and exploratory into the clean and robust.

Sketch users: We’ve also tested out Sketch documents using this workflow. For now you will need to import your Sketch files into Figma, and from there paste it into Plasmic.

Get the plugin here! We’d love to hear your feedback. There will be much deeper functionality around this workflow to come.

Locking layers

You can now lock layers from the tree on the left! Locking layers means you can no longer interact with them on the canvas; you cannot select them with your mouse, drag them, or drag things into them. You can still select them from the tree and edit their styles from the right panel, however.

Locking a layer also locks its descendants, so you are locking a whole tree at a time. But you can also explicitly unlock a descendant if you do want to interact with a descendant tree. A common example is if you want to lock the “outer chrome” of your application while you’re working on something nested inside.

Minor UI refresh

As you may have noticed, we refreshed the UI a bit!

On the left, we’ve organized the three tabs into more granular icon tabs; this will give us more space to organize all the assets you are building up in your project.

On the right, we’ve capped the component panel to 50% height, so if you have a lot of variants for your component, you can still keep the component panel open without it pushing out the style settings. We’ve also separated out the style settings into different panels to better organize them visually.

Naturally, this new UI is entirely built in Plasmic!

And more

  • Added recursive syncing: plasmic sync --recursive --component Sidebar syncs down the Sidebar component along with all the components it depends on.
  • Added shortcuts Cmd+Alt+Shift+H/V to wrap current selection in a box (horizontal or vertical stack).
  • New artboards are now inserted/pasted at the center where you’re currently scrolled to, or at the first available space to the right. Zoom on new artboards has been adjusted as well.
  • In number inputs, Shift+Up/Down increments/decrements by 10.
  • The expanded arena list (at the top of the left sidebar’s Outline tab) can now be resized.
  • Automatic SVG icon handling now colors strokes as well as fills.
  • The main project list page has a new Get Started section, featuring the latest versions of the Plasmic Levels game and Codegen Quickstart project.
  • We have a new public landing page—made in Plasmic! As is our learning center. Check out the Plasmic project for both.
  • Lots of bug fixes and performance improvements.

2020-06-26 Fri: “Plasmic Levels,” variant refactoring, Direct Edit release

Play “Plasmic Levels”!

We made a new mini-game designed as a Plasmic project, presenting a sequence of UI-crafting tasks for you to try your hand at. This gives you a hands-on way to learn about general concepts like layout and variants, and how to use Plasmic to express these.

Clone this project and give it a play!

Variant management

We’ve made it a lot easier for you to manage the variants you create for your components, so you don’t have to get it right the first try! Now, you can right-click on a variant and:

  • Duplicate the variant, which creates a new variant in the same group, with the same style overrides.
  • Move a variant to a different variant group, if you want to change how you organize your variants.
  • Copy variant settings to another variant, which is especially useful to do across variant types—you can now copy variant settings between interaction variants, normal variants, and even “Element State” variants!

Refactoring tools are key to making it tractable to maintain complex components. We will be working on introducing more such capabilities into Plasmic.

Direct Edit codegen stable

Plasmic offers two flavors of codegen:

  • the Blackbox Library scheme, which provides you with a library of presentational components into which you can pass prop overrides, and
  • the Direct Edit scheme, (which gives you components whose JSX trees you can directly edit to attach props.

We have been iterating on our experimental preview release of Direct Edit, and the dust has settled on our release. We will continue to iterate on and improve the scheme, but we don’t have further significant changes planned for it.

The Plasmic CLI now prompts you for the default codegen scheme you’d like to use when running plasmic init. To get started with this on an existing project, you can edit your plasmic.json to change the codeScheme from “blackbox” to “direct.” To re-sync existing files, run plasmic sync --force-overwrite.

Improved drag and drop in the Tree

You can now drag and drop artboards on the Tree panel to re-order them!

You now also have finer-grained control over your drag-and-drop. You can drag a tree node towards the left to pick exactly which node you want to parent under:

And more

  • Can reorder all object types, including arenas, artboards, components, tokens, mixins. We understand that the more you create, the more you’d want to organize them just so. More to come here!
  • Much better performance as you zoom in and out on the canvas.
  • If you need to update an existing image asset with a new image, you previously can only do so by uploading a new file. Now you can do it by pasting from your clipboard too!
  • At codegen, if you have icons in your project, we no longer sync all icons when you do plasmic sync; instead, we only sync down icons that you are actually using in your components. If you want to sync down all icons in a project, use plasmic sync-icons.
  • Lots of bug fixes!

2020-06-12 Fri: image assets, improved icons, plain-JS code

Image asset manager

We have updated how you can manage your uploaded images and icons. From now on, when you upload a new image or SVG file, we will keep track of it in the Gallery tab, where you can easily drag more of them into the canvas. You can also “update” an image asset, replacing it with a different image, and all references to that image will be updated!

If you have existing images in your project, they have not been touched! You can switch over to using the image assets system at your leisure by re-adding the images into the project.

SVG icons support

When you upload or paste in an SVG file with only one color, we will categorize it as an “icon”. An “icon” is special in that:

  • You can change the fill color of the SVG icon (and you can now reference a color token to do it!)
  • When you put an icon into a slot prop, that icon will be colored according to the slot. So you can now define components with slots that will color its icons, and can even change the icon color depending on different variants! A “primary” Button component, for example, can have a dark background but with white icon color.
  • When you export code, we create a new React component for each icon, which you can instantiate and use in your code, just like other icon libraries like Font Awesome. They will render to SVG elements, with colors set to currentColor and width/height set to 1em, so you can also color and size them with color and font-size css properties as you’d expect!

Plain Javascript codegen

We originally launched with support for just Typescript codegen. Now, the Plasmic CLI can additionally generate Javascript to support pure-JS codebases.

To get started on a JS codebase, we have made plasmic init automatically guess your project language (based on whether a tsconfig.json is present) and confirm with you. You can a also set code.lang to "js" in plasmic.json. Afterward, running plasmic sync will generate components as JSX files in ESnext.

3-minute quickstart

If you are looking for a succinct guide to try out Plasmic’s end-to-end workflow, we now have a small quickstart project to provide just that. We walk you through the few simple steps it takes to sync down a single component into your own codebase. Clone this project and try it out!

And more

  • The Direct Edit codegen scheme now uses sequential numeric IDs on unnamed elements for aesthetically cleaner and more readable JSX. The scheme continues to receive fixes and improvements.
  • We now publish the react-web runtime as ES5 code so that it works with more projects and bundlers.
  • plasmic init now interactively prompts you for options such as file placement and project language.

2020-06-05 Fri: directly editable plain-React codegen

Directly editable plain-React codegen (experimental!)

Plasmic has always aimed to support multiple flavors of codegen, even within a single target platform (React), to accommodate a spectrum of developer preferences. We initially launched with a “Blackbox Library” codegen scheme—the philosophy of this approach is to let you treat your generated code like any other library dependency you pull into your project, so that you can just import and use it as a presentational component.

We now have added a “Direct Edit” codegen scheme, which generates “plain React code” (i.e. a JSX tree) that you as a developer can directly edit. When you re-sync new changes from Plasmic, we preserve your edits. The philosophy is that for components with complex compositions and heavy use of logic and props, you may prefer being able to see and manipulate the JSX.

To support this, we have a parser and rewriter that effectively perform a JSX/TSX-aware rebase of your developer edits on top of the latest generated presentational code. As a developer, you can freely wire up your props to the various components directly in the JSX tree, as well as add, remove, wrap, and replace nodes, and furthermore wrap them in expressions, conditionals, loops, IIFEs, etc. A 3-way diff leverages Plasmic revision history to allow us to auto-merge most concurrent changes, while drawing attention to potential conflicts with conventional conflict markers.

Both Direct Edit and Blackbox Library codegen schemes share similar flexibility and expressivity, but differ primarily in their interface. You can now also mix and match these in your codebase, for instance if only certain components should use Direct Edit (more on this below). Not all possible edits or refactorings to the component file are allowed in the Direct Edit scheme, so we plan to provide a static linting tool to verify that your edits are “within bounds,” and over time increase the scope of what it can handle.

This is an experimental preview release—you can play with Direct Edit codegen immediately (and we would love to hear your feedback!), but there are some known limitations we are working on, and generally we will be making further improvements to this scheme before declaring it stable. You can try out the scheme with our CodeSandbox integration or on your local codebase using our CLI (see below).

Check out some code examples below to get a sense of how the Direct Edit scheme works. We will be updating the Plasmic Developer Guide with more complete documentation.

Code examples

Take this Button component as an example. Plasmic generates a plain JSX tree in the Button.tsx.

function Button(props: ButtonProps) {
  const variants: PlasmicButton__VariantsArgs = {};
  const args: PlasmicButton__ArgsType = {};
  const rh = new PlasmicButton__RenderHelper(variants, args, props.className);
  // plasmic-managed-jsx/30
  return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );
}

Note that Plasmic embeds the entire JSX tree right below the *// plasmic-managed-jsx/30* comment line. This line is critical for Plasmic to perform the code merge—do not change or remove it. After you update the Button component in Plasmic studio and sync the code again, Plasmic will search for the // plasmic-managed-jsx/... line, and merge the JSX tree below it with the updated design.

Plasmic currently preserves the following types of edits.

Adding attributes to elements, such as event handlers:

  return (
    <button className={rh.clsRoot()} onClick={props.onClick}>      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );

Overwriting default props:

  return (
    <button className={rh.clsRoot()}>
      <div className={rh.clsImg()} {...rh.propsImg()} src={...} />      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );

Changing tags:

  return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <span className={rh.clsBox()}>Click Me</span>    </button>
  );

Editing className—you can change the value of className however you want, as long as it retains the rh.clsXXX() function call:

  return (
    <button className={[rh.clsRoot(), "myClass1"].join(" ")}>      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );

Wrapping an existing element in another element:

  return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <FancyTooltip title="...">        <div className={rh.clsBox()}>Click Me</div>
      </FancyTooltip>     </button>
  );

Wrapping elements in expressions, such as conditionals, loops, and IIFEs. This can be useful to achieve type safety or repetition:

interface ButtonProps {
  ...
  imgId?: string;
}
function makeImageUrl(imgId: string) {
  return `https://www.images.com/${imgId}`;
}

function Button(...) {
  ...
  return (
    <button className={rh.clsRoot()}>
      {props.imgId && (        <img          className={rh.clsImg()}          {...rh.propsImg()}          src={makeImageUrl(props.imgId)}        />      )}      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );

  // Or: change the image element to a list of images.

  return (
    <button className={rh.clsRoot()}>
      {props.imgIds?.map(imgId =>        <img          key={imgId}          className={rh.clsImg()}          {...rh.propsImg()}          src={makeImageUrl(imgId)}        />      )}      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );
}

Adding elements:

  return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Click Me</div>
      <img className="left-icon" src={...}/>          </button>
  );

Deleting elements:

  return (
    <button className={rh.clsRoot()}>
      <div className={rh.clsBox()}>Click Me</div>
    </button>
  );

Limitations

Here are some edits that are not currently preserved well by Plasmic.

Wrapping multiple Plasmic generated elements as siblings in a container. In this case, only the first wrapped Plasmic generated element will receive updates from Plasmic studio. For example, suppose we wrapped the img and div of Button as follows.

  return (
    <button className={rh.clsRoot()}>
      <div>
        <img className={rh.clsImg()} {...rh.propsImg()} />
        <div className={rh.clsBox()}>Click Me</div>
      </div>
    </button>
  );

If, in Plasmic studio, we rename the img node to leftIcon, and changed text from Click Me to Hello World, the code after merging will be:

  return (
    <button className={rh.clsRoot()}>
      <div>
        <img className={rh.clsLeftIcon()} {...rh.propsLeftIcon()} />
        <div className={rh.clsBox()}>Click Me</div>
      </div>
    </button>
  );

Editing string literals. Suppose we changed text from Click Me to Hello World in code:

 return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Hello World</div>
    </button>
  );

Then after merge:

  return (
    <button className={rh.clsRoot()}>
      <img className={rh.clsImg()} {...rh.propsImg()} />
      <div className={rh.clsBox()}>Hello WorldClick Me</div>
    </button>
  );

Workaround: change the string literal in Plasmic studio!

Edits to unnamed nodes in code could be lost upon code merge if the design in Plasmic is changed in certain ways. We are working toward a solution, but in general we recommend explicitly naming nodes in Plasmic Studio that you plan to edit in code.

Plasmic CLI now supports “direct” scheme

The plasmic CLI now supports the Direct Edit codegen scheme. To start using it, simply edit your plasmic.json to change "scheme" from "blackbox" (the default) to "direct". This makes all new components sync using the Direct Edit scheme.

The CLI also now supports per-component codegen scheme selection. You can now edit plasmic.json to have some components in your codebase using the "blackbox" scheme and others using the direct scheme.

{
  "platform": "react",
  "code": {
    "lang": "ts",
    "scheme": "blackbox"
  },
  ...
  "projects": [
    {
      ...
      "components": [
        {
          "id": "ERc2O74z2Z",
          "name": "ShareDialog",
          ...
          "scheme": "direct"
        },
        ...

To change the scheme of a component you already synced, change the component scheme in plasmic.json, and run plasmic sync --force-overwrite. Note that this will overwrite and discard any current version of your component file!

Local fonts

Plasmic provides common system fonts and all Google Web Fonts out-of-the-box. Starting today, you can additionally use any locally installed fonts in Plasmic!

To get started, switch to the Assets tab in the left sidebar, and at the bottom you’ll find the ability to register new fonts.

Note: within Plasmic, these fonts will only appear correctly to users who have the font installed. We show a warning icon next to user-managed fonts that are missing from the current browser.

When syncing components to a codebase, please make sure you provide the font file elsewhere in your application.

And more

  • Previously all of our documentation and educational content was on Dropbox Paper. We have moved it to a shiny new website at https://plasmic.app/learn. Let us know what other educational resources would be helpful!
  • We have a new Codegen button in the top toolbar. This guides you through getting your designs from Plasmic into your own local codebase in a few simple steps.
  • You can now create multiple CodeSandboxes for a Plasmic project, one per codegen scheme. This lets you easily play with the new Direct Edit codegen scheme, for instance.
  • Added more mouse cursor types, including not-allowed and grab cursors.

2020-05-29 Fri: measurement guides, better “live” mode

Measurement guides

We’ve added the ability for you to quickly measure the distance between any two objects—components, boxes, text, and the artboard.

To start using this tool, select one object. Then, while holding down [Option] or [Alt], hover over anything else to measure the distance to the first object.

As an added bonus, if you hold [Shift]+[Alt/Option], we’ll also show measurement guides to your mouse pointer’s current position!

We’re continuing to iterate on this feature, as well as many other improvements to the core editing experience. Please send us any ideas or suggestions!

Better “live” mode, powered by codegen

As you build out your designs, you can see it in action at any time by entering “Live” mode, either by clicking the “play” button or the “pop-out” button at the upper-right:

With this release, the “live” mode is now powered by the same code that we generate for your React component! This means what you see in “live” mode is really what you will see in your production app, if you use the code generated by Plasmic.

In “Live” mode, you can interact with your components by hovering, clicking, and typing; this allows you to test out your interaction variants like hover and focus states. If you use the “pop-out” live mode, you can also resize the pop out window to test out how your design adapts to different window sizes, and when your global screen variants get activated.

Even better—now, the “pop-out” live mode will be kept in sync with what’s happening in the Plasmic Studio, so that as you make edits, the pop-out window will immediately be updated to reflect the new changes!

Codegen: ScreenVariantProvider

In Plasmic, you can define different screen sizes under the global Screen variant group, and then change what your component looks like in each of these screen sizes to express truly responsive designs.

To achieve this in generated code, Plasmic does two things:

  1. For CSS-only changes, Plasmic uses the expected media queries in the generated CSS, so that the applied css rules change when the window size changes.
  2. For non-CSS changes — for example, showing different text content, activating different component variants, using different element attributes, etc.—Plasmic uses a React Context for the Screen variant. The Plasmic-generated code for affected components would watch for changes to the effective Screen variant and re-render accordingly.

It used to be that for #2, you had to figure out how to provide the right active Screen variant value yourself. We now generate a ScreenVariantProvider, which you can place at the root of your app; it will listen to window resizing events and provide the right Screen variant to all the Plasmic components!

import {ScreenVariantProvider} from "./plasmic/PlasmicGlobalVariant__Screen";
function App() {
  return (
    <ScreenVariantProvider>
      <MyApp/>
    </ScreenVariantProvider>
  );
}

2020-05-22 Fri: new component API

A more familiar component API

When you convert your Plasmic components into code, we generate “blackbox” libraries that your React components can use to actually render your components. Previously, our API uses function calls like createRenderer().withOverrides() in order to minimize runtime overhead and avoid creating additional layers of React components. However, we understand that this code appears unusual, and in most cases, the runtime overhead is negligible.

We have therefore evolved our “blackbox” libraries to expose React components in addition to a renderer, so you can use them in a more familiar way as pure React presentational components.

With the new component API, Plasmic will generate the following skeleton code for a ButtonGroup component in ButtonGroup.tsx.

// This is a skeleton starter React component generated by Plasmic.
// Feel free to edit as you see fit.
import React, { ReactNode } from "react";
import {
  PlasmicButtonGroup__VariantsArgs,
  PlasmicButtonGroup
} from "../gen/PlasmicButtonGroup"; // plasmic-import: e5MdEx4Rxa/render
interface ButtonGroupProps {
  buttons?: ReactNode;
  // className prop is required for positioning instances of
  // this Component
  className?: string;
  children?: never;
}
function ButtonGroup(props: ButtonGroupProps) {
  return (
    <PlasmicButtonGroup
      args={{
        buttons: props.buttons
      }}
      root={
        // className prop needs to be piped to the root element of this component
        { className: props.className }
      }
    />
  );
}
export default ButtonGroup as React.FunctionComponent<ButtonGroupProps>;

PlasmicButton takes in the variants, args, and a list of named nodes for you to override. The API here is basically identical to the PlasmicButton.createRenderer() API, but in React component form!

Plasmic also generates one component for each named node too, so you can use PlasmicButton.<name> to instantiate named nodes. For example, you can pass a list of buttons using the sampleButton component:

function ButtonGroup(props: ButtonGroupProps) {
  return (
    <PlasmicButtonGroup
      args={{
        buttons: (
          <>
            <PlasmicButtonGroup.sampleButton>
              Button 1
            </PlasmicButtonGroup.sampleButton>
            <PlasmicButtonGroup.sampleButton>
              Button 2
            </PlasmicButtonGroup.sampleButton>
          </>
        )
      }}
      root={
        // className prop needs to be piped to the root element of this component
        { className: props.className }
      }
    />
  );
}

The **PlasmicButton.createRenderer()** API will continue to exist, though, so if you prefer to do things that way, you can carry on as you have!

Action required: codegen name change We have switched from using the PP__ prefix to Plasmic to reduce confusion. That means the exported symbols from our Plasmic blackbox libraries have all been changed! You may need to fix up some references from your own component code from PP__ to Plasmic.

New tutorial video: Plasmic Button to React

We’ve created a new video on how to turn that Plasmic Button component to a real React component!

As always, if you have anything you’d like to see a tutorial of, please let us know!

And more

  • A significant number of bug fixes this week. Thank you for all the reports!

2020-05-15 Fri: plain React code and new variants UI

Added codegen scheme: “plain React”

So far we have supported a “blackbox library” codegen scheme—the philosophy of this approach is to let you treat your generated code like any other library dependency you pull into your project, so that you can just import and use it as a presentational component.

We now additionally support generating “Plain React” code as a one-time code export. For instance, if you were just looking for a starting point and don’t need to iterate on the design or keep the code in sync, or if you are an agency that is handing off a project to a client expecting plain React code, then you now have the ability to do so.

Note that this is a one-time code export, meaning that if you edit the generated code to attach real props/data/event handlers, then you now own and maintain the presentational code.

The “Plain React” code scheme is available in our CodeSandbox integration. We will also release a new version of the plasmic CLI soon to support this scheme. (For safety, Plasmic does not overwrite any file you have edited in CodeSandbox; you can first delete the file if you want to force the next update to regenerate that file.)

This is another step on our path to supporting a diverse family of compilation targets. Please continue to let us know what targets you are interested in seeing.

New “Recording Bar”

Working with variants is core to the Plasmic editing experience. We want you to always be aware of what variant you’re currently making changes for, and allow you to easily switch between the different variants. As another step in refining our variants UI, we’ve added a new Recording Bar above the main canvas. It appears whenever you start editing for a certain variant (meaning that your edits are being “recorded” into that variant). This is to help make it always clear what context you’re working in.

Please keep the feedback coming. We will continue to iterate on and improve the UX of using variants.

Improved override indicators

Plasmic gives you a lot of power to model all the different ways your component can look by using variants. Now we’ve made it easier than ever to understand where your style values are coming from and when they are getting overridden!

In the right panel, we show a blue dot for each setting that you’ve modified for your currently-recording variants. You can hover over the blue dot to get more details on exactly which values you’ve overridden from which variant. If your value is derived from a mixin that you’ve applied, you can even click through and edit the mixin directly.

Codegen update: className prop for Components

(Action required!)

In Plasmic, it is possible to create a component instance (say, a Button) and apply additional styling to that instance, usually for positioning—for example, top, left, width, z-index, etc.

The way we used to apply these “positioning styles” is by creating a wrapper div around the component instance, and adding the positioning styles to the wrapper. The wrapper can then place the component instance anywhere, without the component itself being aware of how it’s being used.

However, this was a pretty unusual choice, and led to a few subtle bugs. So we’re taking a different approach: all Components must now have a className prop, which is set on its root element. To position a component instance, we now generate a class with the positioning styles, and pass it to the className prop of the component. The positioning styles now apply directly to the root element of the component, instead of some extra wrapper. This is a common approach taken by many component libraries.

Migration If you have generated code, you now need to do a little bit of work to pipe the className prop to your root element. For example, this may be your Button component currently:

// Button.tsx
interface ButtonProps {
  children?: React.ReactNode;
  type?: "primary"|"secondary";
  onClick?: () => void;
}
function Button(props: ButtonProps) {
  return PP__Button.createRenderer()
    .withVariants({type: props.type})
    .withArgs({children: props.children})
    .withOverrides({
      root: {
        onClick: props.onClick
      }
    })
    .render();
}

You now need to add a new className prop that you set to the root element:

// Button.tsx
interface ButtonProps {
  children?: React.ReactNode;
  type?: "primary"|"secondary";
  onClick?: () => void;

  className?: string;
}
function Button(props: ButtonProps) {
  return PP__Button.createRenderer()
    .withVariants({type: props.type})
    .withArgs({children: props.children})
    .withOverrides({
      root: {
        onClick: props.onClick,
        className: props.className,
      }
    })
    .render();
}

This allows us to position a Button instance by passing in the appropriate class to className.

And more

  • Can now duplicate components.
  • Added new text style controls for overflow, indentation.
  • A significant number of bug fixes this week. Thank you for all the reports!

2020-05-08 Fri: CodeSandbox integration

CodeSandbox integration

You can now bring your designs to life in the click of a button with Plasmic’s new CodeSandbox integration! Instantly prototype with real code and data, conduct user tests, and share a true standalone web app with anyone—all in your browser and without having to set up any development tools.

To get started, click the new toolbar icon to create a sandbox, invite other users to edit the sandbox, and update the sandbox:

A key feature of Plasmic’s codegen capabilities is that it is not just a one-time export operation—you can freely iterate on the design and count on those edits to sync into the generated code, thus keeping the final product truly in sync with the design. This is how the CodeSandbox integration works as well. Plasmic creates exactly one sandbox per Plasmic project, and can update the sandbox with the same code that would have been generated by the plasmic command-line tool.

The sandbox is publicly readable but owned by Plasmic. This means when you try editing, the sandbox forks, so you end up with your own copy which won’t be receiving updates from Plasmic. To edit the Plasmic-owned sandbox and thus preserve your edits across sandbox updates, Plasmic invites you as an editor to the project. Just check your email inbox to “Accept Invitation” and sign into CodeSandbox.

By default, the sandbox shows a gallery of all components you have created in the project, and lets you navigate through them via left/right arrow key (similar to Plasmic’s live preview mode). You can go ahead and freely edit any of the component .tsx files to wire up your real state, event handlers, and logic. You can find more information in the sandbox’s README.md.

Codegen syntax

We know that in order to win over developers, we need to build trust in the generated code being clean and high-quality. To that end, for the blackbox codegen scheme, Plasmic now emits rendering code using JSX syntax, into plasmic/PP__<ComponentName>.tsx. This means that if you ever want to peek inside the blackbox, the rendering code will look significantly more readable and familiar.

For projects which use Plasmic generated code, the next time you run plasmic sync, it will rename PP_<ComponentName>.ts files to PP__<ComponentName>.tsx, and emit the code with the new JSX syntax.

Plasmic CLI upgrade To support the new syntax above, we have updated the plasmic CLI to 0.1.2. If you see the error below:

$ plasmic sync
(node:24800) UnhandledPromiseRejectionWarning: Error: Request failed with status code 426
  ...

Please upgrade the CLI:

$ yarn global add @plasmicapp/cli || npm install -g @plasmicapp/cli

In the future, the CLI will now show a clearer error message so this announcement won’t be necessary.

Tutorial videos

We’re starting a series of in-depth video tutorials!

The first one uses Plasmic to design a Button component:

You will be introduced to major concepts like variants and layout, as well as general tips and tricks on using Plasmic. Please take a look!

We would love to create more of these in the future, both for using Plasmic to design common components as well as for converting those components into real code. If you have something you’d like to see, please let us know in the Slack channel!

And more

  • Significant performance improvements across the board. Updating designs, undo/redo, and startup are all several times faster, and editing remains snappy even as you scale to large arenas with many artboards.
  • We’ve removed all naming restrictions on components; can now name components with any text.
  • Artboard titles now display not just the component name but also the activated variants that artboard is showing.
  • When you hover over the defined-style indicator (i.e. the dot before any style controls), we now explain where the value was defined (for instance, if it came from another variant or from a mixin).
  • Focusable elements now use browser defaults for the focused state unless you have defined a Focused interaction variant.
  • plasmic sync will now sync new components by default, instead of only components it has synced before. To have the old behavior, use plasmic sync --only-existing
  • We now generate more succinct CSS output. Still more to do here!
  • Can now toggle visibility on slots.
  • We now warn you when you try to delete a mixin that is currently in use.
  • Generated code components now should be styled fully consistently with their appearance in Plasmic Studio.
  • Lots more bug fixes and polish - thank you for all the reports and feedback!

2020-04-29 Wed: private alpha begins!

Hello world! Thanks for participating in our private alpha and following along with our progress. We’re so excited to start engaging you.

We’ll occasionally share updates on the new features and capabilities of Plasmic.

Figma-to-code coming soon

Perhaps the most important feature set we’ve been working on is integration with existing design tools, starting with Figma import.

If your team uses Figma and you want to keep your designs faithfully reflected in the final product, please click here to get access (or email us). We’d love to get your help to make sure this works well.

Revamped variants UI

Plasmic has a powerful system for designing different variants of the same component. These are “variations” of a component that may represent different states (“focused”, “error”, “loading”, “hover”, etc.) or different styles (“primary”, “danger”, “borderless”, “large”, etc.). Designers have the power to design exactly how the component should look in each variant, and developers have the power to activate the right variants for each component instance within the context of the live application.

In this release, we’ve made a few changes to how variants are shown in the app:

  • First, the Component Panel showing you information about the component you’re editing has now been merged into the right panel. This gives you more space on the canvas:
  • To create new variants of the component, you can click on the “More…” link in the Component Panel, which will expand and show the variants management UI:
  • If you want to record styles specific to a variant, you can either click on a variant in the expanded view, or just click on “Target Variants to record…” and select the variant to target.
  • When a variant is being targeted, we show a prominent red “Recording” badge that’s always visible on the screen, so that you are aware you’re making exceptional edits to a specific variant, instead of targeting the base.

Working with variants is a core part of the Plasmic experience, and we will continue iterating on this. Please send us any feedback you might have!

Simpler sizing system

Plasmic aims to offer the same powerful layout and styling available in the target medium—and for the web, that means CSS. But CSS is notoriously tricky with a lot of sharp edges, and so wherever possible, Plasmic also tries to offer simplified options for common effects.

One place where we do this is with sizing elements. In CSS, a dizzying set of rules can affect the size of your elements in subtle and nuanced ways depending on how your design is laid out. With this release, Plasmic tries to simplify this by letting you set an element’s width or height to “stretch” or “wrap”:

  • When set to “stretch”, this element will be stretched to fill the available space in its container.
  • When set to “wrap”, this element will take up only as much space as its content requires.

These settings try to consistently do the right thing, regardless of whether the element is in a horizontal, vertical, or free container. (And of course, you can still set an explicit pixel or percentage size if you’d like!)

Additionally, a component instance has an extra special size setting it can use—“default”—which means it will use whatever size setting that is specified for the component’s root element. For example, here are two Button instances on the left artboard, and the master Button component on the right artboard. The two Button instances have their sizes set to “default.” When the component’s root element size changes, the Button instances’ size also changes. The Button instances are also free to override the default to whatever they want, or switch back to the default at any time.

You can even change what the default should be for different variants of the component! Here, the Button component has a “wide” Variant that sets its root width to “stretch,” and a “tall” variant that sets its root height to “stretch.” You can activate these variants for the Button instances and see the difference.

Simplified artboard selection

We’re continuing to iterate on the relationship between artboards and components. We know this has been an area of confusion, and we still have a lot of ideas to try! We would appreciate any feedback you have here.

Codegen updates

We have pushed out @plasmicapp/react-web version 0.0.6. and @plasmicapp/cli version 0.0.9. All newly-exported code will now require this version. Of course, all your existing exported code will continue working until you try to re-export code again.

To upgrade, just run:

yarn add @plasmicapp/react-web || npm install @plasmicapp/react-web
yarn global add @plasmicapp/cli || npm install -g @plasmicapp/cli

# re-export code components you've already exported
plasmic sync

Notable updates here include:

  • Used fonts are now included by default in the generated css, your fonts should just work! In the future, we will provide an option to opt out of this, so you can use other methods of including fonts instead.
  • We’ve introduced a new defaultPlasmicDir option in plasmic.json; this is where Plasmic cli will now dump all generated files owned by Plasmic (all files preceding with PP__). By default, this is set to your src/plasmic.
  • cli will now warn you about version mismatches for @plasmicapp/react-web.

On organizing generated files At Plasmic, our philosophy is that developers should have as much control as possible over how they want to build their React applications. For example, we give developers total control over the React component files, so they can define exactly what props their React components take in, making them indistinguishable from non-Plasmic React components.

One area where this shows up is with file organization. Developers should be able to structure their files and folders however they prefer. That’s why, by default, we will dump files into defaultPlasmicDir, but the developers are always free to move them to wherever they prefer in the srcDir. You can see in plasmic.json where we think each file is on disk. The next time you run plasmic sync, we will try to find those files, detect where they’ve moved, and update the entries in plasmic.json. If Plasmic fails to find the files (say, if you renamed them), you can always directly update plasmic.json with the real locations!

And more

Lots of bug fixes, polish, and performance improvements from initial user reports—thank you!

  • Can use the “s” keyboard shortcut to draw a stack; if you draw a tall rectangle, it will be a vertical stack; if you draw a wide rectangle, it will be a horizontal stack.
  • Can now rename projects from the dashboard.
  • For all the numeric style settings on the right panel, you can now change their values by dragging on the setting labels.
  • From the color picker in the right panel, can now edit the selected color token, and reference a different color token.
  • Now easier to tab around the fields with your keyboard in the right panel once one field has focus.
  • Now including box-sizing: border-box in generated CSS.
  • And many more!