plusui-native 0.2.93 → 0.2.97
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plusui-native",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.97",
|
|
4
4
|
"description": "PlusUI CLI - Build C++ desktop apps modern UI ",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"semver": "^7.6.0",
|
|
28
28
|
"which": "^4.0.0",
|
|
29
29
|
"execa": "^8.0.1",
|
|
30
|
-
"plusui-native-builder": "^0.1.
|
|
31
|
-
"plusui-native-connect": "^0.1.
|
|
30
|
+
"plusui-native-builder": "^0.1.95",
|
|
31
|
+
"plusui-native-connect": "^0.1.95"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"plusui-native-connect": "^0.1.
|
|
34
|
+
"plusui-native-connect": "^0.1.95"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
@@ -1,46 +1,14 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
1
|
import plusui from 'plusui';
|
|
3
2
|
|
|
4
|
-
// That's the only import you need.
|
|
5
|
-
// All features are available directly:
|
|
6
|
-
// plusui.window — show, hide, minimize, maximize, setTitle, setSize ...
|
|
7
|
-
// plusui.app — quit
|
|
8
|
-
// plusui.router — push, setRoutes
|
|
9
|
-
// plusui.clipboard— getText, setText
|
|
10
|
-
// plusui.fileDrop — onFilesDropped, setEnabled
|
|
11
|
-
// plusui.tray — setIcon, setTooltip, onClick
|
|
12
|
-
|
|
13
3
|
function App() {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
plusui.window.show();
|
|
23
|
-
|
|
24
|
-
// Window events — fire automatically, no wiring in main.cpp needed.
|
|
25
|
-
const unsubResize = plusui.window.onResize((size: { width: number; height: number }) => setWindowSize(size));
|
|
26
|
-
const unsubState = plusui.window.onStateChange((state: { isMaximized: boolean; isMinimized: boolean; isVisible: boolean; isFullscreen: boolean }) => setIsMaximized(state.isMaximized));
|
|
27
|
-
|
|
28
|
-
// File drop — built-in, works out of the box.
|
|
29
|
-
const unsubDrop = plusui.fileDrop.onFilesDropped((files: { name: string; size: number; type: string }[]) => setDroppedFiles(files));
|
|
30
|
-
const unsubEnter = plusui.fileDrop.onDragEnter(() => setIsDragging(true));
|
|
31
|
-
const unsubLeave = plusui.fileDrop.onDragLeave(() => setIsDragging(false));
|
|
32
|
-
|
|
33
|
-
// Seed initial size
|
|
34
|
-
plusui.window.getSize().then((size: { width: number; height: number } | null) => { if (size) setWindowSize(size); });
|
|
35
|
-
|
|
36
|
-
return () => {
|
|
37
|
-
unsubResize();
|
|
38
|
-
unsubState();
|
|
39
|
-
unsubDrop();
|
|
40
|
-
unsubEnter();
|
|
41
|
-
unsubLeave();
|
|
42
|
-
};
|
|
43
|
-
}, []);
|
|
4
|
+
const handleShow = () => plusui.window.show();
|
|
5
|
+
const handleHide = () => plusui.window.hide();
|
|
6
|
+
const handleMinimize = () => plusui.window.minimize();
|
|
7
|
+
const handleMaximize = () => plusui.window.maximize();
|
|
8
|
+
const handleRestore = () => plusui.window.restore();
|
|
9
|
+
const handleClose = () => plusui.window.close();
|
|
10
|
+
const handleCenter = () => plusui.window.center();
|
|
11
|
+
const handleQuit = () => plusui.app.quit();
|
|
44
12
|
|
|
45
13
|
return (
|
|
46
14
|
<div className="app">
|
|
@@ -50,68 +18,28 @@ function App() {
|
|
|
50
18
|
</header>
|
|
51
19
|
|
|
52
20
|
<main className="app-content">
|
|
53
|
-
|
|
54
|
-
{/* ── Window ─────────────────────────────────────────────── */}
|
|
55
21
|
<div className="card">
|
|
56
22
|
<h2>Window</h2>
|
|
57
23
|
<div className="button-group">
|
|
58
|
-
<button className="button" onClick={
|
|
59
|
-
<button className="button" onClick={
|
|
60
|
-
<button className="button" onClick={
|
|
61
|
-
<button className="button" onClick={
|
|
62
|
-
|
|
63
|
-
</button>
|
|
64
|
-
<button className="button" onClick={
|
|
65
|
-
<button className="button button-danger" onClick={() => plusui.window.close()}>Close</button>
|
|
24
|
+
<button className="button" onClick={handleShow}>Show</button>
|
|
25
|
+
<button className="button" onClick={handleHide}>Hide</button>
|
|
26
|
+
<button className="button" onClick={handleMinimize}>Minimize</button>
|
|
27
|
+
<button className="button" onClick={handleMaximize}>Maximize</button>
|
|
28
|
+
<button className="button" onClick={handleRestore}>Restore</button>
|
|
29
|
+
<button className="button" onClick={handleCenter}>Center</button>
|
|
30
|
+
<button className="button button-danger" onClick={handleClose}>Close</button>
|
|
66
31
|
</div>
|
|
67
|
-
{windowSize.width > 0 && (
|
|
68
|
-
<p className="info-text">Size: {windowSize.width} × {windowSize.height}</p>
|
|
69
|
-
)}
|
|
70
32
|
</div>
|
|
71
33
|
|
|
72
|
-
{/* ── App ────────────────────────────────────────────────── */}
|
|
73
34
|
<div className="card">
|
|
74
35
|
<h2>App</h2>
|
|
75
|
-
<button className="button button-danger" onClick={
|
|
76
|
-
</div>
|
|
77
|
-
|
|
78
|
-
{/* ── File Drop ──────────────────────────────────────────── */}
|
|
79
|
-
<div className="card">
|
|
80
|
-
<h2>File Drop</h2>
|
|
81
|
-
<div
|
|
82
|
-
className={`filedrop-zone ${isDragging ? 'filedrop-active' : ''}`}
|
|
83
|
-
data-dropzone="true"
|
|
84
|
-
>
|
|
85
|
-
<div className="filedrop-content">
|
|
86
|
-
<div className="filedrop-text">
|
|
87
|
-
{isDragging ? 'Drop files here' : 'Drag & drop files here'}
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
{droppedFiles.length > 0 && (
|
|
93
|
-
<div className="filedrop-files" style={{ marginTop: '1rem' }}>
|
|
94
|
-
{droppedFiles.map((file: { name: string; size: number; type: string }, i: number) => (
|
|
95
|
-
<div key={i} className="filedrop-file-item">
|
|
96
|
-
<div className="filedrop-file-icon">📄</div>
|
|
97
|
-
<div className="filedrop-file-info">
|
|
98
|
-
<div className="filedrop-file-name">{file.name}</div>
|
|
99
|
-
<div className="filedrop-file-meta">
|
|
100
|
-
{plusui.formatFileSize(file.size)} · {file.type || 'unknown'}
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
))}
|
|
105
|
-
</div>
|
|
106
|
-
)}
|
|
36
|
+
<button className="button button-danger" onClick={handleQuit}>Quit</button>
|
|
107
37
|
</div>
|
|
108
38
|
|
|
109
39
|
<div className="info">
|
|
110
|
-
<p>Edit <code>frontend/src/App.tsx</code> for
|
|
111
|
-
<p>Edit <code>main.cpp</code> for
|
|
112
|
-
<p>Run <code>plusui connect</code> to add custom C++ ↔ frontend channels.</p>
|
|
40
|
+
<p>Edit <code>frontend/src/App.tsx</code> for UI</p>
|
|
41
|
+
<p>Edit <code>main.cpp</code> for backend</p>
|
|
113
42
|
</div>
|
|
114
|
-
|
|
115
43
|
</main>
|
|
116
44
|
</div>
|
|
117
45
|
);
|
|
@@ -7,11 +7,10 @@ import { existsSync } from 'fs';
|
|
|
7
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
8
|
const __dirname = dirname(__filename);
|
|
9
9
|
|
|
10
|
-
// Resolve plusui-native-core entry directly (bypasses package.json exports)
|
|
11
10
|
function findPlusuiEntry(): string {
|
|
12
11
|
const candidates = [
|
|
12
|
+
resolve(__dirname, '../../Core/Features/API/index.ts'),
|
|
13
13
|
resolve(__dirname, '../node_modules/plusui-native-core/Core/Features/API/index.ts'),
|
|
14
|
-
resolve(__dirname, '../node_modules/plusui-native-core/Core/API/index.ts'),
|
|
15
14
|
];
|
|
16
15
|
for (const p of candidates) {
|
|
17
16
|
if (existsSync(p)) return p;
|
|
@@ -35,4 +34,3 @@ export default defineConfig({
|
|
|
35
34
|
strictPort: true,
|
|
36
35
|
},
|
|
37
36
|
});
|
|
38
|
-
|
|
@@ -1,118 +1,41 @@
|
|
|
1
|
-
import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
2
1
|
import plusui from 'plusui';
|
|
3
2
|
|
|
4
|
-
// That's the only import you need.
|
|
5
|
-
// All features are available directly:
|
|
6
|
-
// plusui.window — show, hide, minimize, maximize, setTitle, setSize ...
|
|
7
|
-
// plusui.app — quit
|
|
8
|
-
// plusui.router — push, setRoutes
|
|
9
|
-
// plusui.clipboard— getText, setText
|
|
10
|
-
// plusui.fileDrop — onFilesDropped, setEnabled
|
|
11
|
-
// plusui.tray — setIcon, setTooltip, onClick
|
|
12
|
-
|
|
13
3
|
function App() {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
plusui.window.show();
|
|
23
|
-
|
|
24
|
-
// Window events — fire automatically, no wiring in main.cpp needed.
|
|
25
|
-
const unsubResize = plusui.window.onResize((size: { width: number; height: number }) => setWindowSize(size));
|
|
26
|
-
const unsubState = plusui.window.onStateChange((state: { isMaximized: boolean; isMinimized: boolean; isVisible: boolean; isFullscreen: boolean }) => setIsMaximized(state.isMaximized));
|
|
27
|
-
|
|
28
|
-
// File drop — built-in, works out of the box.
|
|
29
|
-
const unsubDrop = plusui.fileDrop.onFilesDropped((files: { name: string; size: number; type: string }[]) => setDroppedFiles(files));
|
|
30
|
-
const unsubEnter = plusui.fileDrop.onDragEnter(() => setIsDragging(true));
|
|
31
|
-
const unsubLeave = plusui.fileDrop.onDragLeave(() => setIsDragging(false));
|
|
32
|
-
|
|
33
|
-
// Seed initial size
|
|
34
|
-
plusui.window.getSize().then((size: { width: number; height: number } | null) => { if (size) setWindowSize(size); });
|
|
35
|
-
|
|
36
|
-
onCleanup(() => {
|
|
37
|
-
unsubResize();
|
|
38
|
-
unsubState();
|
|
39
|
-
unsubDrop();
|
|
40
|
-
unsubEnter();
|
|
41
|
-
unsubLeave();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
4
|
+
const handleShow = () => plusui.window.show();
|
|
5
|
+
const handleHide = () => plusui.window.hide();
|
|
6
|
+
const handleMinimize = () => plusui.window.minimize();
|
|
7
|
+
const handleMaximize = () => plusui.window.maximize();
|
|
8
|
+
const handleRestore = () => plusui.window.restore();
|
|
9
|
+
const handleClose = () => plusui.window.close();
|
|
10
|
+
const handleCenter = () => plusui.window.center();
|
|
11
|
+
const handleQuit = () => plusui.app.quit();
|
|
44
12
|
|
|
45
13
|
return (
|
|
46
14
|
<div class="app">
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
<button class="button" onClick={() => plusui.window.hide()}>Hide</button>
|
|
60
|
-
<button class="button" onClick={() => plusui.window.minimize()}>Minimize</button>
|
|
61
|
-
<button class="button" onClick={() => isMaximized() ? plusui.window.restore() : plusui.window.maximize()}>
|
|
62
|
-
{isMaximized() ? 'Restore' : 'Maximize'}
|
|
63
|
-
</button>
|
|
64
|
-
<button class="button" onClick={() => plusui.window.center()}>Center</button>
|
|
65
|
-
<button class="button button-danger" onClick={() => plusui.window.close()}>Close</button>
|
|
66
|
-
</div>
|
|
67
|
-
{windowSize().width > 0 && (
|
|
68
|
-
<p class="info-text">Size: {windowSize().width} × {windowSize().height}</p>
|
|
69
|
-
)}
|
|
70
|
-
</div>
|
|
71
|
-
|
|
72
|
-
{/* ── App ────────────────────────────────────────────────── */}
|
|
73
|
-
<div class="card">
|
|
74
|
-
<h2>App</h2>
|
|
75
|
-
<button class="button button-danger" onClick={() => plusui.app.quit()}>Quit</button>
|
|
15
|
+
<h1 class="title">{{PROJECT_NAME}}</h1>
|
|
16
|
+
|
|
17
|
+
<section class="section">
|
|
18
|
+
<h2>Window</h2>
|
|
19
|
+
<div class="buttons">
|
|
20
|
+
<button onClick={handleShow}>Show</button>
|
|
21
|
+
<button onClick={handleHide}>Hide</button>
|
|
22
|
+
<button onClick={handleMinimize}>Minimize</button>
|
|
23
|
+
<button onClick={handleMaximize}>Maximize</button>
|
|
24
|
+
<button onClick={handleRestore}>Restore</button>
|
|
25
|
+
<button onClick={handleCenter}>Center</button>
|
|
26
|
+
<button class="danger" onClick={handleClose}>Close</button>
|
|
76
27
|
</div>
|
|
28
|
+
</section>
|
|
77
29
|
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class={`filedrop-zone ${isDragging() ? 'filedrop-active' : ''}`}
|
|
83
|
-
data-dropzone="true"
|
|
84
|
-
>
|
|
85
|
-
<div class="filedrop-content">
|
|
86
|
-
<div class="filedrop-text">
|
|
87
|
-
{isDragging() ? 'Drop files here' : 'Drag & drop files here'}
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
{droppedFiles().length > 0 && (
|
|
93
|
-
<div class="filedrop-files" style={{ 'margin-top': '1rem' }}>
|
|
94
|
-
{droppedFiles().map((file: { name: string; size: number; type: string }) => (
|
|
95
|
-
<div class="filedrop-file-item">
|
|
96
|
-
<div class="filedrop-file-icon">📄</div>
|
|
97
|
-
<div class="filedrop-file-info">
|
|
98
|
-
<div class="filedrop-file-name">{file.name}</div>
|
|
99
|
-
<div class="filedrop-file-meta">
|
|
100
|
-
{plusui.formatFileSize(file.size)} · {file.type || 'unknown'}
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
))}
|
|
105
|
-
</div>
|
|
106
|
-
)}
|
|
107
|
-
</div>
|
|
108
|
-
|
|
109
|
-
<div class="info">
|
|
110
|
-
<p>Edit <code>frontend/src/App.tsx</code> for the UI.</p>
|
|
111
|
-
<p>Edit <code>main.cpp</code> for native backend logic.</p>
|
|
112
|
-
<p>Run <code>plusui connect</code> to add custom C++ ↔ frontend channels.</p>
|
|
113
|
-
</div>
|
|
30
|
+
<section class="section">
|
|
31
|
+
<h2>App</h2>
|
|
32
|
+
<button class="danger" onClick={handleQuit}>Quit</button>
|
|
33
|
+
</section>
|
|
114
34
|
|
|
115
|
-
|
|
35
|
+
<footer class="footer">
|
|
36
|
+
<p>Edit <code>frontend/src/App.tsx</code> for UI</p>
|
|
37
|
+
<p>Edit <code>main.cpp</code> for backend</p>
|
|
38
|
+
</footer>
|
|
116
39
|
</div>
|
|
117
40
|
);
|
|
118
41
|
}
|
|
@@ -7,11 +7,10 @@ import { existsSync } from 'fs';
|
|
|
7
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
8
|
const __dirname = dirname(__filename);
|
|
9
9
|
|
|
10
|
-
// Resolve plusui-native-core entry directly (bypasses package.json exports)
|
|
11
10
|
function findPlusuiEntry(): string {
|
|
12
11
|
const candidates = [
|
|
12
|
+
resolve(__dirname, '../../Core/Features/API/index.ts'),
|
|
13
13
|
resolve(__dirname, '../node_modules/plusui-native-core/Core/Features/API/index.ts'),
|
|
14
|
-
resolve(__dirname, '../node_modules/plusui-native-core/Core/API/index.ts'),
|
|
15
14
|
];
|
|
16
15
|
for (const p of candidates) {
|
|
17
16
|
if (existsSync(p)) return p;
|
|
@@ -34,4 +33,4 @@ export default defineConfig({
|
|
|
34
33
|
port: 5173,
|
|
35
34
|
strictPort: true,
|
|
36
35
|
},
|
|
37
|
-
});
|
|
36
|
+
});
|