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,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file CodeViewer.js
|
|
3
|
+
* @description Read-only code block with line numbers and syntax highlighting.
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
import { colors } from "../utils/themes.js";
|
|
7
|
+
import { generateHighlightedHtml } from "../utils/syntaxHighlight.js";
|
|
8
|
+
|
|
9
|
+
export const CodeViewer = (props) => {
|
|
10
|
+
const {
|
|
11
|
+
code = "",
|
|
12
|
+
title,
|
|
13
|
+
maxHeight = 400,
|
|
14
|
+
fontSize = 12,
|
|
15
|
+
backgroundColor = colors.gray100,
|
|
16
|
+
padding = 12,
|
|
17
|
+
borderRadius = 8,
|
|
18
|
+
showHeader = true,
|
|
19
|
+
showLineNumbers = false,
|
|
20
|
+
startingLineNumber = 1,
|
|
21
|
+
lineNumberWidth = 40,
|
|
22
|
+
lineNumberColor = colors.secondary,
|
|
23
|
+
...rest
|
|
24
|
+
} = props;
|
|
25
|
+
|
|
26
|
+
let currentCode =
|
|
27
|
+
typeof code === "string" ? code : JSON.stringify(code, null, 2);
|
|
28
|
+
let currentTitle = title;
|
|
29
|
+
let headerRef = null;
|
|
30
|
+
let scrollWrapperRef = null;
|
|
31
|
+
let lineNumbersColRef = null;
|
|
32
|
+
let codeColRef = null;
|
|
33
|
+
let codeWrapperRef = null;
|
|
34
|
+
|
|
35
|
+
const refreshContent = () => {
|
|
36
|
+
const lines = currentCode.split("\n");
|
|
37
|
+
const highlightedLines = lines.map((line) => generateHighlightedHtml(line));
|
|
38
|
+
|
|
39
|
+
if (showLineNumbers) {
|
|
40
|
+
// Update line numbers
|
|
41
|
+
if (lineNumbersColRef) {
|
|
42
|
+
lineNumbersColRef.innerHTML = "";
|
|
43
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44
|
+
const numberDiv = WidgetFactory({
|
|
45
|
+
tag: "div",
|
|
46
|
+
padding: `0 ${padding / 2}px 0 ${padding}px`,
|
|
47
|
+
whiteSpace: "pre",
|
|
48
|
+
textContent: String(startingLineNumber + i),
|
|
49
|
+
});
|
|
50
|
+
lineNumbersColRef.appendChild(numberDiv);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Update code
|
|
55
|
+
if (codeColRef) {
|
|
56
|
+
codeColRef.innerHTML = "";
|
|
57
|
+
for (let i = 0; i < lines.length; i++) {
|
|
58
|
+
const lineDiv = WidgetFactory({
|
|
59
|
+
tag: "div",
|
|
60
|
+
whiteSpace: "pre",
|
|
61
|
+
minHeight: "1.5em",
|
|
62
|
+
});
|
|
63
|
+
lineDiv.innerHTML = highlightedLines[i] || " ";
|
|
64
|
+
codeColRef.appendChild(lineDiv);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Update code without line numbers
|
|
69
|
+
if (codeWrapperRef) {
|
|
70
|
+
codeWrapperRef.innerHTML = highlightedLines.join("\n");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const container = WidgetFactory({
|
|
76
|
+
tag: "div",
|
|
77
|
+
widgetName: "CodeViewer",
|
|
78
|
+
width: "100%",
|
|
79
|
+
display: "flex",
|
|
80
|
+
flexDirection: "column",
|
|
81
|
+
...rest,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Header
|
|
85
|
+
if (currentTitle && showHeader) {
|
|
86
|
+
headerRef = WidgetFactory({
|
|
87
|
+
tag: "div",
|
|
88
|
+
padding: "8px 12px",
|
|
89
|
+
backgroundColor: colors.primary,
|
|
90
|
+
borderRadius: `${borderRadius}px ${borderRadius}px 0 0`,
|
|
91
|
+
color: "#fff",
|
|
92
|
+
fontSize: "14px",
|
|
93
|
+
fontWeight: "bold",
|
|
94
|
+
textContent: currentTitle,
|
|
95
|
+
});
|
|
96
|
+
container.appendChild(headerRef);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Scroll wrapper
|
|
100
|
+
scrollWrapperRef = WidgetFactory({
|
|
101
|
+
tag: "div",
|
|
102
|
+
backgroundColor,
|
|
103
|
+
borderRadius: currentTitle
|
|
104
|
+
? `0 0 ${borderRadius}px ${borderRadius}px`
|
|
105
|
+
: `${borderRadius}px`,
|
|
106
|
+
overflow: "auto",
|
|
107
|
+
maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
|
|
108
|
+
overflowX: "auto",
|
|
109
|
+
overflowY: "auto",
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Build content according to showLineNumbers
|
|
113
|
+
if (showLineNumbers) {
|
|
114
|
+
const flexContainer = WidgetFactory({
|
|
115
|
+
tag: "div",
|
|
116
|
+
display: "flex",
|
|
117
|
+
flexDirection: "row",
|
|
118
|
+
minWidth: "100%",
|
|
119
|
+
width: "fit-content",
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
lineNumbersColRef = WidgetFactory({
|
|
123
|
+
tag: "div",
|
|
124
|
+
backgroundColor,
|
|
125
|
+
borderRight: `1px solid ${colors.border}`,
|
|
126
|
+
padding: `${padding}px 0`,
|
|
127
|
+
fontFamily: "monospace",
|
|
128
|
+
fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize,
|
|
129
|
+
lineHeight: "1.5",
|
|
130
|
+
textAlign: "right",
|
|
131
|
+
color: lineNumberColor,
|
|
132
|
+
userSelect: "none",
|
|
133
|
+
width: `${lineNumberWidth}px`,
|
|
134
|
+
flexShrink: 0,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
codeColRef = WidgetFactory({
|
|
138
|
+
tag: "div",
|
|
139
|
+
padding: `${padding}px`,
|
|
140
|
+
fontFamily: "monospace",
|
|
141
|
+
fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize,
|
|
142
|
+
lineHeight: "1.5",
|
|
143
|
+
whiteSpace: "pre",
|
|
144
|
+
flex: 1,
|
|
145
|
+
overflowX: "visible",
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
flexContainer.appendChild(lineNumbersColRef);
|
|
149
|
+
flexContainer.appendChild(codeColRef);
|
|
150
|
+
scrollWrapperRef.appendChild(flexContainer);
|
|
151
|
+
|
|
152
|
+
// Sync scroll
|
|
153
|
+
const syncScroll = () => {
|
|
154
|
+
if (lineNumbersColRef) lineNumbersColRef.scrollTop = codeColRef.scrollTop;
|
|
155
|
+
};
|
|
156
|
+
codeColRef.addEventListener("scroll", syncScroll);
|
|
157
|
+
|
|
158
|
+
scrollWrapperRef.onUnmount(() => {
|
|
159
|
+
codeColRef.removeEventListener("scroll", syncScroll);
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
codeWrapperRef = WidgetFactory({
|
|
163
|
+
tag: "div",
|
|
164
|
+
padding: typeof padding === "number" ? `${padding}px` : padding,
|
|
165
|
+
fontFamily: "monospace",
|
|
166
|
+
fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize,
|
|
167
|
+
whiteSpace: "pre",
|
|
168
|
+
lineHeight: "1.5",
|
|
169
|
+
});
|
|
170
|
+
scrollWrapperRef.appendChild(codeWrapperRef);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
container.appendChild(scrollWrapperRef);
|
|
174
|
+
|
|
175
|
+
// Fill initial content
|
|
176
|
+
const lines = currentCode.split("\n");
|
|
177
|
+
const highlightedLines = lines.map((line) => generateHighlightedHtml(line));
|
|
178
|
+
|
|
179
|
+
if (showLineNumbers) {
|
|
180
|
+
for (let i = 0; i < lines.length; i++) {
|
|
181
|
+
const numberDiv = WidgetFactory({
|
|
182
|
+
tag: "div",
|
|
183
|
+
padding: `0 ${padding / 2}px 0 ${padding}px`,
|
|
184
|
+
whiteSpace: "pre",
|
|
185
|
+
textContent: String(startingLineNumber + i),
|
|
186
|
+
});
|
|
187
|
+
lineNumbersColRef.appendChild(numberDiv);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
for (let i = 0; i < lines.length; i++) {
|
|
191
|
+
const lineDiv = WidgetFactory({
|
|
192
|
+
tag: "div",
|
|
193
|
+
whiteSpace: "pre",
|
|
194
|
+
minHeight: "1.5em",
|
|
195
|
+
});
|
|
196
|
+
lineDiv.innerHTML = highlightedLines[i] || " ";
|
|
197
|
+
codeColRef.appendChild(lineDiv);
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
codeWrapperRef.innerHTML = highlightedLines.join("\n");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ========== PUBLIC METHODS ==========
|
|
204
|
+
container.updateCode = (newCode) => {
|
|
205
|
+
currentCode =
|
|
206
|
+
typeof newCode === "string" ? newCode : JSON.stringify(newCode, null, 2);
|
|
207
|
+
refreshContent();
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
container.updateTitle = (newTitle) => {
|
|
211
|
+
currentTitle = newTitle;
|
|
212
|
+
if (headerRef) {
|
|
213
|
+
headerRef.textContent = currentTitle;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
container.scrollTo = (x, y) => {
|
|
218
|
+
if (scrollWrapperRef) {
|
|
219
|
+
scrollWrapperRef.scrollLeft = x;
|
|
220
|
+
scrollWrapperRef.scrollTop = y;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
container.scrollToStart = () => {
|
|
225
|
+
if (scrollWrapperRef) scrollWrapperRef.scrollLeft = 0;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
container.scrollToEnd = () => {
|
|
229
|
+
if (scrollWrapperRef)
|
|
230
|
+
scrollWrapperRef.scrollLeft = scrollWrapperRef.scrollWidth;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return container;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
export default CodeViewer;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Column.js
|
|
3
|
+
* @description Vertical flex layout container (default `flex-direction: column`).
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
|
|
7
|
+
export const Column = (props = {}) => {
|
|
8
|
+
const {
|
|
9
|
+
display = "flex",
|
|
10
|
+
flexDirection = "column",
|
|
11
|
+
width = "100%",
|
|
12
|
+
height = "auto",
|
|
13
|
+
boxSizing = "border-box",
|
|
14
|
+
...rest
|
|
15
|
+
} = props;
|
|
16
|
+
|
|
17
|
+
return WidgetFactory({
|
|
18
|
+
tag: "div",
|
|
19
|
+
widgetName: "Column",
|
|
20
|
+
display: display,
|
|
21
|
+
flexDirection: flexDirection,
|
|
22
|
+
width: width,
|
|
23
|
+
height: height,
|
|
24
|
+
boxSizing: boxSizing,
|
|
25
|
+
...rest,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default Column;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Container.js
|
|
3
|
+
* @description General-purpose surface container: flex column with overflow and
|
|
4
|
+
* the theme's surface background by default.
|
|
5
|
+
*/
|
|
6
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
7
|
+
import { colors } from "../utils/themes.js";
|
|
8
|
+
|
|
9
|
+
export const Container = (props = {}) => {
|
|
10
|
+
const {
|
|
11
|
+
display = "flex",
|
|
12
|
+
flexDirection = "column",
|
|
13
|
+
overflow = "auto",
|
|
14
|
+
boxSizing = "border-box",
|
|
15
|
+
bgColor = colors.surface,
|
|
16
|
+
...rest
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
return WidgetFactory({
|
|
20
|
+
tag: "div",
|
|
21
|
+
widgetName: "Container",
|
|
22
|
+
display: display,
|
|
23
|
+
flexDirection: flexDirection,
|
|
24
|
+
overflow: overflow,
|
|
25
|
+
boxSizing: boxSizing,
|
|
26
|
+
backgroundColor: bgColor,
|
|
27
|
+
...rest,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default Container;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file DataTable.js
|
|
3
|
+
* @description Table renderer with configurable columns and rows.
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
import { colors } from "../utils/themes.js";
|
|
7
|
+
|
|
8
|
+
export const DataTable = (props) => {
|
|
9
|
+
const {
|
|
10
|
+
columns,
|
|
11
|
+
rows,
|
|
12
|
+
striped = true,
|
|
13
|
+
hoverable = true,
|
|
14
|
+
bordered = true,
|
|
15
|
+
onRowClick,
|
|
16
|
+
|
|
17
|
+
// ========== COLOR PROPS ==========
|
|
18
|
+
headerBgColor = colors.gray100,
|
|
19
|
+
headerTextColor = colors.text,
|
|
20
|
+
headerFontWeight = "bold",
|
|
21
|
+
headerFontSize = 14,
|
|
22
|
+
|
|
23
|
+
rowBgColor = "transparent",
|
|
24
|
+
rowTextColor = colors.text,
|
|
25
|
+
rowFontSize = 13,
|
|
26
|
+
|
|
27
|
+
stripedRowBgColor = colors.gray50,
|
|
28
|
+
|
|
29
|
+
hoverRowBgColor = `${colors.primary}10`,
|
|
30
|
+
|
|
31
|
+
borderColor = colors.border,
|
|
32
|
+
borderWidth = 1,
|
|
33
|
+
|
|
34
|
+
cellPadding = "10px 12px",
|
|
35
|
+
headerCellPadding = "12px",
|
|
36
|
+
|
|
37
|
+
// ========== OTHER PROPS ==========
|
|
38
|
+
...rest
|
|
39
|
+
} = props;
|
|
40
|
+
|
|
41
|
+
// Main container with WidgetFactory
|
|
42
|
+
const container = WidgetFactory({
|
|
43
|
+
widgetName: "DataTable",
|
|
44
|
+
width: "100%",
|
|
45
|
+
overflowX: "auto",
|
|
46
|
+
...rest,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Createste table element
|
|
50
|
+
const table = document.createElement("table");
|
|
51
|
+
table.style.width = "100%";
|
|
52
|
+
table.style.borderCollapse = "collapse";
|
|
53
|
+
table.style.border = bordered
|
|
54
|
+
? `${borderWidth}px solid ${borderColor}`
|
|
55
|
+
: "none";
|
|
56
|
+
|
|
57
|
+
// ========== HEADER ==========
|
|
58
|
+
const thead = document.createElement("thead");
|
|
59
|
+
const headerRow = document.createElement("tr");
|
|
60
|
+
|
|
61
|
+
for (const col of columns) {
|
|
62
|
+
const th = document.createElement("th");
|
|
63
|
+
th.textContent = typeof col === "string" ? col : col.label;
|
|
64
|
+
th.style.padding = headerCellPadding;
|
|
65
|
+
th.style.textAlign = "left";
|
|
66
|
+
th.style.borderBottom = `2px solid ${borderColor}`;
|
|
67
|
+
th.style.backgroundColor = headerBgColor;
|
|
68
|
+
th.style.color = headerTextColor;
|
|
69
|
+
th.style.fontWeight = headerFontWeight;
|
|
70
|
+
th.style.fontSize =
|
|
71
|
+
typeof headerFontSize === "number"
|
|
72
|
+
? `${headerFontSize}px`
|
|
73
|
+
: headerFontSize;
|
|
74
|
+
|
|
75
|
+
// Custom alignment per column
|
|
76
|
+
if (typeof col !== "string" && col.align) {
|
|
77
|
+
th.style.textAlign = col.align;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
headerRow.appendChild(th);
|
|
81
|
+
}
|
|
82
|
+
thead.appendChild(headerRow);
|
|
83
|
+
table.appendChild(thead);
|
|
84
|
+
|
|
85
|
+
// ========== BODY ==========
|
|
86
|
+
const tbody = document.createElement("tbody");
|
|
87
|
+
|
|
88
|
+
rows.forEach((row, index) => {
|
|
89
|
+
const tr = document.createElement("tr");
|
|
90
|
+
|
|
91
|
+
// Row background color (striped or normal)
|
|
92
|
+
if (striped && index % 2 === 1) {
|
|
93
|
+
tr.style.backgroundColor = stripedRowBgColor;
|
|
94
|
+
} else {
|
|
95
|
+
tr.style.backgroundColor = rowBgColor;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Hover effect
|
|
99
|
+
if (hoverable) {
|
|
100
|
+
tr.style.transition = "background-color 0.2s";
|
|
101
|
+
tr.addEventListener("mouseenter", () => {
|
|
102
|
+
tr.style.backgroundColor = hoverRowBgColor;
|
|
103
|
+
});
|
|
104
|
+
tr.addEventListener("mouseleave", () => {
|
|
105
|
+
tr.style.backgroundColor =
|
|
106
|
+
striped && index % 2 === 1 ? stripedRowBgColor : rowBgColor;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Row click handler
|
|
111
|
+
if (onRowClick) {
|
|
112
|
+
tr.style.cursor = "pointer";
|
|
113
|
+
tr.addEventListener("click", () => onRowClick(row, index));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Cells
|
|
117
|
+
for (const col of columns) {
|
|
118
|
+
const td = document.createElement("td");
|
|
119
|
+
const key = typeof col === "string" ? col : col.key;
|
|
120
|
+
const value = row[key];
|
|
121
|
+
|
|
122
|
+
td.textContent = value !== undefined ? String(value) : "";
|
|
123
|
+
td.style.padding = cellPadding;
|
|
124
|
+
td.style.borderBottom = `${borderWidth}px solid ${borderColor}`;
|
|
125
|
+
td.style.color = rowTextColor;
|
|
126
|
+
td.style.fontSize =
|
|
127
|
+
typeof rowFontSize === "number" ? `${rowFontSize}px` : rowFontSize;
|
|
128
|
+
|
|
129
|
+
// Custom alignment per column
|
|
130
|
+
if (typeof col !== "string" && col.align) {
|
|
131
|
+
td.style.textAlign = col.align;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Custom formatter per column
|
|
135
|
+
if (
|
|
136
|
+
typeof col !== "string" &&
|
|
137
|
+
col.format &&
|
|
138
|
+
typeof col.format === "function"
|
|
139
|
+
) {
|
|
140
|
+
td.textContent = col.format(value, row);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
tr.appendChild(td);
|
|
144
|
+
}
|
|
145
|
+
tbody.appendChild(tr);
|
|
146
|
+
});
|
|
147
|
+
table.appendChild(tbody);
|
|
148
|
+
|
|
149
|
+
container.appendChild(table);
|
|
150
|
+
|
|
151
|
+
// ========== PUBLIC METHODS ==========
|
|
152
|
+
|
|
153
|
+
// Update table data
|
|
154
|
+
container.updateData = (newRows) => {
|
|
155
|
+
rows.length = 0;
|
|
156
|
+
rows.push(...newRows);
|
|
157
|
+
|
|
158
|
+
// Rebuild body
|
|
159
|
+
const newTbody = document.createElement("tbody");
|
|
160
|
+
|
|
161
|
+
newRows.forEach((row, index) => {
|
|
162
|
+
const tr = document.createElement("tr");
|
|
163
|
+
|
|
164
|
+
if (striped && index % 2 === 1) {
|
|
165
|
+
tr.style.backgroundColor = stripedRowBgColor;
|
|
166
|
+
} else {
|
|
167
|
+
tr.style.backgroundColor = rowBgColor;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (hoverable) {
|
|
171
|
+
tr.style.transition = "background-color 0.2s";
|
|
172
|
+
tr.addEventListener("mouseenter", () => {
|
|
173
|
+
tr.style.backgroundColor = hoverRowBgColor;
|
|
174
|
+
});
|
|
175
|
+
tr.addEventListener("mouseleave", () => {
|
|
176
|
+
tr.style.backgroundColor =
|
|
177
|
+
striped && index % 2 === 1 ? stripedRowBgColor : rowBgColor;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (onRowClick) {
|
|
182
|
+
tr.style.cursor = "pointer";
|
|
183
|
+
tr.addEventListener("click", () => onRowClick(row, index));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
for (const col of columns) {
|
|
187
|
+
const td = document.createElement("td");
|
|
188
|
+
const key = typeof col === "string" ? col : col.key;
|
|
189
|
+
const value = row[key];
|
|
190
|
+
|
|
191
|
+
td.textContent = value !== undefined ? String(value) : "";
|
|
192
|
+
td.style.padding = cellPadding;
|
|
193
|
+
td.style.borderBottom = `${borderWidth}px solid ${borderColor}`;
|
|
194
|
+
td.style.color = rowTextColor;
|
|
195
|
+
td.style.fontSize =
|
|
196
|
+
typeof rowFontSize === "number" ? `${rowFontSize}px` : rowFontSize;
|
|
197
|
+
|
|
198
|
+
if (typeof col !== "string" && col.align) {
|
|
199
|
+
td.style.textAlign = col.align;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (
|
|
203
|
+
typeof col !== "string" &&
|
|
204
|
+
col.format &&
|
|
205
|
+
typeof col.format === "function"
|
|
206
|
+
) {
|
|
207
|
+
td.textContent = col.format(value, row);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
tr.appendChild(td);
|
|
211
|
+
}
|
|
212
|
+
newTbody.appendChild(tr);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
table.replaceChild(newTbody, tbody);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Update table columns
|
|
219
|
+
container.updateColumns = (newColumns) => {
|
|
220
|
+
columns.length = 0;
|
|
221
|
+
columns.push(...newColumns);
|
|
222
|
+
|
|
223
|
+
// Rebuild header
|
|
224
|
+
const newThead = document.createElement("thead");
|
|
225
|
+
const newHeaderRow = document.createElement("tr");
|
|
226
|
+
|
|
227
|
+
for (const col of newColumns) {
|
|
228
|
+
const th = document.createElement("th");
|
|
229
|
+
th.textContent = typeof col === "string" ? col : col.label;
|
|
230
|
+
th.style.padding = headerCellPadding;
|
|
231
|
+
th.style.textAlign = "left";
|
|
232
|
+
th.style.borderBottom = `2px solid ${borderColor}`;
|
|
233
|
+
th.style.backgroundColor = headerBgColor;
|
|
234
|
+
th.style.color = headerTextColor;
|
|
235
|
+
th.style.fontWeight = headerFontWeight;
|
|
236
|
+
th.style.fontSize =
|
|
237
|
+
typeof headerFontSize === "number"
|
|
238
|
+
? `${headerFontSize}px`
|
|
239
|
+
: headerFontSize;
|
|
240
|
+
|
|
241
|
+
if (typeof col !== "string" && col.align) {
|
|
242
|
+
th.style.textAlign = col.align;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
newHeaderRow.appendChild(th);
|
|
246
|
+
}
|
|
247
|
+
newThead.appendChild(newHeaderRow);
|
|
248
|
+
table.replaceChild(newThead, thead);
|
|
249
|
+
|
|
250
|
+
// Rebuild body with existing rows
|
|
251
|
+
container.updateData(rows);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
return container;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
export default DataTable;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Divider.js
|
|
3
|
+
* @description Horizontal/vertical rule with configurable thickness and margins.
|
|
4
|
+
*/
|
|
5
|
+
import { WidgetFactory } from "../widget-factory/index.js";
|
|
6
|
+
import { colors } from "../utils/themes.js";
|
|
7
|
+
|
|
8
|
+
export const Divider = (props = {}) => {
|
|
9
|
+
const {
|
|
10
|
+
color = colors.surface,
|
|
11
|
+
thickness = 1,
|
|
12
|
+
margin = 16,
|
|
13
|
+
orientation = "horizontal",
|
|
14
|
+
width = "100%",
|
|
15
|
+
height = "100%",
|
|
16
|
+
flexShrink = 0,
|
|
17
|
+
marginTop: propMarginTop,
|
|
18
|
+
marginBottom: propMarginBottom,
|
|
19
|
+
marginLeft: propMarginLeft,
|
|
20
|
+
marginRight: propMarginRight,
|
|
21
|
+
...rest
|
|
22
|
+
} = props;
|
|
23
|
+
|
|
24
|
+
const isHorizontal = orientation === "horizontal";
|
|
25
|
+
|
|
26
|
+
// Determine margin values with proper priority:
|
|
27
|
+
// 1. Individual props (marginTop, marginBottom, etc.)
|
|
28
|
+
// 2. margin object (margin.top, margin.bottom, etc.)
|
|
29
|
+
// 3. margin number (applied to all sides)
|
|
30
|
+
// 4. Default values
|
|
31
|
+
|
|
32
|
+
let finalMarginTop = propMarginTop ?? 0;
|
|
33
|
+
let finalMarginBottom = propMarginBottom ?? 0;
|
|
34
|
+
let finalMarginLeft = propMarginLeft ?? 0;
|
|
35
|
+
let finalMarginRight = propMarginRight ?? 0;
|
|
36
|
+
|
|
37
|
+
if (typeof margin === "number") {
|
|
38
|
+
if (isHorizontal) {
|
|
39
|
+
finalMarginTop = margin;
|
|
40
|
+
finalMarginBottom = margin;
|
|
41
|
+
} else {
|
|
42
|
+
finalMarginLeft = margin;
|
|
43
|
+
finalMarginRight = margin;
|
|
44
|
+
}
|
|
45
|
+
} else if (margin && typeof margin === "object") {
|
|
46
|
+
if (isHorizontal) {
|
|
47
|
+
finalMarginTop = margin.top ?? finalMarginTop;
|
|
48
|
+
finalMarginBottom = margin.bottom ?? finalMarginBottom;
|
|
49
|
+
} else {
|
|
50
|
+
finalMarginLeft = margin.left ?? finalMarginLeft;
|
|
51
|
+
finalMarginRight = margin.right ?? finalMarginRight;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// If margin is a string, use it directly (overrides everything)
|
|
56
|
+
const useMarginString = typeof margin === "string";
|
|
57
|
+
|
|
58
|
+
// Createste widget
|
|
59
|
+
const widget = WidgetFactory({
|
|
60
|
+
tag: "div",
|
|
61
|
+
widgetName: "Divider",
|
|
62
|
+
backgroundColor: color,
|
|
63
|
+
flexShrink: flexShrink,
|
|
64
|
+
...rest,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Apply divider-specific props
|
|
68
|
+
if (isHorizontal) {
|
|
69
|
+
widget.update({
|
|
70
|
+
height: thickness,
|
|
71
|
+
width: width,
|
|
72
|
+
marginTop: finalMarginTop,
|
|
73
|
+
marginBottom: finalMarginBottom,
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
widget.update({
|
|
77
|
+
width: thickness,
|
|
78
|
+
height: height,
|
|
79
|
+
minHeight: 1,
|
|
80
|
+
marginLeft: finalMarginLeft,
|
|
81
|
+
marginRight: finalMarginRight,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If margin is a string, apply it directly (overrides individual margins)
|
|
86
|
+
if (useMarginString) {
|
|
87
|
+
widget.update({ margin: margin });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return widget;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default Divider;
|