paperclip-ui / legacy-paperclip

Paperclip is a common language for designers and developers
http://paperclip.dev
Other
201 stars 13 forks source link
backend css front-end html javascript react

Checks

This project has been moved over to Tandem



Paperclip is a DSL for UI builders. Here's what a basic UI file looks like:

<!--
  @frame { height: 768, visible: false, width: 1024, x: -176, y: 173 }
-->
<ul component as="List">
  <style>
    padding: 14px;
    margin: 0px;
    font-family: sans-serif;
    display: flex;
    flex-direction: column;
    gap: 8px;
    list-style-type: none;
  </style>
  {children}
</ul>

<!--
  @frame { height: 768, visible: false, width: 1024, x: -1, y: 0 }
-->
<li component as="ListItem">
  {children}
</li>

<!--
  @frame { height: 366, title: "Todos", width: 258, x: 766, y: 402 }
-->
<List>
  <ListItem>buy cereal</ListItem>
  <ListItem>buy milk</ListItem>
</List>

Here's a demo of a UI builder prototype that works with Paperclip:

alt something

Paperclip UIs cover just HTML, CSS, and primitive components for now, and can be imported directly into code like so:

import * as styles from "./styles.pc";

export const List = ({items}) => {
  return <styles.List>
    {items.map(item) => {
      return <styles.ListItem key={item.id}>{item.label}</styles.ListItem>;
    }}
  </styles.List>;
};

Language features

Paperclip is limited to bare minimum features that are necessary for building presentational components. This includes:

Tooling features

UI Builder features

Paperclip aims to provide an easy-to-use API for UI builders:

Here's a basic example of the editing API (still very much WIP):

import { WorkspaceClient } from "@tandem-ui/workspace-client";
import { renderFrames, patchFrames } from "@paperclip-ui/web-renderer";

const client = new WorkspaceClient();
const project = await = client.openProject({
  uri: "file:///path/to/project/directory"
});

const doc = await project.getDocuments().open("file:///path/to/project/directory/src/components/button.pc");

// render the document
const mount = document.createElement("div");
let frames = renderFrames(doc.getContent());
document.body.appendChild(mount);

// When the document changes, re-render
doc.onAppliedChanges((newData) => {
  frames = patchFrames(frames, newData);
});

// Make a change to the 
doc.editVirtualObjects({
  kind: VirtualObjectEditKind.AppendChild,

  // path to element to append the child to
  nodePath: "0",

  // Child HTML
  child: {
    value: `Hello World`,
  },
});

Goal

The goal for Paperclip is to be a scalable data format for UI builders, and safe enough for non-engineers to feel confident about making visual changes.

In a perfect world, Paperclip could be the engine for a UI builder that enables:

It seems that the general direction of many UI builders is that they're mostly adopting the same principles (primitive components, slots, variants), and could benefit from using an open-source data model that's geared more for developers. Hopefully in the future, developers of UI builders can add their own rendering engine, create supersets, and rules on top of Paperclip according to features that their UI builder supports.

Why focus on the data model?

Mostly because the data model is easier to shape than a UI builder based on feedback. And, as a developer, I care mostly about how a tool influences the direction of a codebase. If I believe that a tool is detrimental to the overall health of the codebase, then there's no point in using it.

It's also a hard sell to allow anyone to write code who isn't a developer. That's why the data model is such a focus in ensuring that anyone working with it (written by hand or in a UI builder) has enough guardrails (removing incidental complexity, and providing safety tooling) to create shippable UIs.

Why code as a data model?

Mostly for maintainability, collaboration, and safety.

Why not use an existing language?

Mostly to have total control over the data model, and to only have features specifically for visual development. Most languages contain features that make it difficult to effectively map to a practical UI builder (even vanilla HTML and CSS to an extent). I think for a UI builder to be flexible and simple, that simplicity needs to be reflected in the data model.

Another reason why Paperclip was created is to ensure that multiple languages could be targeted. Eventually the plan is for Paperclip to compile down to just about any language.

What's the status of this Project?

Paperclip has been in active development for a few years. Now it's at an inflection point where a UI builder is necessary to help shape the DSL.

Can I use Paperclip now?

Yes! Paperclip can be used to build React applications. Currently it's powering most of the HTML and CSS at Hum Capital.

Installation

Just run this command in your existing project to get started

npx @paperclip-ui/cli init

This will walk you through a brief setup process. Next, just run:

npx @paperclip-ui/cli build

Resources

Contributing

Most of the focus right now for Paperclip is around UI builder APIs, so if you would like to help out, feel free to reach out! Some other areas in the future will include: