foss-design 0.3.5 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/index.js +28 -0
- package/dist/viewer/assets/{index-Cbriu8my.js → index-DmtHtusH.js} +47 -47
- package/dist/viewer/index.html +1 -1
- package/dist/viewer-lib/index.js +40 -2
- package/dist/viewer-lib/types/src/shared/types.d.ts +12 -0
- package/dist/viewer-lib/types/viewer/src/lib/frames.d.ts +9 -1
- package/dist/viewer-lib/types/viewer/src/pages/canvas/items.d.ts +4 -1
- package/dist/viewer-lib/types/viewer/src/ui/toast.d.ts +1 -1
- package/package.json +1 -1
package/dist/viewer/index.html
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
document.documentElement.dataset.theme = dark ? 'dark' : 'light'
|
|
15
15
|
} catch (e) {}
|
|
16
16
|
</script>
|
|
17
|
-
<script type="module" crossorigin src="./assets/index-
|
|
17
|
+
<script type="module" crossorigin src="./assets/index-DmtHtusH.js"></script>
|
|
18
18
|
<link rel="stylesheet" crossorigin href="./assets/index-YT1s8WdL.css">
|
|
19
19
|
</head>
|
|
20
20
|
<body>
|
package/dist/viewer-lib/index.js
CHANGED
|
@@ -6999,6 +6999,10 @@ function Toaster() {
|
|
|
6999
6999
|
name: "alert",
|
|
7000
7000
|
size: 15,
|
|
7001
7001
|
className: "text-danger-text"
|
|
7002
|
+
}) : item.tone === "info" ? /* @__PURE__ */ jsx(Icon, {
|
|
7003
|
+
name: "info",
|
|
7004
|
+
size: 15,
|
|
7005
|
+
className: "text-muted"
|
|
7002
7006
|
}) : /* @__PURE__ */ jsx(Icon, {
|
|
7003
7007
|
name: "check",
|
|
7004
7008
|
size: 15,
|
|
@@ -7106,6 +7110,31 @@ function frameSrc(url, theme, extra) {
|
|
|
7106
7110
|
function absoluteUrl(url) {
|
|
7107
7111
|
return new URL(url, document.baseURI).toString();
|
|
7108
7112
|
}
|
|
7113
|
+
/**
|
|
7114
|
+
* A link or form the runtime kept from leaving its frame. A path whose last part names a screen
|
|
7115
|
+
* or URL item on the canvas (`/settings`, `settings.html`) goes there; a link to another site
|
|
7116
|
+
* opens in a new tab; anything else says where it pointed.
|
|
7117
|
+
*/
|
|
7118
|
+
function followLink(message, canvas, go) {
|
|
7119
|
+
if (message.form) {
|
|
7120
|
+
toast("Forms are not sent from a screen", void 0, "info");
|
|
7121
|
+
return;
|
|
7122
|
+
}
|
|
7123
|
+
if (message.path === null) {
|
|
7124
|
+
const tab = window.open(message.href, "_blank");
|
|
7125
|
+
if (tab) tab.opener = null;
|
|
7126
|
+
else toast("Link to another site", message.href, "info");
|
|
7127
|
+
return;
|
|
7128
|
+
}
|
|
7129
|
+
const path = message.path.split(/[?#]/)[0].replace(/\/+$/, "");
|
|
7130
|
+
let name = path.slice(path.lastIndexOf("/") + 1).replace(/\.html?$/, "");
|
|
7131
|
+
try {
|
|
7132
|
+
name = decodeURIComponent(name);
|
|
7133
|
+
} catch {}
|
|
7134
|
+
const ids = new Set(canvas.pages.flatMap((page) => page.sections.flatMap((section) => section.items.filter((item) => item.kind === "screen" || item.kind === "url").map((item) => item.id))));
|
|
7135
|
+
if (name && ids.has(name)) go(name);
|
|
7136
|
+
else toast("Not a screen on this canvas", message.path, "info");
|
|
7137
|
+
}
|
|
7109
7138
|
//#endregion
|
|
7110
7139
|
//#region viewer/src/components/inspector.tsx
|
|
7111
7140
|
/**
|
|
@@ -8779,7 +8808,7 @@ function FullPage({ canvasId, itemId }) {
|
|
|
8779
8808
|
else if (message.type === "go") {
|
|
8780
8809
|
const id = message.target.includes("/") ? message.target.split("/")[1] : message.target;
|
|
8781
8810
|
if (items.some((entry) => entry.id === id)) navigate(fullHref(canvasId, id, theme), { replace: true });
|
|
8782
|
-
}
|
|
8811
|
+
} else if (message.type === "link" && canvas) followLink(message, canvas, (id) => navigate(fullHref(canvasId, id, theme), { replace: true }));
|
|
8783
8812
|
});
|
|
8784
8813
|
}, [url, item?.kind]);
|
|
8785
8814
|
if (error) return /* @__PURE__ */ jsx(NotFound, {
|
|
@@ -11137,6 +11166,9 @@ var FrameItem = memo(function FrameItem({ placed, mode, thumb, theme, store, eve
|
|
|
11137
11166
|
case "go":
|
|
11138
11167
|
events.onGo(item.id, message.target);
|
|
11139
11168
|
break;
|
|
11169
|
+
case "link":
|
|
11170
|
+
events.onLink(item.id, message);
|
|
11171
|
+
break;
|
|
11140
11172
|
case "wheel":
|
|
11141
11173
|
events.onWheel(frame, message);
|
|
11142
11174
|
break;
|
|
@@ -12078,6 +12110,9 @@ function CanvasView({ canvas, page }) {
|
|
|
12078
12110
|
}
|
|
12079
12111
|
console.warn(`[design] go("${target}"): no such screen`);
|
|
12080
12112
|
},
|
|
12113
|
+
onLink(from, message) {
|
|
12114
|
+
followLink(message, canvas, (id) => this.onGo(from, id));
|
|
12115
|
+
},
|
|
12081
12116
|
onWheel(frame, message) {
|
|
12082
12117
|
const root = frame.closest(".canvas-root");
|
|
12083
12118
|
if (!root) return;
|
|
@@ -12509,7 +12544,10 @@ function Player({ canvas, itemId }) {
|
|
|
12509
12544
|
const [pagePart, idPart] = message.target.includes("/") ? message.target.split("/") : [null, message.target];
|
|
12510
12545
|
const target = all.find((e) => e.item.id === idPart && (!pagePart || e.pageId === pagePart));
|
|
12511
12546
|
if (target) navigate(playHref(canvas.id, target.item.id, target.pageId));
|
|
12512
|
-
}
|
|
12547
|
+
} else if (message.type === "link") followLink(message, canvas, (id) => {
|
|
12548
|
+
const target = all.find((e) => e.item.id === id);
|
|
12549
|
+
if (target) navigate(playHref(canvas.id, target.item.id, target.pageId));
|
|
12550
|
+
});
|
|
12513
12551
|
});
|
|
12514
12552
|
}, [
|
|
12515
12553
|
item,
|
|
@@ -284,6 +284,18 @@ export type RuntimeMessage = {
|
|
|
284
284
|
key: string;
|
|
285
285
|
type: 'go';
|
|
286
286
|
target: string;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A link or form in the screen would have taken the frame to another page, which the frame's
|
|
290
|
+
* origin does not serve; the runtime kept the frame put. `path` is set for its own origin.
|
|
291
|
+
*/
|
|
292
|
+
| {
|
|
293
|
+
source: 'design-runtime';
|
|
294
|
+
key: string;
|
|
295
|
+
type: 'link';
|
|
296
|
+
href: string;
|
|
297
|
+
path: string | null;
|
|
298
|
+
form: boolean;
|
|
287
299
|
} | {
|
|
288
300
|
source: 'design-runtime';
|
|
289
301
|
key: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RuntimeMessage, Theme, ViewerMessage } from '../../../src/shared/types';
|
|
1
|
+
import type { CanvasDoc, RuntimeMessage, Theme, ViewerMessage } from '../../../src/shared/types';
|
|
2
2
|
type Handler = (message: RuntimeMessage) => void;
|
|
3
3
|
export declare function listenToFrame(frame: HTMLIFrameElement, handler: Handler): () => void;
|
|
4
4
|
type Outgoing = ViewerMessage extends infer M ? M extends {
|
|
@@ -22,4 +22,12 @@ export declare const FRAME_ORIGIN: string;
|
|
|
22
22
|
export declare function frameSrc(url: string, theme: Theme, extra?: Record<string, string>): string;
|
|
23
23
|
/** Absolute URL for opening a frame in a new tab. */
|
|
24
24
|
export declare function absoluteUrl(url: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* A link or form the runtime kept from leaving its frame. A path whose last part names a screen
|
|
27
|
+
* or URL item on the canvas (`/settings`, `settings.html`) goes there; a link to another site
|
|
28
|
+
* opens in a new tab; anything else says where it pointed.
|
|
29
|
+
*/
|
|
30
|
+
export declare function followLink(message: Extract<RuntimeMessage, {
|
|
31
|
+
type: 'link';
|
|
32
|
+
}>, canvas: CanvasDoc, go: (id: string) => void): void;
|
|
25
33
|
export {};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type { CanvasSection, ImageItem, NoteItem, ScreenItem, Theme, UrlItem } from '../../../../src/shared/types';
|
|
1
|
+
import type { CanvasSection, ImageItem, NoteItem, RuntimeMessage, ScreenItem, Theme, UrlItem } from '../../../../src/shared/types';
|
|
2
2
|
import type { Placed } from './layout';
|
|
3
3
|
import { type ViewStore } from './view-state';
|
|
4
4
|
import type { FrameMode } from './viewport';
|
|
5
5
|
export interface FrameEvents {
|
|
6
6
|
onGo(from: string, target: string): void;
|
|
7
|
+
onLink(from: string, message: Extract<RuntimeMessage, {
|
|
8
|
+
type: 'link';
|
|
9
|
+
}>): void;
|
|
7
10
|
onWheel(frame: HTMLIFrameElement, message: {
|
|
8
11
|
deltaX: number;
|
|
9
12
|
deltaY: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ToastTone = 'ok' | 'error';
|
|
1
|
+
export type ToastTone = 'ok' | 'info' | 'error';
|
|
2
2
|
/** A short confirmation; `error` shows a failure and stays a little longer to be read. */
|
|
3
3
|
export declare function toast(title: string, text?: string, tone?: ToastTone): void;
|
|
4
4
|
/** Only the first mounted Toaster shows toasts: an app that embeds the viewer may keep its own. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foss-design",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Design canvases and design systems for coding agents: live, animated, clickable screens on an infinite canvas, served locally from a .design folder.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|