applet 0.6.3
applet: ^0.6.3 copied to clipboard
A Flutter package for hot updates and code push with JavaScript.
Applet #
English 中文
A Flutter package for hot updates and code push with JavaScript.
Features #
- Supports the latest version of Flutter.
- Both the UI and logic are implemented using JavaScript.
- Supports all platforms, including mobile, desktop, and web.
Getting started #
An example of a simple text component. Here is the JS code:
App = {
"type": "Container",
"color": "#000000",
"alignment": "center",
"child": {
"type": "Text",
"data": "Flutter Applet Example",
"maxLines": 3,
"overflow": "ellipsis",
"style": {
"color": "#00FFFF",
"fontSize": 20.0,
"fontWeight": "bold",
"decoration": "underline"
}
}
}
In Applet, the App
object describes the structure of the UI. Dynamically modifying components involves changing the properties of the App
object.
To convert the above JS code into UI components, you can simply use Applet(jsCode)
. The more detailed code is as follows:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: Center(
child: Applet(jsCode)
)
);
}
Upon running, you will see:

Advanced #
Let's look at a more complex calculator example. The code can be divided into three parts:
- The calculator's buttons (grid components)
grid_app
are generated through thebuttons
array.
const buttons = [
{ label: '+', event: "op('add')" },
{ label: '-', event: "op('sub')" },
{ label: 'x', event: "op('mul')" },
{ label: '÷', event: "op('div')" },
{ label: '1', event: "digit(1)" },
{ label: '2', event: "digit(2)" },
{ label: '3', event: "digit(3)" },
{ label: 'C', event: "clear()" },
{ label: '4', event: "digit(4)" },
{ label: '5', event: "digit(5)" },
{ label: '6', event: "digit(6)" },
{ label: '0', event: "digit(0)" },
{ label: '7', event: "digit(7)" },
{ label: '8', event: "digit(8)" },
{ label: '9', event: "digit(9)" },
{ label: '=', event: "equal()" }
];
const grid_app = {
"type": "GridView",
"crossAxisCount": 4,
"padding": "10, 10, 10, 10",
"mainAxisSpacing": 4.0,
"crossAxisSpacing": 4.0,
"childAspectRatio": 1.6,
"children": buttons.map(button => ({
"type": "TextButton",
"child": {
"type": "Text",
"data": button.label,
"style": {
"fontSize": 30.0
}
},
"click_event": button.event
}))
};
- In the
App
, the text component andgrid_app
are assembled to form the complete calculator UI.
App =
{
"type": "Column",
"crossAxisAlignment": "end",
"mainAxisAlignment": "end",
"mainAxisSize": "max",
"textBaseline": "alphabetic",
"textDirection": "ltr",
"verticalDirection": "down",
"children": [{
"type": "Text",
"data": "",
}, {
"type": "Text",
"data": " ",
"maxLines": 3,
"overflow": "ellipsis",
"style": {
"color": "#000000",
"fontSize": 40.0,
"fontWeight": "bold",
}
},
{
"type": "Expanded",
"child": grid_app
}]
}
- The calculator’s computation logic is completed through functions such as
clear
,digit
, andequal
.
var _pending = 0;
var _pendingOp = 'none';
var _display = 0;
var _displayLocked = false;
var _afterEquals = false;
function _resolve() {
if (_pendingOp === 'add') {
_display = _pending + _display;
} else if (_pendingOp === 'sub') {
_display = _pending - _display;
} else if (_pendingOp === 'mul') {
_display = _pending * _display;
} else if (_pendingOp === 'div') {
_display = _pending / _display;
}
_pendingOp = 'none';
}
function clear() {
_pending = 0;
_pendingOp = 'none';
_display = 0;
_displayLocked = false;
_afterEquals = false;
App.children[1].data = ""
}
function digit(n) {
if (_displayLocked || _afterEquals) {
_display = 0;
_displayLocked = false;
_afterEquals = false;
}
_display = _display * 10 + n;
App.children[1].data = _display + " ";
}
function op(operation) {
_resolve();
if (_afterEquals) {
_pending = _display;
_afterEquals = false;
} else {
_pending = _display;
}
_pendingOp = operation;
_display = 0;
_displayLocked = false;
App.children[1].data = (operation === 'add' ? '+' : operation === 'sub' ? '-' : operation === 'mul' ? 'x' : '÷') + " ";
}
function equal() {
_resolve();
_pending = _display;
_displayLocked = true;
_afterEquals = true;
App.children[1].data = _display + " ";
}
Upon running, you will see:

Additional information #
- The inspiration for the calculator comes from rfw.
- The UI components of the applet are built using dynamic_widget.
- The JS runtime uses jsf, which I developed myself.