This is a lower-level package for constructing an abstract, universal data representation of UI. If you're looking for the developer SDK, use the Codelessly CloudUI™ SDK.
Flutter's layouts and widgets represented as models and JSON data.
This package is used by the Codelessly Editor and CloudUI SDK to render Flutter Widgets. These APIs enable developers to interact with and manipulate user interfaces in a structured manner. It can be used to define components, layouts, interactions, and styles, among other things, programmatically.
User Interfaces (UI) as data.
This lower-level package establishes a foundation for an abstract, universally interpretable data representation of UI. The API is language-agnostic, written in pure Dart with no Flutter dependencies.
This universal approach allows for broad, diverse applications across different programming languages. The result is a library that supports the construction of complex UI structures, regardless of the programming language or development environment.
For example, we've translated this library to Javascript and Typescript and created a prototype SDK for building native web UIs. We were able to deploy the same UI to Flutter and HTML simultaneously.
Our goal is to continuously build a set of fundamental UI constructs that can express UI in HTML, SwiftUI, Android Compose, and eventually AI.
This package contains tools to create custom BaseNodes
. To convert a custom BaseNode
into UI, see the language
specific Flutter implementation in the Codelessly Cloud UI SDK package.
This is how you can create a custom BaseNode
:
import 'package:codelessly_api/codelessly_api.dart';
import 'package:codelessly_json_annotation/codelessly_json_annotation.dart';
part 'custom_node.g.dart';
@JsonSerializable()
class CustomNode extends BaseNode {
@override
final String type = 'custom_node';
MyCoolNode({
required super.id,
required super.name,
required super.basicBoxLocal,
});
factory CustomNode.fromJson(Map json) => _$CustomNodeFromJson(json);
@override
Map toJson() => _$CustomNodeToJson(this);
}
All nodes must extend BaseNode
. Please refer to the documentation inside BaseNode
for more information.
Then, register your node with the NodeJsonConverter
so that it can be properly deserialized from json. The
NodeJsonConverter will deserialize any registered nodes into their proper types.
NodeJsonConverter.registerNode('custom_node', CustomNode.fromJson);
For more examples, see
codelessly_api/lib/api/nodes
The base classes provided by the CodelesslyAPI include Vec
, RectC
, SizeC
, AlignC
, and others. They mirror
Flutter's own models and offer functionalities that represent essential building blocks for Flutter widgets.
These classes encapsulate key properties and behaviors needed for vector representations (Vec
), rectangular shapes (
RectC
), sizes (SizeC
), and alignment specifications (AlignC
). Each class is equipped with serialization and
deserialization capabilities, allowing them to be conveniently converted to and from JSON format. These classes
collectively provide a foundation for defining and manipulating UI elements in Flutter applications.
Classes that mirror Flutter tend to be suffixed with a C
for Codelessly
or Model
to
differentiate them from their Flutter counterparts like RectC
.
- Vec: This class represents a two-dimensional vector with x and y coordinates.
- RectC: This class represents a rectangle with a top-left position and a size. The position is represented as a
Vec
object, while the size is represented as aSizeC
object.
Components represent the building blocks of the user interface. They can be anything from a single button to a complex form or even an entire webpage.
ComponentModel
: A single component that holds properties of the component (type
), its unique identifier (id
), and actions associated with it (action
).
Actions define what should happen when a user interacts with a component in a certain way (for example, clicking a button or submitting a form).
ActionModel
: Holds information about an action to perform on a user interaction. It defines the type of the action (type
), which can be things like navigating to a page, opening a link, submitting a form, etc.
The PaintModel
is used to define styles that can be applied to components. It can represent a solid color, gradient,
or image texture.
PaintModel
: Defines the style properties such as the type of paint (type
), its visibility (visible
), and its opacity (opacity
), among others. Depending on the type of paint, it might have properties like color (color
), gradient transform (gradientTransform
), gradient stops (gradientStops
), or image transform (imageTransform
).
Contributions are welcome! Please open an issue to start a discussion.
Special thanks to the Flutter community for providing the inspiration and foundation for this project.
You can contact us on our website or join us on our Discord Server.