flet-box 0.0.0-stage → 1.0.2
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.
- package/LICENSE +21 -0
- package/README.md +190 -2
- package/bin/cli.js +394 -0
- package/bin/commands/buildAndroid.js +200 -0
- package/bin/commands/buildIOS.js +237 -0
- package/bin/commands/create.js +406 -0
- package/bin/commands/createBundle.js +375 -0
- package/bin/commands/createComponent.js +115 -0
- package/bin/commands/createScreen.js +161 -0
- package/bin/commands/killServer.js +107 -0
- package/bin/commands/package.js +131 -0
- package/bin/commands/release.js +189 -0
- package/bin/commands/runBundle.js +62 -0
- package/bin/commands/runCloudflare.js +89 -0
- package/bin/commands/runNative.js +109 -0
- package/bin/commands/runServer.js +390 -0
- package/bin/ota/loader.js +361 -0
- package/bin/utils/bundleConfig.js +178 -0
- package/bin/utils/capacitor.js +137 -0
- package/bin/utils/colors.js +215 -0
- package/bin/utils/helpers.js +80 -0
- package/bin/utils/spinner.js +96 -0
- package/bin/utils/templates.js +1824 -0
- package/bin/utils/version.js +108 -0
- package/package.json +58 -4
- package/src/animations/AnimatedBox.js +607 -0
- package/src/animations/AnimatedText.js +105 -0
- package/src/animations/MatrixRain.js +220 -0
- package/src/animations/ParallaxBox.js +369 -0
- package/src/animations/animate.js +332 -0
- package/src/animations/index.js +25 -0
- package/src/app.js +41 -0
- package/src/assets/icon-1024-maskable.png +0 -0
- package/src/assets/icon-192-maskable.png +0 -0
- package/src/assets/icon-192.png +0 -0
- package/src/assets/icon-512-maskable.png +0 -0
- package/src/assets/icon-512.png +0 -0
- package/src/assets/logo.png +0 -0
- package/src/core/App.js +44 -0
- package/src/core/hmr-client.js +142 -0
- package/src/core/index.js +34 -0
- package/src/core/pwa.js +100 -0
- package/src/core/runApp.js +430 -0
- package/src/create-index.sh +237 -0
- package/src/fonts/MaterialIcons-Regular.woff2 +0 -0
- package/src/fonts/icons.css +23 -0
- package/src/index.d.ts +1930 -0
- package/src/index.js +288 -0
- package/src/navigations/AdaptiveScaffold.js +149 -0
- package/src/navigations/AppBar.js +331 -0
- package/src/navigations/BottomNavigation.js +298 -0
- package/src/navigations/CollapsibleSideBar.js +139 -0
- package/src/navigations/Drawer.js +333 -0
- package/src/navigations/DrawerItem.js +260 -0
- package/src/navigations/Router.js +475 -0
- package/src/navigations/Scaffold.js +537 -0
- package/src/navigations/Tabs.js +384 -0
- package/src/navigations/index.js +57 -0
- package/src/services/RamStore.js +213 -0
- package/src/services/Session.js +310 -0
- package/src/services/Storage.js +309 -0
- package/src/services/http.js +350 -0
- package/src/services/index.js +57 -0
- package/src/tools/animation.js +42 -0
- package/src/tools/array.js +95 -0
- package/src/tools/border.js +28 -0
- package/src/tools/clipboard.js +104 -0
- package/src/tools/color.js +329 -0
- package/src/tools/createList.js +215 -0
- package/src/tools/delay.js +55 -0
- package/src/tools/device.js +138 -0
- package/src/tools/dict.js +297 -0
- package/src/tools/dimensions.js +118 -0
- package/src/tools/filter.js +41 -0
- package/src/tools/flex.js +26 -0
- package/src/tools/gradient.js +34 -0
- package/src/tools/grid.js +57 -0
- package/src/tools/index.js +38 -0
- package/src/tools/mapList.js +107 -0
- package/src/tools/margin.js +93 -0
- package/src/tools/memo.js +60 -0
- package/src/tools/os.js +104 -0
- package/src/tools/padding.js +93 -0
- package/src/tools/print.js +69 -0
- package/src/tools/random.js +299 -0
- package/src/tools/ref.js +70 -0
- package/src/tools/rgba.js +4 -0
- package/src/tools/shadow.js +23 -0
- package/src/tools/string.js +85 -0
- package/src/tools/time.js +674 -0
- package/src/tools/transform.js +68 -0
- package/src/tools/transition.js +48 -0
- package/src/tools/useState.js +268 -0
- package/src/tools/uuid.js +42 -0
- package/src/utils/TextInputValidator.js +256 -0
- package/src/utils/composeUpdate.js +65 -0
- package/src/utils/getWidgetProps.js +35 -0
- package/src/utils/index.js +76 -0
- package/src/utils/markdownParser.js +368 -0
- package/src/utils/mediaTime.js +79 -0
- package/src/utils/navigation.js +263 -0
- package/src/utils/scriptInjector.js +73 -0
- package/src/utils/stackPosition.js +31 -0
- package/src/utils/stopWebRefresh.js +77 -0
- package/src/utils/styleInjector.js +38 -0
- package/src/utils/syntaxHighlight.js +339 -0
- package/src/utils/themes.js +347 -0
- package/src/utils/units.js +87 -0
- package/src/utils/visualEffects.js +169 -0
- package/src/widget-factory/addChildren.js +114 -0
- package/src/widget-factory/assignProps.js +256 -0
- package/src/widget-factory/createWidget.js +28 -0
- package/src/widget-factory/effects.js +132 -0
- package/src/widget-factory/index.js +7 -0
- package/src/widget-factory/lifecycle.js +210 -0
- package/src/widget-factory/makeParentable.js +89 -0
- package/src/widget-factory/pixTool.js +40 -0
- package/src/widget-factory/processProps.js +122 -0
- package/src/widget-factory/reactivity.js +98 -0
- package/src/widget-factory/remTool.js +34 -0
- package/src/widget-factory/stackPosition.js +87 -0
- package/src/widget-factory/stringTool.js +26 -0
- package/src/widget-factory/tools.js +249 -0
- package/src/widget-factory/translateProps.js +1049 -0
- package/src/widget-factory/warnings.js +284 -0
- package/src/widget-factory/widgetFactory.js +200 -0
- package/src/widgets/Accordion.js +562 -0
- package/src/widgets/AdMob.js +315 -0
- package/src/widgets/AdSense.js +268 -0
- package/src/widgets/AlertDialog.js +162 -0
- package/src/widgets/Audio.js +311 -0
- package/src/widgets/Avatar.js +210 -0
- package/src/widgets/Badge.js +189 -0
- package/src/widgets/BottomSheet.js +287 -0
- package/src/widgets/Button.js +247 -0
- package/src/widgets/Card.js +33 -0
- package/src/widgets/Carousel.js +301 -0
- package/src/widgets/Chart.js +632 -0
- package/src/widgets/Checkbox.js +106 -0
- package/src/widgets/Chip.js +153 -0
- package/src/widgets/CircularBar.js +352 -0
- package/src/widgets/CircularChart.js +549 -0
- package/src/widgets/CodeViewer.js +236 -0
- package/src/widgets/Column.js +29 -0
- package/src/widgets/Container.js +31 -0
- package/src/widgets/DataTable.js +257 -0
- package/src/widgets/Divider.js +93 -0
- package/src/widgets/DraggBox.js +115 -0
- package/src/widgets/Dropdown.js +505 -0
- package/src/widgets/DroppBox.js +180 -0
- package/src/widgets/FloatingActionButton.js +91 -0
- package/src/widgets/GridView.js +20 -0
- package/src/widgets/Icon.js +33 -0
- package/src/widgets/Image.js +15 -0
- package/src/widgets/Input.js +565 -0
- package/src/widgets/Inspector.js +254 -0
- package/src/widgets/InstallButton.js +110 -0
- package/src/widgets/ListTile.js +224 -0
- package/src/widgets/ListView.js +503 -0
- package/src/widgets/Markdown.js +1236 -0
- package/src/widgets/Modal.js +496 -0
- package/src/widgets/Pagination.js +195 -0
- package/src/widgets/ProgressBar.js +178 -0
- package/src/widgets/QRCode.js +467 -0
- package/src/widgets/Radio.js +132 -0
- package/src/widgets/Rating.js +261 -0
- package/src/widgets/Row.js +29 -0
- package/src/widgets/Skeleton.js +243 -0
- package/src/widgets/Slider.js +527 -0
- package/src/widgets/SnackBar.js +227 -0
- package/src/widgets/Stack.js +29 -0
- package/src/widgets/Stepper.js +296 -0
- package/src/widgets/Switch.js +102 -0
- package/src/widgets/Text.js +98 -0
- package/src/widgets/Tooltip.js +267 -0
- package/src/widgets/TreeView.js +370 -0
- package/src/widgets/Video.js +92 -0
- package/src/widgets/index.js +52 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file TreeView.js
|
|
3
|
+
* @description Expandable tree with recursive node rendering.
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
import { colors } from "../utils/themes.js";
|
|
7
|
+
|
|
8
|
+
export const TreeView = (props) => {
|
|
9
|
+
const {
|
|
10
|
+
nodes = [],
|
|
11
|
+
onSelect,
|
|
12
|
+
onToggle,
|
|
13
|
+
/** @deprecated Use onPress instead */
|
|
14
|
+
onPress: onPressProp,
|
|
15
|
+
expandedNodes = [],
|
|
16
|
+
indent = 20,
|
|
17
|
+
showIcons = true,
|
|
18
|
+
folderIcon = "folder",
|
|
19
|
+
folderOpenIcon = "folder_open",
|
|
20
|
+
fileIcon = "insert_drive_file",
|
|
21
|
+
expandIcon = "chevron_right",
|
|
22
|
+
collapseIcon = "expand_more",
|
|
23
|
+
defaultExpanded = false,
|
|
24
|
+
selectable = true,
|
|
25
|
+
selectedNodeId = null,
|
|
26
|
+
|
|
27
|
+
// Color props for consistency
|
|
28
|
+
bgColor = "transparent",
|
|
29
|
+
hoverBgColor = colors.gray100,
|
|
30
|
+
selectedBgColor = `${colors.primary}20`,
|
|
31
|
+
textColor = colors.text,
|
|
32
|
+
selectedTextColor = colors.primary,
|
|
33
|
+
iconColor = colors.textSecondary,
|
|
34
|
+
folderIconColor = colors.warning,
|
|
35
|
+
borderColor = colors.border,
|
|
36
|
+
|
|
37
|
+
// Spacing props
|
|
38
|
+
nodePadding = "6px 4px",
|
|
39
|
+
nodeGap = 4,
|
|
40
|
+
childrenGap = 2,
|
|
41
|
+
borderRadius = 6,
|
|
42
|
+
|
|
43
|
+
// Font props
|
|
44
|
+
fontSize = 14,
|
|
45
|
+
iconSize = 18,
|
|
46
|
+
|
|
47
|
+
// Animation
|
|
48
|
+
transitionDuration = "0.2s",
|
|
49
|
+
|
|
50
|
+
...rest
|
|
51
|
+
} = props;
|
|
52
|
+
|
|
53
|
+
let expandedSet = new Set(expandedNodes);
|
|
54
|
+
let currentSelectedId = selectedNodeId;
|
|
55
|
+
let containerRef = null;
|
|
56
|
+
let isRendering = false;
|
|
57
|
+
|
|
58
|
+
// Initialize with default expanded if needed
|
|
59
|
+
if (defaultExpanded && expandedNodes.length === 0) {
|
|
60
|
+
const collectAllIds = (nodeList) => {
|
|
61
|
+
for (const node of nodeList) {
|
|
62
|
+
expandedSet.add(node.id);
|
|
63
|
+
if (node.children && node.children.length) {
|
|
64
|
+
collectAllIds(node.children);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
collectAllIds(nodes);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const collectAllIds = (nodeList) => {
|
|
72
|
+
let ids = [];
|
|
73
|
+
for (const node of nodeList) {
|
|
74
|
+
ids.push(node.id);
|
|
75
|
+
if (node.children && node.children.length) {
|
|
76
|
+
ids = ids.concat(collectAllIds(node.children));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return ids;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const renderNode = (node, level = 0) => {
|
|
83
|
+
const hasChildren = node.children && node.children.length > 0;
|
|
84
|
+
const isExpanded = expandedSet.has(node.id);
|
|
85
|
+
const isSelected = currentSelectedId === node.id;
|
|
86
|
+
|
|
87
|
+
// Node wrapper
|
|
88
|
+
const nodeWrapper = WidgetFactory({
|
|
89
|
+
tag: "div",
|
|
90
|
+
display: "flex",
|
|
91
|
+
flexDirection: "column",
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Node row
|
|
95
|
+
const nodeRow = WidgetFactory({
|
|
96
|
+
tag: "div",
|
|
97
|
+
display: "flex",
|
|
98
|
+
alignItems: "center",
|
|
99
|
+
gap: `${nodeGap}px`,
|
|
100
|
+
cursor: selectable ? "pointer" : "default",
|
|
101
|
+
backgroundColor: isSelected ? selectedBgColor : bgColor,
|
|
102
|
+
padding: nodePadding,
|
|
103
|
+
borderRadius:
|
|
104
|
+
typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius,
|
|
105
|
+
marginLeft: `${level * indent}px`,
|
|
106
|
+
transition: `background-color ${transitionDuration} ease`,
|
|
107
|
+
hoverBackgroundColor: hoverBgColor,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Add hover effect
|
|
111
|
+
if (selectable && !isSelected) {
|
|
112
|
+
nodeRow.addEventListener("mouseenter", () => {
|
|
113
|
+
nodeRow.style.backgroundColor = hoverBgColor;
|
|
114
|
+
});
|
|
115
|
+
nodeRow.addEventListener("mouseleave", () => {
|
|
116
|
+
nodeRow.style.backgroundColor = bgColor;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Selection handler
|
|
121
|
+
if (selectable) {
|
|
122
|
+
nodeRow.addEventListener("click", (e) => {
|
|
123
|
+
e.stopPropagation();
|
|
124
|
+
const selectCb = onSelect || onPressProp;
|
|
125
|
+
if (selectCb) {
|
|
126
|
+
currentSelectedId = node.id;
|
|
127
|
+
selectCb(node);
|
|
128
|
+
rerender();
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Expand/collapse button
|
|
134
|
+
if (hasChildren) {
|
|
135
|
+
const toggleBtn = WidgetFactory({
|
|
136
|
+
tag: "div",
|
|
137
|
+
width: "24px",
|
|
138
|
+
height: "24px",
|
|
139
|
+
display: "flex",
|
|
140
|
+
alignItems: "center",
|
|
141
|
+
justifyContent: "center",
|
|
142
|
+
cursor: "pointer",
|
|
143
|
+
borderRadius: "4px",
|
|
144
|
+
transition: `background-color ${transitionDuration} ease`,
|
|
145
|
+
child: WidgetFactory({
|
|
146
|
+
tag: "span",
|
|
147
|
+
className: "material-icons",
|
|
148
|
+
fontSize: `${iconSize}px`,
|
|
149
|
+
color: iconColor,
|
|
150
|
+
textContent: isExpanded ? collapseIcon : expandIcon,
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
toggleBtn.addEventListener("click", (e) => {
|
|
155
|
+
e.stopPropagation();
|
|
156
|
+
if (expandedSet.has(node.id)) {
|
|
157
|
+
expandedSet.delete(node.id);
|
|
158
|
+
} else {
|
|
159
|
+
expandedSet.add(node.id);
|
|
160
|
+
}
|
|
161
|
+
if (onToggle) onToggle(node.id, expandedSet.has(node.id));
|
|
162
|
+
rerender();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
nodeRow.appendChild(toggleBtn);
|
|
166
|
+
} else {
|
|
167
|
+
const spacer = WidgetFactory({
|
|
168
|
+
tag: "div",
|
|
169
|
+
width: "24px",
|
|
170
|
+
});
|
|
171
|
+
nodeRow.appendChild(spacer);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Node icon
|
|
175
|
+
if (showIcons) {
|
|
176
|
+
let iconName = node.icon;
|
|
177
|
+
if (!iconName) {
|
|
178
|
+
if (hasChildren) {
|
|
179
|
+
iconName = isExpanded ? folderOpenIcon : folderIcon;
|
|
180
|
+
} else {
|
|
181
|
+
iconName = fileIcon;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const iconSpan = WidgetFactory({
|
|
186
|
+
tag: "span",
|
|
187
|
+
className: "material-icons",
|
|
188
|
+
fontSize: `${iconSize + 2}px`,
|
|
189
|
+
color: node.iconColor || (hasChildren ? folderIconColor : iconColor),
|
|
190
|
+
textContent: iconName,
|
|
191
|
+
});
|
|
192
|
+
nodeRow.appendChild(iconSpan);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Node label
|
|
196
|
+
const labelSpan = WidgetFactory({
|
|
197
|
+
tag: "span",
|
|
198
|
+
flex: 1,
|
|
199
|
+
fontSize: `${fontSize}px`,
|
|
200
|
+
fontWeight: isSelected ? "bold" : "normal",
|
|
201
|
+
color: isSelected ? selectedTextColor : textColor,
|
|
202
|
+
textContent: node.label,
|
|
203
|
+
});
|
|
204
|
+
nodeRow.appendChild(labelSpan);
|
|
205
|
+
|
|
206
|
+
// Badge
|
|
207
|
+
if (node.badge) {
|
|
208
|
+
const badge = WidgetFactory({
|
|
209
|
+
tag: "div",
|
|
210
|
+
backgroundColor: colors.danger,
|
|
211
|
+
borderRadius: "12px",
|
|
212
|
+
padding: "2px 8px",
|
|
213
|
+
child: WidgetFactory({
|
|
214
|
+
tag: "span",
|
|
215
|
+
fontSize: "10px",
|
|
216
|
+
color: "#ffffff",
|
|
217
|
+
fontWeight: "bold",
|
|
218
|
+
textContent: String(node.badge),
|
|
219
|
+
}),
|
|
220
|
+
});
|
|
221
|
+
nodeRow.appendChild(badge);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
nodeWrapper.appendChild(nodeRow);
|
|
225
|
+
|
|
226
|
+
// Children
|
|
227
|
+
if (hasChildren && isExpanded) {
|
|
228
|
+
const childrenContainer = WidgetFactory({
|
|
229
|
+
tag: "div",
|
|
230
|
+
display: "flex",
|
|
231
|
+
flexDirection: "column",
|
|
232
|
+
gap: `${childrenGap}px`,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
node.children.forEach((child) => {
|
|
236
|
+
childrenContainer.appendChild(renderNode(child, level + 1));
|
|
237
|
+
});
|
|
238
|
+
nodeWrapper.appendChild(childrenContainer);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return nodeWrapper;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const rerender = () => {
|
|
245
|
+
if (isRendering || !containerRef) return;
|
|
246
|
+
isRendering = true;
|
|
247
|
+
|
|
248
|
+
// Clear container
|
|
249
|
+
while (containerRef.firstChild) {
|
|
250
|
+
containerRef.removeChild(containerRef.firstChild);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Build wrapper
|
|
254
|
+
const wrapper = WidgetFactory({
|
|
255
|
+
tag: "div",
|
|
256
|
+
display: "flex",
|
|
257
|
+
flexDirection: "column",
|
|
258
|
+
gap: `${childrenGap}px`,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
nodes.forEach((node) => {
|
|
262
|
+
wrapper.appendChild(renderNode(node, 0));
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
containerRef.appendChild(wrapper);
|
|
266
|
+
isRendering = false;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// Main container using WidgetFactory
|
|
270
|
+
const container = WidgetFactory({
|
|
271
|
+
tag: "div",
|
|
272
|
+
widgetName: "TreeView",
|
|
273
|
+
width: "100%",
|
|
274
|
+
overflow: "auto",
|
|
275
|
+
...rest,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
containerRef = container;
|
|
279
|
+
rerender();
|
|
280
|
+
|
|
281
|
+
// ========== PUBLIC METHODS ==========
|
|
282
|
+
|
|
283
|
+
container.updateNodes = (newNodes, selectedId = null) => {
|
|
284
|
+
nodes.length = 0;
|
|
285
|
+
nodes.push(...newNodes);
|
|
286
|
+
if (selectedId !== undefined) currentSelectedId = selectedId;
|
|
287
|
+
rerender();
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
container.expandAll = () => {
|
|
291
|
+
const allIds = collectAllIds(nodes);
|
|
292
|
+
allIds.forEach((id) => expandedSet.add(id));
|
|
293
|
+
rerender();
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
container.collapseAll = () => {
|
|
297
|
+
expandedSet.clear();
|
|
298
|
+
rerender();
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
container.expandTo = (nodeId) => {
|
|
302
|
+
const findPath = (nodeList, targetId, path = []) => {
|
|
303
|
+
for (const node of nodeList) {
|
|
304
|
+
if (node.id === targetId) return [...path, node.id];
|
|
305
|
+
if (node.children) {
|
|
306
|
+
const res = findPath(node.children, targetId, [...path, node.id]);
|
|
307
|
+
if (res) return res;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
};
|
|
312
|
+
const path = findPath(nodes, nodeId);
|
|
313
|
+
if (path) {
|
|
314
|
+
path.forEach((id) => expandedSet.add(id));
|
|
315
|
+
rerender();
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
container.collapseTo = (nodeId) => {
|
|
320
|
+
const findPath = (nodeList, targetId, path = []) => {
|
|
321
|
+
for (const node of nodeList) {
|
|
322
|
+
if (node.id === targetId) return [...path, node.id];
|
|
323
|
+
if (node.children) {
|
|
324
|
+
const res = findPath(node.children, targetId, [...path, node.id]);
|
|
325
|
+
if (res) return res;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
};
|
|
330
|
+
const path = findPath(nodes, nodeId);
|
|
331
|
+
if (path) {
|
|
332
|
+
// Keep only the path to target, remove deeper expansions
|
|
333
|
+
const toKeep = new Set(path);
|
|
334
|
+
for (const id of expandedSet) {
|
|
335
|
+
if (!toKeep.has(id)) expandedSet.delete(id);
|
|
336
|
+
}
|
|
337
|
+
rerender();
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
container.getExpanded = () => Array.from(expandedSet);
|
|
342
|
+
container.getSelected = () => currentSelectedId;
|
|
343
|
+
container.setSelected = (nodeId) => {
|
|
344
|
+
currentSelectedId = nodeId;
|
|
345
|
+
rerender();
|
|
346
|
+
const selectCb = onSelect || onPressProp;
|
|
347
|
+
if (selectCb) {
|
|
348
|
+
const findNode = (nodeList, targetId) => {
|
|
349
|
+
for (const node of nodeList) {
|
|
350
|
+
if (node.id === targetId) return node;
|
|
351
|
+
if (node.children) {
|
|
352
|
+
const found = findNode(node.children, targetId);
|
|
353
|
+
if (found) return found;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
};
|
|
358
|
+
const node = findNode(nodes, nodeId);
|
|
359
|
+
if (node) selectCb(node);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
if (typeof rest.ref === "function") {
|
|
364
|
+
rest.ref(container);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return container;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export default TreeView;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Video.js
|
|
3
|
+
* @description `<video>` wrapper; media attributes are set as element properties.
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
|
|
7
|
+
export const Video = (props) => {
|
|
8
|
+
const {
|
|
9
|
+
src,
|
|
10
|
+
width = "100%",
|
|
11
|
+
height = "auto",
|
|
12
|
+
autoplay = false,
|
|
13
|
+
controls = true,
|
|
14
|
+
loop = false,
|
|
15
|
+
muted = false,
|
|
16
|
+
poster,
|
|
17
|
+
ref,
|
|
18
|
+
...rest
|
|
19
|
+
} = props;
|
|
20
|
+
|
|
21
|
+
const video = WidgetFactory({
|
|
22
|
+
tag: "video",
|
|
23
|
+
widgetName: "Video",
|
|
24
|
+
src: src,
|
|
25
|
+
width: width,
|
|
26
|
+
height: height,
|
|
27
|
+
...rest,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Media attributes are element properties, not CSS — apply them directly.
|
|
31
|
+
video.controls = Boolean(controls);
|
|
32
|
+
video.loop = Boolean(loop);
|
|
33
|
+
video.muted = Boolean(muted);
|
|
34
|
+
video.autoplay = Boolean(autoplay);
|
|
35
|
+
if (poster) video.poster = poster;
|
|
36
|
+
|
|
37
|
+
// Save native methods
|
|
38
|
+
const nativePlay = video.play.bind(video);
|
|
39
|
+
const nativePause = video.pause.bind(video);
|
|
40
|
+
|
|
41
|
+
// Add custom methods BEFORE calling the ref
|
|
42
|
+
video.playVideo = () => {
|
|
43
|
+
nativePlay().catch((error) => console.warn("Video play failed:", error));
|
|
44
|
+
return video;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
video.pauseVideo = () => {
|
|
48
|
+
nativePause();
|
|
49
|
+
return video;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
video.stop = () => {
|
|
53
|
+
nativePause();
|
|
54
|
+
video.currentTime = 0;
|
|
55
|
+
return video;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
video.restart = () => {
|
|
59
|
+
video.currentTime = 0;
|
|
60
|
+
nativePlay();
|
|
61
|
+
return video;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
video.volumeUp = (step = 0.1) => {
|
|
65
|
+
video.volume = Math.min(1, video.volume + step);
|
|
66
|
+
return video;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
video.volumeDown = (step = 0.1) => {
|
|
70
|
+
video.volume = Math.max(0, video.volume - step);
|
|
71
|
+
return video;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
video.muteVideo = () => {
|
|
75
|
+
video.muted = true;
|
|
76
|
+
return video;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
video.unmuteVideo = () => {
|
|
80
|
+
video.muted = false;
|
|
81
|
+
return video;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Call the ref after adding the methods
|
|
85
|
+
if (ref && typeof ref === "function") {
|
|
86
|
+
ref(video);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return video;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default Video;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/widgets/index.js
|
|
2
|
+
export { AdSense } from "./AdSense.js";
|
|
3
|
+
export { AdMob } from "./AdMob.js";
|
|
4
|
+
export { Container } from "./Container.js";
|
|
5
|
+
export { Row } from "./Row.js";
|
|
6
|
+
export { Column } from "./Column.js";
|
|
7
|
+
export { Stack } from "./Stack.js";
|
|
8
|
+
export { ListView } from "./ListView.js";
|
|
9
|
+
export { GridView } from "./GridView.js";
|
|
10
|
+
export { Text } from "./Text.js";
|
|
11
|
+
export { Button } from "./Button.js";
|
|
12
|
+
export { Icon } from "./Icon.js";
|
|
13
|
+
export { Image } from "./Image.js";
|
|
14
|
+
export { Avatar } from "./Avatar.js";
|
|
15
|
+
export { Card } from "./Card.js";
|
|
16
|
+
export { ListTile } from "./ListTile.js";
|
|
17
|
+
export { ProgressBar } from "./ProgressBar.js";
|
|
18
|
+
export { Rating } from "./Rating.js";
|
|
19
|
+
export { Chip } from "./Chip.js";
|
|
20
|
+
export { Badge } from "./Badge.js";
|
|
21
|
+
export { Divider } from "./Divider.js";
|
|
22
|
+
export { Accordion } from "./Accordion.js";
|
|
23
|
+
export { Input } from "./Input.js";
|
|
24
|
+
export { Radio } from "./Radio.js";
|
|
25
|
+
export { Switch } from "./Switch.js";
|
|
26
|
+
export { Checkbox } from "./Checkbox.js";
|
|
27
|
+
export { Dropdown } from "./Dropdown.js";
|
|
28
|
+
export { SnackBar } from "./SnackBar.js";
|
|
29
|
+
export { Modal } from "./Modal.js";
|
|
30
|
+
export { BottomSheet } from "./BottomSheet.js";
|
|
31
|
+
export { AlertDialog } from "./AlertDialog.js";
|
|
32
|
+
export { FloatingActionButton } from "./FloatingActionButton.js";
|
|
33
|
+
export { CodeViewer } from "./CodeViewer.js";
|
|
34
|
+
export { Inspector, printWidgetCode, inspectWidget } from "./Inspector.js";
|
|
35
|
+
export { DraggBox } from "./DraggBox.js";
|
|
36
|
+
export { DroppBox } from "./DroppBox.js";
|
|
37
|
+
export { DataTable } from "./DataTable.js";
|
|
38
|
+
export { Carousel } from "./Carousel.js";
|
|
39
|
+
export { Tooltip } from "./Tooltip.js";
|
|
40
|
+
export { Pagination } from "./Pagination.js";
|
|
41
|
+
export { TreeView } from "./TreeView.js";
|
|
42
|
+
export { Stepper } from "./Stepper.js";
|
|
43
|
+
export { Skeleton } from "./Skeleton.js";
|
|
44
|
+
export { Chart } from "./Chart.js";
|
|
45
|
+
export { QRCode } from "./QRCode.js";
|
|
46
|
+
export { Slider } from "./Slider.js";
|
|
47
|
+
export { InstallButton } from "./InstallButton.js";
|
|
48
|
+
export { Video } from "./Video.js";
|
|
49
|
+
export { Audio } from "./Audio.js";
|
|
50
|
+
export { CircularBar } from "./CircularBar.js";
|
|
51
|
+
export { CircularChart } from "./CircularChart.js";
|
|
52
|
+
export { Markdown } from './Markdown.js';
|