Quick Start
CoCube combines the reactive cell and expression model from spreadsheets, event-driven interactivity from web pages, and the visual workflow of vector graphics design tools into a single system. It makes it easy to create, share, and collaborate on interactive tools like reactive diagrams, knowledge management systems, and more.
This guide is an introduction to CoCube. It will walk through the fundamental concepts you need to get started, beginning with small examples and building toward more complex use cases.
CoCube is in early release. Be aware that updates may alter or break your saved components. A desktop browser with WebGPU support is required. Using Chrome is highly recommended. Join the Discord to ask questions, provide feedback, and report issues!
What this guide covers
This guide will go over the following topics.
- High-level workflow.
- What is a component?
- Creating a component.
- Modifying appearance.
- Combining components.
- Cells and references.
- Adding reactivity.
- Collaboration and publishing.
High-level workflow.
The high-level workflow is as follows.
- Create simple interactive components that can view and modify data.
- Combine components to create more complex and useful tools.
- Optionally share and collaborate on these components with others.
What is a component?
Components are the collaborative, composable visual tools you create with CoCube. Like a spreadsheet, all data in a component exists in reactive cells. However, unlike a spreadsheet, a component is not displayed as a grid. Instead, the cells it contains define how it looks and behaves.
The following is a very simple component.
Width | 100 |
Height | 100 |
This component appears as a green (default color) square (default shape) with a width and height of 100. Width and Height are the names of the two cells defining this component. As you will see, any cell can be defined as a value or as an expression, allowing you to easily create dynamic behavior.
Cells
Every cell in a component has a unique name, and contains an expression to compute its value. You can give any name you want to a cell, but two cells with the same name can not exist together in a component. In this guide, text that looks like Height, or Width is always referring to the name of a cell.
Certain cells are special, in that they define how a component looks and behaves. Components contain cells which define its attributes - layout, color, size, rotation, reactivity, and more. These special cells are called Attribute Cells. They will be covered in the upcomming section.
Cells can be defined as a simple value, or as an expression. For example, the Width cell expects a Number. Instead of directly providing a value, you could set the cell to an expression that returns a Number. Something like Add(2, 3) would work.An expression that does not return the expected type of data will result in the Width cell taking its default value of 10.
In this guide, text formatted like Number, Color, or Bool indicates the type of some data. Usually the type is self explanatory, Number is a number, Text is some text string, like "hello". A Bool can be either true or false. An Array is a list of values, for example [1, "hi", true].
A Map is a set of named values, for example:
Item | Bubblegum |
Cost | 3 |
There are more types, like Color, EventHandler, Anchor, and Component that will be covered later in the guide.
Attribute Cells
Attribute cells are used to define how the component looks and behaves. These are cells with special names, and are listed in the table below along with the type of data they expect.
Color Color | Color of the component. |
---|---|
Width Number | Width of the component. |
Height Number | Height of the component. |
Rotation Angle | Rotation angle of the component. |
RotationAbsolute Bool | Set to prevent a component from inheriting its parent rotation. |
Display Shape | Define what the component looks like (square, letter, etc). |
AlignTo FixPoint | Set where the component aligns to. |
AlignFrom FixPoint | Set the point on the component which should act as the center. |
Anchor Anchor | Define what the component is aligned to. |
Animation Map | Define the animations for the component. |
EventHandler EventHandler | Define how the component reacts to events. |
Components Map | Define subcomponents. |
Selectable Bool | If true, the component will be selectable by the event system. |
PivotX Number | Define the pivot point offset in the X direction. |
PivotY Number | Define the pivot point offset in the Y direction. |
OffsetX Number | Define the component offset in the X direction. |
OffsetY Number | Define the component offset in the Y direction. |
ClipMask Bool | If true, the component will act as a clip mask. Subcomponents will only render directly behind it. |
Layer Bool | If true, the component will be displayed above all other components. |
Creating a component.
Navigate to the console.
Click the "+ New" button to create and start editing a new component.
With the editor open, you should see a single component rendered as a green square. This is how a component looks when no cells are defined.
Modifying appearance.
Let's change the color of the new component.
Create a new cell with the name Color. Capitalization matters when naming cells, Color is different from color. When naming the cell you want to insert you should also see a popup with a few common cell names. These are attribute cells - the cells which change the appearance or behavior of the component. Feel free to select Color from the list instead of typing it out.
When the cell is created, it will contain a default value. To change this value, click the cell itself in the cells panel. This will open the expression editor for that cell.
Since we are editing the Color cell, we want the cell to contain a Color, not a Number, Text, or any other type of data. You can change the type of data using the expression editor, by clicking on the type dropdown and selecting Color. Once the Color cell contains a Color you should see your component change.
Combining components.
Let's say you wanted to add a component to another component. This is where the Components attribute cell comes in. The following is a definition of a component containing two subcomponents named Little and Big.
Width | 50 | ||||||||||||
Height | 50 | ||||||||||||
Components |
|
The easiest way to add new subcomponents like this is to use the subcomponents panel. Alternatively, you can just set the Components cell yourself. This cell expects a Map containing Components and/or ComponentRefs.
After creating a component, you can then add it as a subcomponent to another component using a ComponentRef.
Nested Component Layout
This section looks at how a component is aligned relative to its containing component.
By default, the center of a subcomponent is aligned to the center of the parent component. This can be adjusted in multiple ways.
The first method is to set the AlignTo and AlignFrom cells.
You can also set the OffsetX and OffsetY cells to add some additional offset to the component. These cells expect a Number.
The PivotX and PivotY cells allow you to adjust the rotational center point of the component. These cells expect a Number.
The Anchor cell allows you to change what the component is relatively anchored to. By default, subcomponents are anchored to their containing component. This can be changed to anchor a component to the screen, or to the workspace. This cell expects an Anchor.
Cells and references.
Cells can reference other cells via a few functions.
Here is a component that uses a reference to compute its size dynamically:
Width | 50 |
Height | Cell(Width) |
Modifying the Width cell would cause the Height of the component to change as well; in this case, the height will always match the width.
To read a cell in a parent component use e.g. ParentCell(Width, 1). This function reads the Width of the containing component. For example:
Width | 100 | ||||||
Components |
|
In this component, any change to the containing components Width cell will result in a change to the subcomponents Height.
Adding reactivity.
Components can be configured to react to events.
To make a component reactive, set the EventHandler cell to an EventHandler.You can then configure the event handler inside the expression editor.
Event handlers work using two concepts: Matchers and Actions.
A matcher allows you to choose what events the component will listen to. For example, if a cell should be modified when the component is clicked, then the matcher would be:
Once a matcher is selected, actions can be added. Say the components Color cell should be changed. To do this, add the following action to the event handler:
The matcher would then trigger the action when the component is clicked, changing its color.
SetCell can take any expression, and that expression is evaluated when it matches an event.
Collaboration and publishing.
Once you have something you want to publish just make it public and share the URL.