• Getting Started
  • Using Visly from code
  • Version Control
  • Tokens
  • Layers
  • Primitives
  • Interaction States
  • Variants
  • Props & Slots
  • Composition & Inner Components
  • Built-ins
  • Responsive Design


  • Using Visly with Create React App
  • Using Visly with Next.js
  • Using Visly with Gatsby
  • Creating stateful components
  • Routing with Visly
  • Using variants for responsive design
  • Create dynamic UI with inner components
  • Reuse existing components with Slots


Props & Slots

Props are key to any React component and thus are key to creating components in Visly. This is a big difference from traditional design tools. Visly understands code and gives you the tools to integrate seamlessly with code. You can see your component’s props in the props panel on the bottom left of the editor.

There are a few different kinds of props in Visly: variant props, content props, and slot props. These all translate to regular React props in code. In brief:

  • Variant props are associated with your Variants and are used to indicate from code which variant a component should use;
  • Content props are props that pass data to a component, such as text for a text layer or an image for image layers; and
  • Slot props are props associated with a Slot or an inner component. Slots accept a React component as their value.

Content props

The rules for props are very similar to the rules for props in React components written by hand. For example, all props must have a unique name, as in the end Visly will be generating code very similar to what you would have written by hand. The prop names must also be written in camelCase naming to ensure they translate to a valid JavaScript identifier. For those of you using TypeScript, Visly will automatically infer the type of prop based on the property the prop is bound to.

Currently there are only a few properties that can have props bound to them, and they are generally what we classify as ‘content’ (e.g. - the text of a text layer, the icon of an icon layer, and the image of an image layer). Over time, you'll see Visly enable binding props to more styles such as the background color of a layer. Since this is not possible yet today, we suggest using Variants instead. To expose an icon, image, or text as a prop, you first select that layer and then find the diamond icon in the right hand side bar. Pressing this button will expose this as a content prop.

From the props panel at the bottom left of the editor, you can double click on a prop name to change it; this will also be the name of the prop in code. From code, props work exactly like any other React component, and if you're using TypeScript, Visly even generates type definitions for you!

Default values

All props in Visly have default values. The default value of a prop is what you see in the editor. So if you have an icon exposed as a prop, but in the editor have configured the icon to show a checkmark, then the checkmark icon will be treated as a default value for that prop and it will show if no prop is passed to it from code. The exceptions to this rule are Slot props and props bound to the image layer; the default value for both of these kinds of props is null, so you must pass in a valid prop for your component to render correctly.

Slots as placeholders

One of the main use cases of slots is providing a way of reusing components that you have already created in code within your Visly components. A slot in this case acts as a placeholder for a component that you pass it via a prop from code. By default, the name of both the slot layer and the prop on the component is children, which allows you to add component to this slot as you would with any other component in React that accepts a children prop. For example, you may want to design a reusable Card component in Visly, but you want this card to be able to host arbitrary content, even React components that weren't built in Visly. Slots are perfect for this use case.

From code you would import the Card component and then pass any component, whether created in Visly or in code, as a child to the Card component.

import { Card } from '../visly'
import { CodeComponent } from '../ui'

    <CodeComponent />

However, you can also create components that have multiple slots. In this case, it's better to give the slots specific names rather than using the default children prop name.

import { ComponentWithSlots } from '../visly'
import { NavBar } from '../ui'
import { Footer } from '../ui'

    Header={<NavBar />}
    Footer={<Footer />} />

Slots for composition

Another purpose for slots is to enable complex composition of components and inner components. This can be quite difficult to grasp as you are just getting started with Visly, but it's worth playing around with, as it will enable you to build much more dynamic components. While a normal Layers accepts any React component passed to it from code, it can also be configured to accept a fixed number of components built in Visly. This can be done by adding Composition & Inner Components as children to the slot layer.

In the above example, the children slot now accepts either a CopyLink component or a Publish component instead of any arbitrary React component. In this specific example, the CopyLink and Publish components are defined as inner components, but slots also accept external component references and even mixing of the two. This feature is incredibly powerful when you want to show two slightly different components / content depending on some application state. The example above is actually from the Visly application itself, where we show a UI for publishing a design system if you haven't already published it - otherwise we show a UI for copying the link to your design system.

From code, you can use this slot exactly the same way you would use any other slot, but instead of passing an arbitrary component to the slot, you pass one of the components that was listed as a child to the slot in Visly. This doesn't just work for children slots: you can do this for any slot in your component and even multiple slots.

import { ShareLinkDialogContent } from '../visly'

  {link != null ? (
    <ShareLinkDialogContent.CopyLink link={link} />
  ) : (
    <ShareLinkDialogContent.Publish />