flet-box 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +10 -0
  2. package/bin/cli.js +23 -7
  3. package/bin/commands/checkApi.js +761 -0
  4. package/bin/commands/create.js +77 -5
  5. package/bin/utils/dtsProps.js +191 -0
  6. package/bin/utils/moduleExports.js +165 -0
  7. package/bin/utils/neutralise.js +64 -0
  8. package/bin/utils/templates.js +366 -27
  9. package/docs/CONTRIBUTING.md +156 -0
  10. package/docs/README.md +68 -0
  11. package/docs/arquitectura.md +164 -0
  12. package/docs/cli/README.md +542 -0
  13. package/docs/guides/README.md +33 -0
  14. package/docs/guides/app-templates.md +197 -0
  15. package/docs/guides/compatibility.md +95 -0
  16. package/docs/guides/embedding.md +284 -0
  17. package/docs/guides/first-app.md +208 -0
  18. package/docs/guides/frontend-services.md +171 -0
  19. package/docs/guides/minification-and-protection.md +260 -0
  20. package/docs/guides/mobile-and-platforms.md +439 -0
  21. package/docs/guides/online-updates.md +196 -0
  22. package/docs/guides/router.md +282 -0
  23. package/docs/guides/state.md +283 -0
  24. package/docs/guides/syntax-philosophy.md +150 -0
  25. package/docs/guides/utilities.md +241 -0
  26. package/docs/guides/widget-structure.md +163 -0
  27. package/docs/server/README.md +68 -0
  28. package/docs/server/START_HERE.md +121 -0
  29. package/docs/server/api.md +225 -0
  30. package/docs/server/data-services.md +300 -0
  31. package/docs/server/deployment.md +113 -0
  32. package/docs/server/security.md +196 -0
  33. package/docs/services/README.md +79 -0
  34. package/docs/services/RamStore.md +84 -0
  35. package/docs/services/Session.md +84 -0
  36. package/docs/services/Storage.md +88 -0
  37. package/docs/services/http.md +86 -0
  38. package/docs/tools/README.md +138 -0
  39. package/docs/tools/animation.md +87 -0
  40. package/docs/tools/async-ids-log.md +80 -0
  41. package/docs/tools/device.md +132 -0
  42. package/docs/tools/introspection.md +67 -0
  43. package/docs/tools/lists.md +96 -0
  44. package/docs/tools/markdown.md +79 -0
  45. package/docs/tools/reactivity.md +288 -0
  46. package/docs/tools/state.md +103 -0
  47. package/docs/tools/styling.md +92 -0
  48. package/docs/tools/text-and-time.md +89 -0
  49. package/docs/tools/theme.md +102 -0
  50. package/docs/tools/validation.md +75 -0
  51. package/docs/tools/visual-effects.md +84 -0
  52. package/docs/widget/Accordion.md +144 -0
  53. package/docs/widget/AdMob.md +144 -0
  54. package/docs/widget/AdSense.md +133 -0
  55. package/docs/widget/AdaptiveScaffold.md +105 -0
  56. package/docs/widget/AlertDialog.md +103 -0
  57. package/docs/widget/AnimatedBox.md +130 -0
  58. package/docs/widget/AnimatedText.md +123 -0
  59. package/docs/widget/AppBar.md +118 -0
  60. package/docs/widget/Audio.md +135 -0
  61. package/docs/widget/Avatar.md +119 -0
  62. package/docs/widget/Badge.md +128 -0
  63. package/docs/widget/BottomNavigation.md +116 -0
  64. package/docs/widget/BottomSheet.md +125 -0
  65. package/docs/widget/Button.md +137 -0
  66. package/docs/widget/COMMON_PROPS.md +150 -0
  67. package/docs/widget/Card.md +125 -0
  68. package/docs/widget/Carousel.md +151 -0
  69. package/docs/widget/Chart.md +151 -0
  70. package/docs/widget/Checkbox.md +118 -0
  71. package/docs/widget/Chip.md +126 -0
  72. package/docs/widget/CircularBar.md +168 -0
  73. package/docs/widget/CircularChart.md +164 -0
  74. package/docs/widget/CodeViewer.md +130 -0
  75. package/docs/widget/CollapsibleSideBar.md +112 -0
  76. package/docs/widget/Column.md +129 -0
  77. package/docs/widget/Container.md +136 -0
  78. package/docs/widget/DataTable.md +150 -0
  79. package/docs/widget/Divider.md +109 -0
  80. package/docs/widget/DraggBox.md +129 -0
  81. package/docs/widget/Drawer.md +135 -0
  82. package/docs/widget/DrawerItem.md +98 -0
  83. package/docs/widget/Dropdown.md +139 -0
  84. package/docs/widget/DroppBox.md +152 -0
  85. package/docs/widget/FloatingActionButton.md +120 -0
  86. package/docs/widget/GridView.md +140 -0
  87. package/docs/widget/Icon.md +117 -0
  88. package/docs/widget/Image.md +125 -0
  89. package/docs/widget/Input.md +151 -0
  90. package/docs/widget/Inspector.md +92 -0
  91. package/docs/widget/InstallButton.md +128 -0
  92. package/docs/widget/ListTile.md +132 -0
  93. package/docs/widget/ListView.md +138 -0
  94. package/docs/widget/Markdown.md +175 -0
  95. package/docs/widget/MatrixRain.md +122 -0
  96. package/docs/widget/Modal.md +129 -0
  97. package/docs/widget/Pagination.md +135 -0
  98. package/docs/widget/ParallaxBox.md +128 -0
  99. package/docs/widget/ProgressBar.md +130 -0
  100. package/docs/widget/QRCode.md +117 -0
  101. package/docs/widget/README.md +188 -0
  102. package/docs/widget/Radio.md +123 -0
  103. package/docs/widget/Rating.md +131 -0
  104. package/docs/widget/Row.md +131 -0
  105. package/docs/widget/START_HERE.md +146 -0
  106. package/docs/widget/Scaffold.md +152 -0
  107. package/docs/widget/Skeleton.md +130 -0
  108. package/docs/widget/Slider.md +146 -0
  109. package/docs/widget/SnackBar.md +102 -0
  110. package/docs/widget/Stack.md +128 -0
  111. package/docs/widget/Stepper.md +145 -0
  112. package/docs/widget/Switch.md +118 -0
  113. package/docs/widget/Tabs.md +124 -0
  114. package/docs/widget/Text.md +133 -0
  115. package/docs/widget/Tooltip.md +145 -0
  116. package/docs/widget/TreeView.md +176 -0
  117. package/docs/widget/Video.md +127 -0
  118. package/docs/widget/_template.md +61 -0
  119. package/package.json +3 -2
  120. package/src/animations/animate.js +180 -70
  121. package/src/animations/index.js +1 -0
  122. package/src/create-index.sh +1 -1
  123. package/src/index.d.ts +45 -22
  124. package/src/index.js +1 -0
  125. package/src/navigations/AdaptiveScaffold.js +11 -2
  126. package/src/navigations/BottomNavigation.js +10 -3
  127. package/src/navigations/Tabs.js +6 -2
  128. package/src/tools/useState.js +54 -63
  129. package/src/widget-factory/assignProps.js +23 -1
  130. package/src/widget-factory/processProps.js +10 -3
  131. package/src/widget-factory/reactiveValue.js +43 -18
  132. package/src/widget-factory/translateProps.js +777 -901
  133. package/src/widgets/AlertDialog.js +7 -5
  134. package/src/widgets/Checkbox.js +9 -7
  135. package/src/widgets/CircularBar.js +12 -1
  136. package/src/widgets/FloatingActionButton.js +4 -7
  137. package/src/widgets/Image.js +5 -7
  138. package/src/widgets/Input.js +92 -0
  139. package/src/widgets/ListView.js +73 -29
  140. package/src/widgets/Pagination.js +6 -3
  141. package/src/widgets/ProgressBar.js +16 -13
  142. package/src/widgets/Radio.js +6 -7
  143. package/src/widgets/Slider.js +23 -4
  144. package/src/widgets/Stack.js +36 -3
  145. package/src/widgets/Stepper.js +4 -3
  146. package/src/widgets/Switch.js +3 -4
  147. package/src/widgets/TreeView.js +0 -1
