@vantail/create 0.1.0
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/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +189 -0
- package/dist/index.js.map +1 -0
- package/dist/naming.d.ts +6 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +18 -0
- package/dist/naming.js.map +1 -0
- package/package.json +27 -0
- package/templates/react-ts/README.md +34 -0
- package/templates/react-ts/_gitignore +5 -0
- package/templates/react-ts/icon.png +0 -0
- package/templates/react-ts/index.html +12 -0
- package/templates/react-ts/package.json +25 -0
- package/templates/react-ts/src/App.tsx +39 -0
- package/templates/react-ts/src/main.tsx +14 -0
- package/templates/react-ts/src/style.css +60 -0
- package/templates/react-ts/tsconfig.json +14 -0
- package/templates/react-ts/vantail.config.ts +60 -0
- package/templates/react-ts/vite.config.ts +8 -0
- package/templates/svelte-ts/README.md +34 -0
- package/templates/svelte-ts/_gitignore +5 -0
- package/templates/svelte-ts/icon.png +0 -0
- package/templates/svelte-ts/index.html +12 -0
- package/templates/svelte-ts/package.json +22 -0
- package/templates/svelte-ts/src/App.svelte +35 -0
- package/templates/svelte-ts/src/main.ts +9 -0
- package/templates/svelte-ts/src/style.css +60 -0
- package/templates/svelte-ts/src/vite-env.d.ts +3 -0
- package/templates/svelte-ts/svelte.config.js +6 -0
- package/templates/svelte-ts/tsconfig.json +14 -0
- package/templates/svelte-ts/vantail.config.ts +60 -0
- package/templates/svelte-ts/vite.config.ts +8 -0
- package/templates/vanilla-ts/README.md +34 -0
- package/templates/vanilla-ts/_gitignore +5 -0
- package/templates/vanilla-ts/icon.png +0 -0
- package/templates/vanilla-ts/index.html +21 -0
- package/templates/vanilla-ts/package.json +20 -0
- package/templates/vanilla-ts/src/main.ts +36 -0
- package/templates/vanilla-ts/src/style.css +60 -0
- package/templates/vanilla-ts/tsconfig.json +13 -0
- package/templates/vanilla-ts/vantail.config.ts +60 -0
- package/templates/vue-ts/README.md +34 -0
- package/templates/vue-ts/_gitignore +5 -0
- package/templates/vue-ts/icon.png +0 -0
- package/templates/vue-ts/index.html +12 -0
- package/templates/vue-ts/package.json +22 -0
- package/templates/vue-ts/src/App.vue +40 -0
- package/templates/vue-ts/src/main.ts +9 -0
- package/templates/vue-ts/src/style.css +60 -0
- package/templates/vue-ts/tsconfig.json +15 -0
- package/templates/vue-ts/vantail.config.ts +60 -0
- package/templates/vue-ts/vite.config.ts +8 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { app, dialog, filesystem, VantailError } from "@vantail/api";
|
|
3
|
+
|
|
4
|
+
let contents = $state<string | null>(null);
|
|
5
|
+
let path = $state<string | null>(null);
|
|
6
|
+
let error = $state<string | null>(null);
|
|
7
|
+
|
|
8
|
+
const info = app.infoSync();
|
|
9
|
+
|
|
10
|
+
async function open() {
|
|
11
|
+
error = null;
|
|
12
|
+
try {
|
|
13
|
+
const picked = await dialog.openFile({ title: "Open a text file" });
|
|
14
|
+
if (!picked) return;
|
|
15
|
+
|
|
16
|
+
// Picking the file in the dialog is what grants access to it - the
|
|
17
|
+
// config above never mentions this path.
|
|
18
|
+
path = picked;
|
|
19
|
+
contents = await filesystem.readText(picked);
|
|
20
|
+
} catch (cause) {
|
|
21
|
+
error = VantailError.is(cause) ? `${cause.code}: ${cause.message}` : String(cause);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<main>
|
|
27
|
+
<h1>{info?.name ?? "Vantail"}</h1>
|
|
28
|
+
<p class="meta">v{info?.version}</p>
|
|
29
|
+
|
|
30
|
+
<button onclick={() => void open()}>Select file</button>
|
|
31
|
+
|
|
32
|
+
{#if error}<p class="error">{error}</p>{/if}
|
|
33
|
+
{#if path}<p class="meta">{path}</p>{/if}
|
|
34
|
+
{#if contents !== null}<pre>{contents}</pre>{:else}<p class="meta">No file open.</p>{/if}
|
|
35
|
+
</main>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
font-family: ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
|
|
4
|
+
font-size: 14px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
margin: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 12px;
|
|
15
|
+
padding: 24px;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h1 {
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-size: 18px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.meta {
|
|
26
|
+
margin: 0;
|
|
27
|
+
opacity: 0.6;
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
overflow-wrap: anywhere;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.error {
|
|
33
|
+
margin: 0;
|
|
34
|
+
color: #d43b3b;
|
|
35
|
+
font-size: 13px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
align-self: flex-start;
|
|
40
|
+
padding: 6px 12px;
|
|
41
|
+
border-radius: 7px;
|
|
42
|
+
border: 1px solid currentColor;
|
|
43
|
+
background: transparent;
|
|
44
|
+
color: inherit;
|
|
45
|
+
font: inherit;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pre {
|
|
50
|
+
flex: 1;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 12px;
|
|
53
|
+
overflow: auto;
|
|
54
|
+
border-radius: 8px;
|
|
55
|
+
background: color-mix(in srgb, currentColor 8%, transparent);
|
|
56
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
white-space: pre-wrap;
|
|
59
|
+
overflow-wrap: anywhere;
|
|
60
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"types": ["vite/client"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src", "vantail.config.ts", "vite.config.ts", "svelte.config.js"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineConfig } from "@vantail/cli";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
app: {
|
|
5
|
+
name: "__APP_NAME__",
|
|
6
|
+
identifier: "__APP_IDENTIFIER__",
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
// A square PNG. Every size each platform asks for is scaled down from it.
|
|
9
|
+
icon: "icon.png",
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
window: {
|
|
13
|
+
title: "__APP_NAME__",
|
|
14
|
+
width: 900,
|
|
15
|
+
height: 640,
|
|
16
|
+
minWidth: 480,
|
|
17
|
+
minHeight: 360,
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// On macOS this is not decoration: without these predefined items in the
|
|
21
|
+
// menu, Cmd-C, Cmd-V and Cmd-Z do not work anywhere in the application.
|
|
22
|
+
// Add your own submenus alongside them.
|
|
23
|
+
menu: [
|
|
24
|
+
{
|
|
25
|
+
type: "submenu",
|
|
26
|
+
label: "__APP_NAME__",
|
|
27
|
+
items: [
|
|
28
|
+
{ type: "predefined", item: "about" },
|
|
29
|
+
{ type: "separator" },
|
|
30
|
+
{ type: "predefined", item: "hide" },
|
|
31
|
+
{ type: "predefined", item: "quit" },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: "submenu",
|
|
36
|
+
label: "Edit",
|
|
37
|
+
items: [
|
|
38
|
+
{ type: "predefined", item: "undo" },
|
|
39
|
+
{ type: "predefined", item: "redo" },
|
|
40
|
+
{ type: "separator" },
|
|
41
|
+
{ type: "predefined", item: "cut" },
|
|
42
|
+
{ type: "predefined", item: "copy" },
|
|
43
|
+
{ type: "predefined", item: "paste" },
|
|
44
|
+
{ type: "predefined", item: "selectAll" },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
|
|
49
|
+
// Everything is denied until you ask for it. Start small: `dialog` plus the
|
|
50
|
+
// default `grantFromDialog` is enough to open any file the user picks,
|
|
51
|
+
// without granting standing access to their disk.
|
|
52
|
+
permissions: {
|
|
53
|
+
dialog: true,
|
|
54
|
+
clipboard: true,
|
|
55
|
+
menu: true,
|
|
56
|
+
filesystem: {
|
|
57
|
+
write: ["$APPDATA/**"],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# __APP_NAME__
|
|
2
|
+
|
|
3
|
+
Built with [Vantail](https://github.com/jeroenvanwissen/vantail).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install
|
|
7
|
+
npm run dev # native window against the Vite dev server
|
|
8
|
+
npm run build # build the web assets
|
|
9
|
+
npm run package # produce a distributable application
|
|
10
|
+
npm run doctor # check that everything needed is installed
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
There is no Node.js in this app. `node:fs` and friends do not exist - use
|
|
14
|
+
`@vantail/api` instead:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { dialog, filesystem } from "@vantail/api";
|
|
18
|
+
|
|
19
|
+
const path = await dialog.openFile();
|
|
20
|
+
if (path) console.log(await filesystem.readText(path));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Native access is denied by default and granted in `vantail.config.ts`. The same
|
|
24
|
+
file also describes the application menu, and can add a tray icon and a
|
|
25
|
+
self-updater.
|
|
26
|
+
|
|
27
|
+
More windows are labels, opened at runtime:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { app, createWindow } from "@vantail/api";
|
|
31
|
+
|
|
32
|
+
const settings = await createWindow("settings", { url: "settings.html" });
|
|
33
|
+
await app.emit("hello", { from: "main" }, { to: "settings" });
|
|
34
|
+
```
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<main>
|
|
10
|
+
<h1 id="title">__APP_NAME__</h1>
|
|
11
|
+
<p class="meta" id="version"></p>
|
|
12
|
+
|
|
13
|
+
<button id="open">Select file</button>
|
|
14
|
+
|
|
15
|
+
<p class="error" id="error" hidden></p>
|
|
16
|
+
<p class="meta" id="path"></p>
|
|
17
|
+
<pre id="contents"></pre>
|
|
18
|
+
</main>
|
|
19
|
+
<script type="module" src="/src/main.ts"></script>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PACKAGE_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vantail dev",
|
|
8
|
+
"build": "vantail build",
|
|
9
|
+
"package": "vantail package",
|
|
10
|
+
"doctor": "vantail doctor"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@vantail/api": "^0.1.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@vantail/cli": "^0.1.0",
|
|
17
|
+
"typescript": "^5.9.0",
|
|
18
|
+
"vite": "^8.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { app, dialog, filesystem, VantailError } from "@vantail/api";
|
|
2
|
+
|
|
3
|
+
import "./style.css";
|
|
4
|
+
|
|
5
|
+
const openButton = document.querySelector<HTMLButtonElement>("#open")!;
|
|
6
|
+
const errorLine = document.querySelector<HTMLParagraphElement>("#error")!;
|
|
7
|
+
const pathLine = document.querySelector<HTMLParagraphElement>("#path")!;
|
|
8
|
+
const contents = document.querySelector<HTMLPreElement>("#contents")!;
|
|
9
|
+
const version = document.querySelector<HTMLParagraphElement>("#version")!;
|
|
10
|
+
|
|
11
|
+
// Injected before any script runs, so no await is needed for app identity.
|
|
12
|
+
const info = app.infoSync();
|
|
13
|
+
version.textContent = info ? `v${info.version}` : "";
|
|
14
|
+
|
|
15
|
+
openButton.addEventListener("click", () => {
|
|
16
|
+
void open();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
async function open(): Promise<void> {
|
|
20
|
+
errorLine.hidden = true;
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const picked = await dialog.openFile({ title: "Open a text file" });
|
|
24
|
+
if (!picked) return;
|
|
25
|
+
|
|
26
|
+
// Picking the file in the dialog is what grants access to it - the
|
|
27
|
+
// config never mentions this path.
|
|
28
|
+
pathLine.textContent = picked;
|
|
29
|
+
contents.textContent = await filesystem.readText(picked);
|
|
30
|
+
} catch (cause) {
|
|
31
|
+
errorLine.hidden = false;
|
|
32
|
+
errorLine.textContent = VantailError.is(cause)
|
|
33
|
+
? `${cause.code}: ${cause.message}`
|
|
34
|
+
: String(cause);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
font-family: ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
|
|
4
|
+
font-size: 14px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
margin: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 12px;
|
|
15
|
+
padding: 24px;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h1 {
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-size: 18px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.meta {
|
|
26
|
+
margin: 0;
|
|
27
|
+
opacity: 0.6;
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
overflow-wrap: anywhere;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.error {
|
|
33
|
+
margin: 0;
|
|
34
|
+
color: #d43b3b;
|
|
35
|
+
font-size: 13px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
align-self: flex-start;
|
|
40
|
+
padding: 6px 12px;
|
|
41
|
+
border-radius: 7px;
|
|
42
|
+
border: 1px solid currentColor;
|
|
43
|
+
background: transparent;
|
|
44
|
+
color: inherit;
|
|
45
|
+
font: inherit;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pre {
|
|
50
|
+
flex: 1;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 12px;
|
|
53
|
+
overflow: auto;
|
|
54
|
+
border-radius: 8px;
|
|
55
|
+
background: color-mix(in srgb, currentColor 8%, transparent);
|
|
56
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
white-space: pre-wrap;
|
|
59
|
+
overflow-wrap: anywhere;
|
|
60
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"types": ["vite/client"]
|
|
11
|
+
},
|
|
12
|
+
"include": ["src", "vantail.config.ts"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineConfig } from "@vantail/cli";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
app: {
|
|
5
|
+
name: "__APP_NAME__",
|
|
6
|
+
identifier: "__APP_IDENTIFIER__",
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
// A square PNG. Every size each platform asks for is scaled down from it.
|
|
9
|
+
icon: "icon.png",
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
window: {
|
|
13
|
+
title: "__APP_NAME__",
|
|
14
|
+
width: 900,
|
|
15
|
+
height: 640,
|
|
16
|
+
minWidth: 480,
|
|
17
|
+
minHeight: 360,
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// On macOS this is not decoration: without these predefined items in the
|
|
21
|
+
// menu, Cmd-C, Cmd-V and Cmd-Z do not work anywhere in the application.
|
|
22
|
+
// Add your own submenus alongside them.
|
|
23
|
+
menu: [
|
|
24
|
+
{
|
|
25
|
+
type: "submenu",
|
|
26
|
+
label: "__APP_NAME__",
|
|
27
|
+
items: [
|
|
28
|
+
{ type: "predefined", item: "about" },
|
|
29
|
+
{ type: "separator" },
|
|
30
|
+
{ type: "predefined", item: "hide" },
|
|
31
|
+
{ type: "predefined", item: "quit" },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: "submenu",
|
|
36
|
+
label: "Edit",
|
|
37
|
+
items: [
|
|
38
|
+
{ type: "predefined", item: "undo" },
|
|
39
|
+
{ type: "predefined", item: "redo" },
|
|
40
|
+
{ type: "separator" },
|
|
41
|
+
{ type: "predefined", item: "cut" },
|
|
42
|
+
{ type: "predefined", item: "copy" },
|
|
43
|
+
{ type: "predefined", item: "paste" },
|
|
44
|
+
{ type: "predefined", item: "selectAll" },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
|
|
49
|
+
// Everything is denied until you ask for it. Start small: `dialog` plus the
|
|
50
|
+
// default `grantFromDialog` is enough to open any file the user picks,
|
|
51
|
+
// without granting standing access to their disk.
|
|
52
|
+
permissions: {
|
|
53
|
+
dialog: true,
|
|
54
|
+
clipboard: true,
|
|
55
|
+
menu: true,
|
|
56
|
+
filesystem: {
|
|
57
|
+
write: ["$APPDATA/**"],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# __APP_NAME__
|
|
2
|
+
|
|
3
|
+
Built with [Vantail](https://github.com/jeroenvanwissen/vantail).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install
|
|
7
|
+
npm run dev # native window against the Vite dev server
|
|
8
|
+
npm run build # build the web assets
|
|
9
|
+
npm run package # produce a distributable application
|
|
10
|
+
npm run doctor # check that everything needed is installed
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
There is no Node.js in this app. `node:fs` and friends do not exist - use
|
|
14
|
+
`@vantail/api` instead:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { dialog, filesystem } from "@vantail/api";
|
|
18
|
+
|
|
19
|
+
const path = await dialog.openFile();
|
|
20
|
+
if (path) console.log(await filesystem.readText(path));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Native access is denied by default and granted in `vantail.config.ts`. The same
|
|
24
|
+
file also describes the application menu, and can add a tray icon and a
|
|
25
|
+
self-updater.
|
|
26
|
+
|
|
27
|
+
More windows are labels, opened at runtime:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { app, createWindow } from "@vantail/api";
|
|
31
|
+
|
|
32
|
+
const settings = await createWindow("settings", { url: "settings.html" });
|
|
33
|
+
await app.emit("hello", { from: "main" }, { to: "settings" });
|
|
34
|
+
```
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PACKAGE_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vantail dev",
|
|
8
|
+
"build": "vantail build",
|
|
9
|
+
"package": "vantail package",
|
|
10
|
+
"doctor": "vantail doctor"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@vantail/api": "^0.1.0",
|
|
14
|
+
"vue": "^3.5.41"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@vantail/cli": "^0.1.0",
|
|
18
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
19
|
+
"typescript": "^5.9.0",
|
|
20
|
+
"vite": "^8.0.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
|
|
4
|
+
import { app, dialog, filesystem, VantailError } from "@vantail/api";
|
|
5
|
+
|
|
6
|
+
const contents = ref<string | null>(null);
|
|
7
|
+
const path = ref<string | null>(null);
|
|
8
|
+
const error = ref<string | null>(null);
|
|
9
|
+
|
|
10
|
+
const info = app.infoSync();
|
|
11
|
+
|
|
12
|
+
async function open() {
|
|
13
|
+
error.value = null;
|
|
14
|
+
try {
|
|
15
|
+
const picked = await dialog.openFile({ title: "Open a text file" });
|
|
16
|
+
if (!picked) return;
|
|
17
|
+
|
|
18
|
+
// Picking the file in the dialog is what grants access to it - the
|
|
19
|
+
// config above never mentions this path.
|
|
20
|
+
path.value = picked;
|
|
21
|
+
contents.value = await filesystem.readText(picked);
|
|
22
|
+
} catch (cause) {
|
|
23
|
+
error.value = VantailError.is(cause) ? `${cause.code}: ${cause.message}` : String(cause);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<main>
|
|
30
|
+
<h1>{{ info?.name ?? "Vantail" }}</h1>
|
|
31
|
+
<p class="meta">v{{ info?.version }}</p>
|
|
32
|
+
|
|
33
|
+
<button @click="open">Select file</button>
|
|
34
|
+
|
|
35
|
+
<p v-if="error" class="error">{{ error }}</p>
|
|
36
|
+
<p v-if="path" class="meta">{{ path }}</p>
|
|
37
|
+
<pre v-if="contents !== null">{{ contents }}</pre>
|
|
38
|
+
<p v-else class="meta">No file open.</p>
|
|
39
|
+
</main>
|
|
40
|
+
</template>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
font-family: ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
|
|
4
|
+
font-size: 14px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
margin: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 12px;
|
|
15
|
+
padding: 24px;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h1 {
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-size: 18px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.meta {
|
|
26
|
+
margin: 0;
|
|
27
|
+
opacity: 0.6;
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
overflow-wrap: anywhere;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.error {
|
|
33
|
+
margin: 0;
|
|
34
|
+
color: #d43b3b;
|
|
35
|
+
font-size: 13px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
align-self: flex-start;
|
|
40
|
+
padding: 6px 12px;
|
|
41
|
+
border-radius: 7px;
|
|
42
|
+
border: 1px solid currentColor;
|
|
43
|
+
background: transparent;
|
|
44
|
+
color: inherit;
|
|
45
|
+
font: inherit;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pre {
|
|
50
|
+
flex: 1;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 12px;
|
|
53
|
+
overflow: auto;
|
|
54
|
+
border-radius: 8px;
|
|
55
|
+
background: color-mix(in srgb, currentColor 8%, transparent);
|
|
56
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
white-space: pre-wrap;
|
|
59
|
+
overflow-wrap: anywhere;
|
|
60
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"types": ["vite/client"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src", "vantail.config.ts", "vite.config.ts"]
|
|
15
|
+
}
|