By Crayons and For Crayons
Tags: productivity, freshworks, crayons, visualeditor
Published: 2022-05-13 10:32:21

This post is about how I built a Visual Code generator called [Crayons Playground](https://crayons-playground.vercel.app/) using a web components library called [Crayons](https://crayons.freshworks.com/) and how I created two additional npm libraries supporting this tool.

The beauty of this Visual Code editor is that, it automatically generates markup using Crayons Components and it is also built using the Crayons components behind the scene.

## About Crayons
[Crayons](https://crayons.freshworks.com/) is a design library for developers who build apps for the [Freshworks Marketplace](https://www.freshworks.com/apps/). Through pre-built components, it offers control and flexibility to build rich interfaces consistent with the Freshworks product design and experience.

The Crayons Team is using Stencil to build the Crayons components using [TypeScript](https://typescriptlang.org) and React-like component semantics and finally publish them as platform native Web components and React wrappers for the same. You can find out more about this in the [Stencil documentation](https://stenciljs.com/docs/react).

## Why I built the Drag-n-Drop UI builder?
It all started as part of an internal hackathon at Freshworks where we built some cool and awesome stuff for the Marketplace apps.

It’s difficult to build Marketplace Apps UI without HTML & CSS Knowledge. Not every app developer is a designer. I wanted to address this problem by building a drag-n-drop UI builder using Crayons components. It is the answer to some of these questions. Can we have an IDE like tool for building Marketplace apps? How can we have apps with consistent look & feel with alignment to the product? What if we remove the coding barrier for building Marketplace app UIs?


## What it does?
Crayons Playground is kind of a Visual Editor for working with the Crayons component library for building Marketplace app user-interfaces without manually writing HTML Markup code. It features a fully drag-n-drop style UI builder. You can build any simple or complex layouts with it.

## Target Users
It is with the following people in mind I built this Drag-n-Drop UI builder tool using the Crayons Components library:
- Marketplace App Developers
- Front-end developers and
- Product Managers


## Inspirations
The original idea and inspiration for the Crayons Playground came from the full-featured visual editor and code generator for [React](https://reactjs.org) using [Chakra UI](https://chakra-ui.com/) called [openchakra](https://openchakra.app). All the underlying architecture, code organization and design & communication patterns are borrowed from openchakra. The only difference is Crayons Playground doesn't make use of any JavaScript framework whereas openchakra is completely built using React. 

## Technology
The Crayons Playground is built using vanilla Web Components without using any component publishing libraries like [Stencil](https://stenciljs.com/), [Lit](https://lit.dev/) and so on. The reason being I met with some roadblocks in building a drag-n-drop editor using these libraries. 

It is using [Webpack](https://webpack.js.org) for bundling, [Redux](https://redux.js.org) and [Immer](https://immerjs.github.io) for application state management.

Using robust state management toolbelts like Redux and Immer guarantees an easy and effective way to manage state throughout the application. Immer helps to keep the state immutable and clean.

It uses other utility libraries like [Lodash](https://lodash.com), [JSZip](https://stuk.github.io/jszip/) and [SortableJS](https://sortablejs.github.io/Sortable/). JSZip is used to package the user interface markup into HTML files and other required JavaScript files for a Marketplace App boilerplate in a compressed format and download them from the browser.

SortableJS is used to re-order the components in the Drag-n-Drop Editor from a separate component called the Children panel on the right side of the app.

In addition to the above mentioned libraries, I have also used two of my own npm libraries called [styled-web-components](https://github.com/rajasegar/styled-web-components) and [crayons-extensions](https://github.com/rajasegar/crayons-extensions). Let's have a brief look at them.

## styled-web-components

styled-web-components is a library offering style property primitives for Web components inspired by styled-system. I have already written a post about it in here.

{% embed https://dev.to/rajasegar/giving-super-powers-to-your-web-components-3j7k %}


## crayons-extensions
[crayons-extensions](https://github.com/rajasegar/crayons-extensions) is a small collection of layout components built as an extension for Crayons components. It will help you to construct complex UI layouts with simple component primitives like `fw-flex`, `fw-grid`, etc.,

See the Codepen below to understand how can you use the components from crayons-extensions.

{% codepen https://codepen.io/rajasegar/pen/ZErOKNy %}

I will write a separate post detailing the need, usage and the architecture of crayons-extensions which will be published soon here.

## Demo
The below is a demo of the Crayons Playground in action. It shows how to build the user interface by dragging and dropping components, updating their properties, testing them in a Code sandbox like [JSFiddle](https://jsfiddle.net/), check the generated HTML code and finally download the project as a Marketplace app. You can also see the app in action in the [Freshdesk](https://freshdesk.com) product.

{% embed https://www.youtube.com/watch?v=lA8TS-JGGps %}

## What's next? 
The tool currently produces Crayons v2 version code. Now we have seen what Crayons Playground can do, we can make some broad contours for the distant future. 

These are some of the things in the backlog:
- Update to Crayons v3
- Build a complete end-to-end solution for Building Marketplace Apps right from design to deployment. 
- Add more UI components and enhancements to the playground. 
- Built-in UI templates for common use-cases
- Automatic interaction and behavior wiring with JavaScript using existing events and data interfaces