@@ -0,0 +1,197 @@
1
+ # Build your first FletBox app
2
+
3
+ This guide shows complete app shapes. You can copy one example, run it, and then replace the text or widgets with your own ideas.
4
+
5
+ ## 1. The smallest app
6
+
7
+ Start with one widget and mount it with `runApp`.
8
+
9
+ ```javascript
10
+ import { runApp, Container, Text } from "flet-box";
11
+
12
+ const App = () => {
13
+ return Container({
14
+ padding: 20,
15
+ child: Text({ text: "Hello World" }),
16
+ });
17
+ };
18
+
19
+ runApp(App, "root");
20
+ ```
21
+
22
+ What happens:
23
+
24
+ - `App` is a function that describes the screen.
25
+ - `Container` creates a layout box.
26
+ - `Text` writes words inside the box.
27
+ - `runApp` places the result in the HTML element with id `root`.
28
+
29
+ ## 2. A styled page
30
+
31
+ ```javascript
32
+ import { runApp, Container, Text, colors } from "flet-box";
33
+
34
+ const App = () => {
35
+ return Container({
36
+ padding: 20,
37
+ bgColor: colors.background,
38
+ borderRadius: 16,
39
+ child: Text({
40
+ text: "My App",
41
+ size: 24,
42
+ weight: "bold",
43
+ }),
44
+ });
45
+ };
46
+
47
+ runApp(App, "root");
48
+ ```
49
+
50
+ Use `padding` for space inside the box. Use `bgColor` to change its background. Use `borderRadius` to soften its corners.
51
+
52
+ ## 3. A page with a top bar
53
+
54
+ ```javascript
55
+ import { runApp, Scaffold, AppBar, Text, colors } from "flet-box";
56
+
57
+ const App = () => {
58
+ return Scaffold({
59
+ appBar: AppBar({
60
+ title: "My App",
61
+ centerTitle: true,
62
+ }),
63
+ body: Text({ text: "Main content" }),
64
+ backgroundColor: colors.background,
65
+ });
66
+ };
67
+
68
+ runApp(App, "root");
69
+ ```
70
+
71
+ `Scaffold` gives a page a standard structure. `appBar` is the top area and `body` is the main content.
72
+
73
+ ## 4. A page with a side menu
74
+
75
+ ```javascript
76
+ import {
77
+ runApp,
78
+ Scaffold,
79
+ AppBar,
80
+ Drawer,
81
+ DrawerItem,
82
+ Icon,
83
+ Text,
84
+ colors,
85
+ openDrawer,
86
+ } from "flet-box";
87
+
88
+ const App = () => {
89
+ return Scaffold({
90
+ appBar: AppBar({
91
+ title: "My App",
92
+ leading: Icon({
93
+ name: "menu",
94
+ onPress: () => openDrawer(),
95
+ }),
96
+ }),
97
+ drawer: Drawer({
98
+ header: Text({ text: "Menu", size: 20, weight: "bold", padding: 20 }),
99
+ body: [
100
+ DrawerItem({ icon: "home", label: "Home", route: "/" }),
101
+ DrawerItem({ icon: "settings", label: "Settings", route: "/settings" }),
102
+ ],
103
+ }),
104
+ body: Text({ text: "Main content" }),
105
+ backgroundColor: colors.background,
106
+ });
107
+ };
108
+
109
+ runApp(App, "root");
110
+ ```
111
+
112
+ The menu button calls `openDrawer`. Each `DrawerItem` describes one navigation option.
113
+
114
+ ## 5. A page with tabs
115
+
116
+ ```javascript
117
+ import { runApp, Scaffold, AppBar, Tabs, Text, colors } from "flet-box";
118
+
119
+ const App = () => {
120
+ return Scaffold({
121
+ appBar: AppBar({ title: "My App", centerTitle: true }),
122
+ body: Tabs({
123
+ tabs: ["Home", "Profile", "Settings"],
124
+ children: [
125
+ Text({ text: "Home screen" }),
126
+ Text({ text: "User profile" }),
127
+ Text({ text: "Settings" }),
128
+ ],
129
+ }),
130
+ backgroundColor: colors.background,
131
+ });
132
+ };
133
+
134
+ runApp(App, "root");
135
+ ```
136
+
137
+ The first item in `tabs` matches the first item in `children`, the second matches the second, and so on.
138
+
139
+ ## 6. A reusable component
140
+
141
+ ```javascript
142
+ import { Container, Text, colors } from "flet-box";
143
+
144
+ export const ProfileCard = ({ title, onPress }) => {
145
+ return Container({
146
+ padding: 16,
147
+ bgColor: colors.surface,
148
+ borderRadius: 12,
149
+ onPress,
150
+ child: Text({
151
+ text: title || "My Profile",
152
+ size: 18,
153
+ weight: "bold",
154
+ }),
155
+ });
156
+ };
157
+ ```
158
+
159
+ A component is a function that receives values and returns widgets. This lets you reuse the same design in many places.
160
+
161
+ ## 7. A list with data
162
+
163
+ ```javascript
164
+ import { ListView, ListTile, createList, random } from "flet-box";
165
+
166
+ const createUsers = () => createList({
167
+ id: () => random.id(),
168
+ title: () => random.fullName(),
169
+ subtitle: () => random.email(),
170
+ }, 20);
171
+
172
+ export const UserList = ({ data = createUsers(), onSelect }) => {
173
+ return ListView({
174
+ data,
175
+ renderItem: (item) => ListTile({
176
+ title: item.title,
177
+ subtitle: item.subtitle,
178
+ onPress: () => onSelect(item),
179
+ }),
180
+ });
181
+ };
182
+ ```
183
+
184
+ `data` is the collection. `renderItem` explains how one item should look. FletBox repeats that design for every item.
185
+
186
+ ## A simple learning path
187
+
188
+ 1. Build a page with `Container` and `Text`.
189
+ 2. Add `Column` and `Row` to arrange content.
190
+ 3. Add a `Button` and an event such as `onPress`.
191
+ 4. Add `Input`, `Checkbox`, `Switch`, or `Dropdown` for user input.
192
+ 5. Use `Scaffold`, `AppBar`, `Drawer`, or `Tabs` for a larger screen.
193
+ 6. Extract repeated designs into reusable components.
194
+
195
+ For individual widget details, return to the [widget documentation](../widget/README.md) or begin with [Start here](../widget/START_HERE.md).
196
+
197
+ If you already have a page and only want to add one interactive area, read [Add FletBox to an existing page](embedding.md).
@@ -0,0 +1,95 @@
1
+ # Compatibility and support
2
+
3
+ > **Level: Advanced.** This page is for shipping — skip it on a first read. It follows [mobile and platforms](mobile-and-platforms.md) in the book's reading path.
4
+
5
+ FletBox targets browser-based applications and can also be packaged for mobile platforms.
6
+
7
+ ## Platform matrix
8
+
9
+ | Platform | Status | Notes |
10
+ | --- | --- | --- |
11
+ | Modern browsers | Supported | Uses DOM, ES modules, and browser APIs. |
12
+ | Static web hosting | Supported | Build with `npm run build`. |
13
+ | PWA | Supported | Requires manifest, service worker, and HTTPS in production. |
14
+ | Android | Supported through Capacitor | Build the web app first, then sync Capacitor. |
15
+ | iOS | Supported through Capacitor | Requires macOS and Xcode. |
16
+ | Desktop | Possible through Electron or Tauri | Package the generated web build. |
17
+ | Server-side rendering | Not a primary target | Widgets depend on browser DOM APIs. |
18
+
19
+ ## Runtime requirements
20
+
21
+ ### Browser
22
+
23
+ The application expects support for:
24
+
25
+ - ES modules.
26
+ - `fetch`.
27
+ - `localStorage` and `sessionStorage` when storage services are used.
28
+ - DOM events and `HTMLElement`.
29
+ - `AbortSignal.timeout` when using the default HTTP timeout behavior.
30
+ - `WebSocket` when HMR is enabled.
31
+
32
+ Private browsing, sandboxed iframes, and strict browser policies may disable some APIs. Check availability before using storage or device features.
33
+
34
+ ### Node.js
35
+
36
+ Node.js 18 or newer is required for the CLI and build tooling. FletBox widgets themselves are browser-oriented and should not be rendered directly in a Node process without a DOM environment.
37
+
38
+ ## Build targets
39
+
40
+ The main build path is:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ Then use the output in `dist/` for hosting or Capacitor:
47
+
48
+ ```bash
49
+ npx cap sync android
50
+ npx cap sync ios
51
+ ```
52
+
53
+ See [Mobile and platforms](mobile-and-platforms.md) for APK, AAB, iOS, PWA, and desktop workflows.
54
+
55
+ ## Browser feature checks
56
+
57
+ ```javascript
58
+ import { device, isStorageAvailable } from "flet-box";
59
+
60
+ if (device.isMobile()) {
61
+ console.log("Mobile device");
62
+ }
63
+
64
+ if (!isStorageAvailable()) {
65
+ console.warn("Persistent storage is not available");
66
+ }
67
+ ```
68
+
69
+ ## API stability labels
70
+
71
+ Documentation uses these meanings:
72
+
73
+ - **Stable**: exported, documented, and intended for normal application use.
74
+ - **Compatible alias**: an alternative name kept to make migration easier.
75
+ - **Experimental**: available but subject to behavior or API changes.
76
+ - **Legacy**: retained for older projects; prefer the current documented form.
77
+
78
+ When the runtime and `index.d.ts` disagree, the implementation must be verified before treating the feature as stable.
79
+
80
+ ## Known compatibility boundaries
81
+
82
+ - Browser storage is origin-scoped and limited in size.
83
+ - WebView behavior can differ from desktop browsers.
84
+ - Native device features require Capacitor plugins and permissions.
85
+ - HMR is a development feature and should not be required in production.
86
+ - Direct browser DOM access is required for widget mounting.
87
+ - Source maps can expose original source and should be handled intentionally.
88
+
89
+ ---
90
+
91
+ ## Continue reading
92
+
93
+ - **Previous:** [Build FletBox for mobile and other platforms](mobile-and-platforms.md)
94
+ - **Next:** [Add FletBox to an existing page](embedding.md) — Appendix D
95
+ - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
@@ -0,0 +1,284 @@
1
+ # Add FletBox to an existing page
2
+
3
+ > **Level: Advanced.** This page is for integration work. It is the last page of the book.
4
+
5
+ FletBox does not have to control your whole application. You can add one widget to an existing HTML page and keep using your current backend, CSS, JavaScript, or frontend framework.
6
+
7
+ This is useful when you want to add an interactive feature without rewriting the rest of the page.
8
+
9
+ ## Two ways to use FletBox
10
+
11
+ ### Complete application
12
+
13
+ Use `runApp()` when FletBox owns the main interface, routing, theme, and rendering lifecycle:
14
+
15
+ ```javascript
16
+ import { runApp, Container, Text } from "flet-box";
17
+
18
+ const App = () => Container({
19
+ padding: 24,
20
+ child: Text({ text: "A complete FletBox screen" }),
21
+ });
22
+
23
+ runApp(App, "root");
24
+ ```
25
+
26
+ ### Add one part to an existing page
27
+
28
+ Use `insertBy()` when your page already exists and you only want to add a widget:
29
+
30
+ ```javascript
31
+ import { Button, insertBy } from "flet-box";
32
+
33
+ insertBy(
34
+ Button({
35
+ text: "Open panel",
36
+ onPress: () => console.log("clicked"),
37
+ }),
38
+ "existing-root",
39
+ );
40
+ ```
41
+
42
+ The existing HTML only needs an element with the matching id:
43
+
44
+ ```html
45
+ <div id="existing-root"></div>
46
+ ```
47
+
48
+ ## Add FletBox with a browser import map
49
+
50
+ A plain HTML page can import FletBox as an ES module:
51
+
52
+ ```html
53
+ <script type="importmap">
54
+ {
55
+ "imports": {
56
+ "flet-box": "./node_modules/flet-box/src/index.js"
57
+ }
58
+ }
59
+ </script>
60
+
61
+ <div id="toolbar"></div>
62
+
63
+ <script type="module">
64
+ import { Button, insertBy } from "flet-box";
65
+
66
+ insertBy(
67
+ Button({
68
+ text: "Save",
69
+ onPress: () => alert("Saved"),
70
+ }),
71
+ "toolbar",
72
+ );
73
+ </script>
74
+ ```
75
+
76
+ Your page must be served through a development server or web server. Browser module imports usually do not work correctly when opening the file directly with `file://`.
77
+
78
+ ## Add a widget after existing content
79
+
80
+ Use `insertBy()` to append a widget:
81
+
82
+ ```javascript
83
+ import { Card, Text, insertBy } from "flet-box";
84
+
85
+ insertBy(
86
+ Card({
87
+ padding: 16,
88
+ child: Text({ text: "This card was added to an existing page." }),
89
+ }),
90
+ "content",
91
+ );
92
+ ```
93
+
94
+ ## Add a widget before or after another element
95
+
96
+ The target is an element id:
97
+
98
+ ```javascript
99
+ import { Button, insertBefore, insertAfter } from "flet-box";
100
+
101
+ const button = Button({ text: "Action" });
102
+
103
+ insertBefore(button, "original-heading");
104
+ insertAfter(Button({ text: "Next action" }), "original-heading");
105
+ ```
106
+
107
+ HTML:
108
+
109
+ ```html
110
+ <h1 id="original-heading">Existing heading</h1>
111
+ ```
112
+
113
+ ## Replace an existing element
114
+
115
+ Use `replaceBy()` when a FletBox widget should take the place of an existing DOM element:
116
+
117
+ ```javascript
118
+ import { Container, Text, replaceBy } from "flet-box";
119
+
120
+ replaceBy(
121
+ Container({
122
+ padding: 20,
123
+ bgColor: "#eff6ff",
124
+ child: Text({ text: "This replaces the old content." }),
125
+ }),
126
+ "legacy-message",
127
+ );
128
+ ```
129
+
130
+ ## Insert at the beginning
131
+
132
+ Use `prependBy()` to place the widget before the current first child:
133
+
134
+ ```javascript
135
+ import { Text, prependBy } from "flet-box";
136
+
137
+ prependBy(Text({ text: "Welcome", color: "#2563eb" }), "page-content");
138
+ ```
139
+
140
+ ## Mount the same widget in several roots
141
+
142
+ `mountAll()` clones a widget and appends a copy to each root id:
143
+
144
+ ```javascript
145
+ import { Text, mountAll } from "flet-box";
146
+
147
+ const notice = Text({
148
+ text: "Updated content",
149
+ color: "#2563eb",
150
+ });
151
+
152
+ mountAll(notice, ["header-notice", "footer-notice"]);
153
+ ```
154
+
155
+ HTML:
156
+
157
+ ```html
158
+ <div id="header-notice"></div>
159
+ <div id="footer-notice"></div>
160
+ ```
161
+
162
+ For complex interactive widgets, prefer creating a fresh widget for each root so each instance has its own state and event handlers.
163
+
164
+ ## Use a custom HTML page
165
+
166
+ FletBox can live beside normal HTML:
167
+
168
+ ```html
169
+ <section class="legacy-profile">
170
+ <h2>Existing profile</h2>
171
+ <p>This content was already on the page.</p>
172
+ <div id="profile-actions"></div>
173
+ </section>
174
+ ```
175
+
176
+ ```javascript
177
+ import { Button, Row, Text, insertBy } from "flet-box";
178
+
179
+ insertBy(
180
+ Row({
181
+ gap: 8,
182
+ children: [
183
+ Text({ text: "Actions:" }),
184
+ Button({ text: "Edit", onPress: () => openEditor() }),
185
+ Button({ text: "Delete", variant: "outlined", onPress: () => removeProfile() }),
186
+ ],
187
+ }),
188
+ "profile-actions",
189
+ );
190
+ ```
191
+
192
+ FletBox only owns the DOM node where the widget is mounted. The rest of the page remains yours.
193
+
194
+ ## Use FletBox with another frontend
195
+
196
+ You can mount a FletBox widget from React, Vue, Angular, or another application as long as you have a DOM element:
197
+
198
+ ```javascript
199
+ const target = document.querySelector("#external-toolbar");
200
+ const widget = Button({ text: "FletBox action" });
201
+
202
+ target.appendChild(widget);
203
+ ```
204
+
205
+ For a framework integration, mount and remove the widget inside that framework's lifecycle. Keep the widget reference so you can remove it during cleanup.
206
+
207
+ ## Direct DOM access
208
+
209
+ Every widget is a real `HTMLElement`. You can use standard DOM APIs when needed:
210
+
211
+ ```javascript
212
+ const button = Button({ text: "Inspect me" });
213
+
214
+ button.setAttribute("aria-label", "Inspect me");
215
+ button.addEventListener("mouseenter", () => {
216
+ console.log("native DOM event");
217
+ });
218
+
219
+ document.querySelector("#actions").appendChild(button);
220
+ ```
221
+
222
+ Prefer direct widget props such as `className` and framework event props when they are enough. Use direct DOM access for integration with existing page code.
223
+
224
+ ## Choosing the right mounting API
225
+
226
+ | Goal | API |
227
+ | --- | --- |
228
+ | Build the whole FletBox application | `runApp()` |
229
+ | Add a widget at the end of a root | `insertBy()` |
230
+ | Add a widget at the beginning | `prependBy()` |
231
+ | Place a widget before an element | `insertBefore()` |
232
+ | Place a widget after an element | `insertAfter()` |
233
+ | Replace an existing element | `replaceBy()` |
234
+ | Add copies to several roots | `mountAll()` |
235
+ | Create a controllable app instance | `createApp()` |
236
+
237
+ ## `createApp()` for a controlled application
238
+
239
+ Use `createApp()` when you want explicit `start()` and `destroy()` methods:
240
+
241
+ ```javascript
242
+ import { Container, Text, createApp } from "flet-box";
243
+
244
+ const app = createApp(
245
+ {
246
+ "/": () => Container({
247
+ padding: 20,
248
+ child: Text({ text: "Home" }),
249
+ }),
250
+ },
251
+ {
252
+ rootId: "app-root",
253
+ fallback: Container({
254
+ padding: 20,
255
+ child: Text({ text: "Loading..." }),
256
+ }),
257
+ },
258
+ );
259
+
260
+ app.start();
261
+
262
+ // Later, when the page or integration is destroyed:
263
+ // app.destroy();
264
+ ```
265
+
266
+ ## Important integration tips
267
+
268
+ - Mount into a dedicated element instead of replacing an unrelated page section.
269
+ - Give every integration root a stable id.
270
+ - Use `children: [ ... ]` for several widgets and `child: widget` for one child.
271
+ - Keep application state inside the integration when possible.
272
+ - Clean up app instances when a page is removed.
273
+ - Use `runApp()` only when FletBox should own the root lifecycle.
274
+ - Use `insertBy()` and related helpers when FletBox is only one part of the page.
275
+
276
+ ---
277
+
278
+ ## Continue reading
279
+
280
+ - **Previous:** [Compatibility and support](compatibility.md)
281
+ - **Next:** [Ship updates without the store (OTA / online updates)](online-updates.md) — Appendix E
282
+ - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
283
+
284
+ > The [FletBox Server](../server/README.md) toolkit is a separate backend product and is not part of the reading path.