@liberation-data/desk 0.4.0 → 0.7.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.
Files changed (46) hide show
  1. package/README.md +63 -2
  2. package/dist/core/desk.d.ts +13 -0
  3. package/dist/core/desk.d.ts.map +1 -1
  4. package/dist/core/desk.js +55 -1
  5. package/dist/core/desk.js.map +1 -1
  6. package/dist/core/index.d.ts +2 -2
  7. package/dist/core/index.d.ts.map +1 -1
  8. package/dist/core/types.d.ts +7 -0
  9. package/dist/core/types.d.ts.map +1 -1
  10. package/dist/css/apps.css +57 -0
  11. package/dist/css/controls.css +975 -0
  12. package/dist/css/conversation.css +232 -0
  13. package/dist/css/dock.css +272 -0
  14. package/dist/css/menus.css +204 -0
  15. package/dist/css/overlays.css +237 -0
  16. package/dist/css/search.css +149 -0
  17. package/dist/css/setup.css +284 -0
  18. package/dist/css/tokens.css +90 -0
  19. package/dist/css/windows.css +321 -0
  20. package/dist/desk.css +1080 -1070
  21. package/dist/react/Desktop.d.ts +9 -2
  22. package/dist/react/Desktop.d.ts.map +1 -1
  23. package/dist/react/Desktop.js +85 -23
  24. package/dist/react/Desktop.js.map +1 -1
  25. package/dist/react/appFrame.d.ts +9 -2
  26. package/dist/react/appFrame.d.ts.map +1 -1
  27. package/dist/react/appFrame.js +26 -5
  28. package/dist/react/appFrame.js.map +1 -1
  29. package/llms.txt +12 -1
  30. package/package.json +4 -3
  31. package/src/core/desk.ts +67 -1
  32. package/src/core/index.ts +2 -1
  33. package/src/core/types.ts +8 -0
  34. package/src/css/apps.css +56 -0
  35. package/src/css/controls.css +974 -0
  36. package/src/css/conversation.css +231 -0
  37. package/src/css/dock.css +271 -0
  38. package/src/css/menus.css +203 -0
  39. package/src/css/overlays.css +236 -0
  40. package/src/css/search.css +148 -0
  41. package/src/css/setup.css +283 -0
  42. package/src/css/tokens.css +89 -0
  43. package/src/css/windows.css +320 -0
  44. package/src/react/Desktop.tsx +97 -26
  45. package/src/react/appFrame.tsx +48 -5
  46. package/src/desk.css +0 -2820
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { WindowId } from '../core/types.js';
2
+ import type { WindowId, WindowLimits } from '../core/types.js';
3
3
  import type { WindowFailed, WindowLoading } from './windowBoundary.js';
4
4
  export type DeskLayout = 'desktop' | 'fullscreen';
5
5
  export interface DesktopProps {
@@ -11,6 +11,13 @@ export interface DesktopProps {
11
11
  * gives way to the actions and disappears before the title does when the window is narrow.
12
12
  */
13
13
  readonly note?: (id: WindowId) => ReactNode;
14
+ /**
15
+ * How big this window may be. Most windows want the whole desk when filled and whatever they are
16
+ * dragged to when free, which is what `null` says. A window whose content has a natural size —
17
+ * an About box, a small form — says so, and is never stretched past it, however it is filled,
18
+ * arranged or dragged.
19
+ */
20
+ readonly limits?: (id: WindowId) => WindowLimits | null;
14
21
  /**
15
22
  * What this window is, behind an (i) at the end of its title bar — the same place in every window,
16
23
  * so a person who wonders what they are looking at always knows where to ask. Explanation only: a
@@ -32,5 +39,5 @@ export interface DesktopProps {
32
39
  readonly layout?: DeskLayout | 'auto';
33
40
  readonly className?: string;
34
41
  }
35
- export declare function Desktop({ renderWindow, title, note, info, actions, empty, loading, failed, layout, className }: DesktopProps): import("react").JSX.Element;
42
+ export declare function Desktop({ renderWindow, title, note, info, actions, limits, empty, loading, failed, layout, className }: DesktopProps): import("react").JSX.Element;
36
43
  //# sourceMappingURL=Desktop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Desktop.d.ts","sourceRoot":"","sources":["../../src/react/Desktop.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoD,SAAS,EAAE,MAAM,OAAO,CAAA;AAGxF,OAAO,KAAK,EAAqB,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAKnE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEtE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,YAAY,CAAA;AAEjD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAClD,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C,yGAAyG;IACzG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC9C,oCAAoC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AA2CD,wBAAgB,OAAO,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAe,EAAE,SAAS,EAAE,EAAE,YAAY,+BA2FrI"}
1
+ {"version":3,"file":"Desktop.d.ts","sourceRoot":"","sources":["../../src/react/Desktop.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoD,SAAS,EAAE,MAAM,OAAO,CAAA;AAIxF,OAAO,KAAK,EAAqB,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAKjF,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEtE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,YAAY,CAAA;AAEjD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAClD,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,YAAY,GAAG,IAAI,CAAA;IACvD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC3C,yGAAyG;IACzG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,SAAS,CAAA;IAC9C,oCAAoC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AA2CD,wBAAgB,OAAO,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAe,EAAE,SAAS,EAAE,EAAE,YAAY,+BAsH7I"}
@@ -35,7 +35,7 @@ const halfFrame = (stage, side) => {
35
35
  const width = (area.width - area.gap) / 2;
36
36
  return { x: side === 'start' ? area.x : area.x + width + area.gap, y: area.y, width, height: area.height };
37
37
  };
38
- export function Desktop({ renderWindow, title, note, info, actions, empty, loading, failed, layout = 'auto', className }) {
38
+ export function Desktop({ renderWindow, title, note, info, actions, limits, empty, loading, failed, layout = 'auto', className }) {
39
39
  const desk = useDesk();
40
40
  const state = useDeskState();
41
41
  const stage = useRef(null);
@@ -44,29 +44,59 @@ export function Desktop({ renderWindow, title, note, info, actions, empty, loadi
44
44
  useLayoutEffect(() => {
45
45
  desk.setStage(() => ({ width: stage.current?.clientWidth ?? 1024, height: stage.current?.clientHeight ?? 768 }));
46
46
  }, [desk]);
47
+ /*
48
+ * The desk changing size is not a layout decision, but it can undo one: unplug an external
49
+ * display and the windows you spread across it are past the edge of the laptop screen, where
50
+ * nothing can drag them back. They are brought in; plug the display back in and they go out
51
+ * again exactly as they were.
52
+ *
53
+ * Filled windows need none of this — they are whatever size the desk is — so a desk of only
54
+ * filled windows never commits anything here.
55
+ */
56
+ useEffect(() => {
57
+ const element = stage.current;
58
+ if (!element || mode !== 'desktop')
59
+ return undefined;
60
+ let frame = 0;
61
+ // Once per paint: dragging the browser window's edge fires this continuously.
62
+ const refit = () => {
63
+ cancelAnimationFrame(frame);
64
+ frame = requestAnimationFrame(() => {
65
+ const fit = desk.fitToStage();
66
+ /*
67
+ * One window that no longer fits is brought in and made smaller, and that is enough. Two or
68
+ * more means the layout itself is gone: each was clamped on its own, so windows that sat
69
+ * side by side now sit on top of each other, and the desk is left looking like one window.
70
+ * At that point it is laid out the way Arrange would — which is a layout for THIS screen,
71
+ * while the frames from the big one are remembered and come back with it.
72
+ */
73
+ if (fit.squeezed.length > 1)
74
+ arrangeNow(desk, element);
75
+ });
76
+ };
77
+ // The stage can change size without the window doing so — a sidebar opening beside it — so the
78
+ // element is watched where that can be watched, and the window is the fallback where it cannot.
79
+ if (typeof ResizeObserver === 'undefined') {
80
+ addEventListener('resize', refit);
81
+ return () => {
82
+ cancelAnimationFrame(frame);
83
+ removeEventListener('resize', refit);
84
+ };
85
+ }
86
+ const observer = new ResizeObserver(refit);
87
+ observer.observe(element);
88
+ return () => {
89
+ cancelAnimationFrame(frame);
90
+ observer.disconnect();
91
+ };
92
+ }, [desk, mode]);
47
93
  useEffect(() => (stage.current ? addDeskCommands(stage.current, desk) : undefined), [desk]);
48
94
  // Arrange lays every window out once, as free windows that can be moved again straight away.
49
95
  useEffect(() => {
50
96
  const element = stage.current;
51
97
  if (!element || mode !== 'desktop')
52
98
  return undefined;
53
- return addCommandHandler(element, DeskCommands.arrange, () => {
54
- const { windows, stack } = desk.getState();
55
- const [focused, previous] = [stack.at(-1), stack.at(-2)];
56
- if (windows.length === 1) {
57
- if (focused)
58
- desk.fill(focused);
59
- return;
60
- }
61
- const frames = arrangement(windows.map(w => w.id), focused ?? null, previous ?? null, arrangementArea(element), { minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT });
62
- desk.placeAll(frames);
63
- // Windows that cascade come in front of the half they cascade over; the focused window stays in front of all.
64
- if (previous)
65
- desk.focus(previous);
66
- windows.forEach(w => w.id !== focused && w.id !== previous && desk.focus(w.id));
67
- if (focused)
68
- desk.focus(focused);
69
- }, {
99
+ return addCommandHandler(element, DeskCommands.arrange, () => arrangeNow(desk, element), {
70
100
  enabled: () => {
71
101
  const { windows } = desk.getState();
72
102
  return windows.length > 1 || windows.some(w => w.mode === 'floating');
@@ -88,12 +118,31 @@ export function Desktop({ renderWindow, title, note, info, actions, empty, loadi
88
118
  }, [focused]);
89
119
  return (_jsxs("div", { ref: stage, className: ['desk-stage', className].filter(Boolean).join(' '), "data-layout": mode, [STAGE_ATTRIBUTE]: '', children: [state.windows.length === 0 && empty, state.windows.map(window => (_jsx(WindowView, { window: window, layout: mode, depth: state.stack.indexOf(window.id), focused: window.id === focused,
90
120
  // One window at a time: the rest stay mounted, keeping their state, and simply wait offstage.
91
- hidden: mode === 'fullscreen' && window.id !== focused, title: title(window.id), note: note?.(window.id), info: info?.(window.id), actions: actions?.(window.id), children: _jsx(WindowContent, { id: window.id, render: renderWindow, loading: loading, failed: failed }) }, window.id)))] }));
121
+ hidden: mode === 'fullscreen' && window.id !== focused, title: title(window.id), note: note?.(window.id), info: info?.(window.id), limits: limits?.(window.id) ?? null, actions: actions?.(window.id), children: _jsx(WindowContent, { id: window.id, render: renderWindow, loading: loading, failed: failed }) }, window.id)))] }));
92
122
  }
93
123
  // Each window loads and fails on its own: one fetching its code, or throwing, never blanks another.
94
124
  const WindowContent = memo(function WindowContent({ id, render, loading, failed }) {
95
125
  return (_jsx(WindowBoundary, { id: id, loading: loading, failed: failed, children: render(id) }));
96
126
  });
127
+ /** Moving by the title bar, or resizing from the corner or from the left, right or bottom edge. */
128
+ /** Lays every open window out at once: what Window → Arrange does, and what a shrunken desk needs. */
129
+ function arrangeNow(desk, element) {
130
+ const { windows, stack } = desk.getState();
131
+ const [focused, previous] = [stack.at(-1), stack.at(-2)];
132
+ if (windows.length === 1) {
133
+ if (focused)
134
+ desk.fill(focused);
135
+ return;
136
+ }
137
+ const frames = arrangement(windows.map(w => w.id), focused ?? null, previous ?? null, arrangementArea(element), { minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT });
138
+ desk.placeAll(frames);
139
+ // Windows that cascade come in front of the half they cascade over; the focused window stays in front of all.
140
+ if (previous)
141
+ desk.focus(previous);
142
+ windows.forEach(w => w.id !== focused && w.id !== previous && desk.focus(w.id));
143
+ if (focused)
144
+ desk.focus(focused);
145
+ }
97
146
  /** The frame a gesture makes of `origin` after the pointer has travelled dx, dy. */
98
147
  function reshape(gesture, origin, dx, dy) {
99
148
  switch (gesture) {
@@ -112,7 +161,7 @@ function reshape(gesture, origin, dx, dy) {
112
161
  }
113
162
  }
114
163
  }
115
- function WindowView({ window, layout, hidden, depth, focused, title, note, info, actions, children }) {
164
+ function WindowView({ window, layout, hidden, depth, focused, title, note, info, actions, limits, children }) {
116
165
  const desk = useDesk();
117
166
  // While dragging, the frame lives here and commits once on release, so a drag
118
167
  // re-renders one window rather than notifying every subscriber per pixel.
@@ -197,11 +246,24 @@ function WindowView({ window, layout, hidden, depth, focused, title, note, info,
197
246
  desk.toggleMode(window.id);
198
247
  };
199
248
  const frame = layout === 'desktop' ? (live ?? (window.mode === 'floating' ? window.frame : null)) : null;
249
+ /*
250
+ * A window that says how big it may be is capped in the browser rather than in the state: filling
251
+ * the desk, being arranged into a cell and being dragged wider all end at the same place, and the
252
+ * window sits in the middle of whatever room it was given rather than pinned to a corner of it.
253
+ */
254
+ const capped = {
255
+ ...(limits?.maxWidth ? { maxWidth: limits.maxWidth } : {}),
256
+ ...(limits?.maxHeight ? { maxHeight: limits.maxHeight } : {}),
257
+ ...(limits?.minWidth ? { minWidth: limits.minWidth } : {}),
258
+ ...(limits?.minHeight ? { minHeight: limits.minHeight } : {}),
259
+ // Filled and capped: it sits in the middle of the room, not in the corner of it.
260
+ ...(limits && (limits.maxWidth || limits.maxHeight) && !frame ? { margin: 'auto' } : {}),
261
+ };
200
262
  const style = layout !== 'desktop'
201
- ? undefined
263
+ ? capped
202
264
  : frame
203
- ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth }
204
- : { zIndex: 10 + depth };
265
+ ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth, ...capped }
266
+ : { zIndex: 10 + depth, ...capped };
205
267
  return (_jsx(WindowContext.Provider, { value: context, children: _jsxs("section", { ref: element, tabIndex: -1, [WINDOW_ATTRIBUTE]: window.id, className: "desk-window", "data-mode": layout === 'fullscreen' ? 'fullscreen' : live ? 'floating' : window.mode, "data-hidden": hidden || undefined, inert: hidden || undefined, "data-focused": focused || undefined, "data-dragging": live ? true : undefined, "aria-labelledby": titleId, style: style, onPointerDownCapture: () => {
206
268
  if (!focused)
207
269
  desk.focus(window.id);
@@ -1 +1 @@
1
- {"version":3,"file":"Desktop.js","sourceRoot":"","sources":["../../src/react/Desktop.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Desktop.js","sourceRoot":"","sources":["../../src/react/Desktop.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,9 @@
1
1
  import type { Accepts } from './dnd.js';
2
+ export interface AppTheme {
3
+ readonly mode: 'light' | 'dark';
4
+ /** Custom properties, named as they will be set: `{ '--sb-bg-dark': '#0b0f1a' }`. */
5
+ readonly tokens: Readonly<Record<string, string>>;
6
+ }
2
7
  export interface AppFrameProps {
3
8
  /** The accessible name of the frame: what the app is. */
4
9
  readonly title: string;
@@ -9,6 +14,8 @@ export interface AppFrameProps {
9
14
  readonly listens?: readonly string[];
10
15
  /** Topics the app may say. Anything else it publishes is dropped. Default: none. */
11
16
  readonly says?: readonly string[];
17
+ /** The desk's own look, offered to the app: it is applied to the app's root and re-sent on change. */
18
+ readonly theme?: AppTheme;
12
19
  /** What may be dropped on it. Default: nothing. */
13
20
  readonly accepts?: Accepts;
14
21
  /** Windows the app may ask to open. Default: none. */
@@ -20,7 +27,7 @@ export interface AppFrameProps {
20
27
  readonly sandbox?: string;
21
28
  readonly className?: string;
22
29
  }
23
- export declare function AppFrame({ title, src, srcDoc, listens, says, accepts, opens, sandbox, className, }: AppFrameProps): import("react").JSX.Element;
30
+ export declare function AppFrame({ title, src, srcDoc, listens, says, theme, accepts, opens, sandbox, className, }: AppFrameProps): import("react").JSX.Element;
24
31
  /**
25
32
  * The app's half of the bridge, as a script to put in its page. It gives the page a
26
33
  * small `desk` object:
@@ -31,7 +38,7 @@ export declare function AppFrame({ title, src, srcDoc, listens, says, accepts, o
31
38
  * desk.open('map') ask for a window, if it was granted
32
39
  * desk.window which window this is, once connected
33
40
  */
34
- export declare const APP_BRIDGE_SCRIPT = "(() => {\n const handlers = new Map();\n const drops = [];\n const send = message => parent.postMessage(Object.assign({ desk: 1 }, message), '*');\n const desk = {\n window: null,\n listens: [],\n says: [],\n on(topic, handler) { (handlers.get(topic) || handlers.set(topic, []).get(topic)).push(handler); },\n onDrop(handler) { drops.push(handler); },\n publish(topic, payload) { send({ kind: 'publish', topic, payload }); },\n open(window) { send({ kind: 'open', window }); },\n };\n const matches = (pattern, topic) =>\n pattern === '*' || pattern === topic || (pattern.endsWith('.*') && (topic === pattern.slice(0, -2) || topic.startsWith(pattern.slice(0, -1))));\n addEventListener('message', event => {\n if (event.source !== parent || !event.data || event.data.desk !== 1) return;\n const message = event.data;\n if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; }\n if (message.kind === 'event') for (const [pattern, list] of handlers) if (matches(pattern, message.topic)) list.forEach(h => h(message));\n if (message.kind === 'drop') drops.forEach(h => h(message));\n });\n window.desk = desk;\n send({ kind: 'ready' });\n})();";
41
+ export declare const APP_BRIDGE_SCRIPT = "(() => {\n const handlers = new Map();\n const drops = [];\n const send = message => parent.postMessage(Object.assign({ desk: 1 }, message), '*');\n const applyTheme = theme => {\n if (!theme) return;\n desk.theme = theme;\n const root = document.documentElement;\n root.dataset.deskTheme = theme.mode;\n root.style.colorScheme = theme.mode;\n for (const [name, value] of Object.entries(theme.tokens || {})) root.style.setProperty(name, value);\n themed.forEach(h => h(theme));\n };\n const themed = [];\n const desk = {\n window: null,\n listens: [],\n says: [],\n theme: null,\n onTheme(handler) { themed.push(handler); if (desk.theme) handler(desk.theme); },\n on(topic, handler) { (handlers.get(topic) || handlers.set(topic, []).get(topic)).push(handler); },\n onDrop(handler) { drops.push(handler); },\n publish(topic, payload) { send({ kind: 'publish', topic, payload }); },\n open(window) { send({ kind: 'open', window }); },\n };\n const matches = (pattern, topic) =>\n pattern === '*' || pattern === topic || (pattern.endsWith('.*') && (topic === pattern.slice(0, -2) || topic.startsWith(pattern.slice(0, -1))));\n addEventListener('message', event => {\n if (event.source !== parent || !event.data || event.data.desk !== 1) return;\n const message = event.data;\n if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; applyTheme(message.theme); }\n if (message.kind === 'theme') applyTheme(message.theme);\n if (message.kind === 'event') for (const [pattern, list] of handlers) if (matches(pattern, message.topic)) list.forEach(h => h(message));\n if (message.kind === 'drop') drops.forEach(h => h(message));\n });\n window.desk = desk;\n send({ kind: 'ready' });\n})();";
35
42
  /** Puts the bridge into a page of HTML, so a generated app needs nothing added by hand. */
36
43
  export declare function withAppBridge(html: string): string;
37
44
  //# sourceMappingURL=appFrame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"appFrame.d.ts","sourceRoot":"","sources":["../../src/react/appFrame.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AA8BvC,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,GAAG,EACH,MAAM,EACN,OAAY,EACZ,IAAS,EACT,OAAO,EACP,KAAU,EACV,OAAqC,EACrC,SAAS,GACV,EAAE,aAAa,+BAyEf;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,2uCAwBxB,CAAA;AAEN,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD"}
1
+ {"version":3,"file":"appFrame.d.ts","sourceRoot":"","sources":["../../src/react/appFrame.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AA6BvC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAClD;AAgBD,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,sGAAsG;IACtG,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;IACzB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,GAAG,EACH,MAAM,EACN,OAAY,EACZ,IAAS,EACT,KAAK,EACL,OAAO,EACP,KAAU,EACV,OAAqC,EACrC,SAAS,GACV,EAAE,aAAa,+BAiFf;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,yyDAqCxB,CAAA;AAEN,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD"}
@@ -16,7 +16,7 @@ import { useBus } from './events.js';
16
16
  /** The protocol version. Every message carries it, so a mismatch is ignored rather than misread. */
17
17
  const PROTOCOL = 1;
18
18
  const isAppMessage = (data) => typeof data === 'object' && data !== null && data.desk === PROTOCOL && typeof data.kind === 'string';
19
- export function AppFrame({ title, src, srcDoc, listens = [], says = [], accepts, opens = [], sandbox = 'allow-scripts allow-forms', className, }) {
19
+ export function AppFrame({ title, src, srcDoc, listens = [], says = [], theme, accepts, opens = [], sandbox = 'allow-scripts allow-forms', className, }) {
20
20
  const desk = useDesk();
21
21
  const bus = useBus();
22
22
  const windowId = useWindowId();
@@ -28,8 +28,8 @@ export function AppFrame({ title, src, srcDoc, listens = [], says = [], accepts,
28
28
  // window and no other.
29
29
  frame.current?.contentWindow?.postMessage(message, '*');
30
30
  };
31
- const latest = useRef({ listens, says, opens, windowId });
32
- latest.current = { listens, says, opens, windowId };
31
+ const latest = useRef({ listens, says, opens, windowId, theme });
32
+ latest.current = { listens, says, opens, windowId, theme };
33
33
  // What the app says: only from this frame, only on topics it was granted.
34
34
  useEffect(() => {
35
35
  const onMessage = (event) => {
@@ -38,7 +38,7 @@ export function AppFrame({ title, src, srcDoc, listens = [], says = [], accepts,
38
38
  const message = event.data;
39
39
  const granted = latest.current;
40
40
  if (message.kind === 'ready') {
41
- post({ desk: PROTOCOL, kind: 'hello', window: granted.windowId, listens: granted.listens, says: granted.says });
41
+ post({ desk: PROTOCOL, kind: 'hello', window: granted.windowId, listens: granted.listens, says: granted.says, theme: granted.theme ?? null });
42
42
  }
43
43
  else if (message.kind === 'publish') {
44
44
  if (typeof message.topic === 'string' && granted.says.some(pattern => topicMatches(pattern, message.topic))) {
@@ -53,6 +53,14 @@ export function AppFrame({ title, src, srcDoc, listens = [], says = [], accepts,
53
53
  window.addEventListener('message', onMessage);
54
54
  return () => window.removeEventListener('message', onMessage);
55
55
  }, [bus, desk]);
56
+ // The desk's look, again, whenever it changes: a person switching theme switches the app too.
57
+ const themeKey = theme ? `${theme.mode}|${Object.entries(theme.tokens).map(([k, v]) => `${k}:${v}`).join(';')}` : '';
58
+ useEffect(() => {
59
+ if (!latest.current.theme)
60
+ return;
61
+ post({ desk: PROTOCOL, kind: 'theme', theme: latest.current.theme });
62
+ // eslint-disable-next-line react-hooks/exhaustive-deps
63
+ }, [themeKey]);
56
64
  // What the app hears: only the topics it was granted, and never its own words back.
57
65
  const listenKey = listens.join('|');
58
66
  useEffect(() => {
@@ -90,10 +98,22 @@ export const APP_BRIDGE_SCRIPT = `(() => {
90
98
  const handlers = new Map();
91
99
  const drops = [];
92
100
  const send = message => parent.postMessage(Object.assign({ desk: ${PROTOCOL} }, message), '*');
101
+ const applyTheme = theme => {
102
+ if (!theme) return;
103
+ desk.theme = theme;
104
+ const root = document.documentElement;
105
+ root.dataset.deskTheme = theme.mode;
106
+ root.style.colorScheme = theme.mode;
107
+ for (const [name, value] of Object.entries(theme.tokens || {})) root.style.setProperty(name, value);
108
+ themed.forEach(h => h(theme));
109
+ };
110
+ const themed = [];
93
111
  const desk = {
94
112
  window: null,
95
113
  listens: [],
96
114
  says: [],
115
+ theme: null,
116
+ onTheme(handler) { themed.push(handler); if (desk.theme) handler(desk.theme); },
97
117
  on(topic, handler) { (handlers.get(topic) || handlers.set(topic, []).get(topic)).push(handler); },
98
118
  onDrop(handler) { drops.push(handler); },
99
119
  publish(topic, payload) { send({ kind: 'publish', topic, payload }); },
@@ -104,7 +124,8 @@ export const APP_BRIDGE_SCRIPT = `(() => {
104
124
  addEventListener('message', event => {
105
125
  if (event.source !== parent || !event.data || event.data.desk !== ${PROTOCOL}) return;
106
126
  const message = event.data;
107
- if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; }
127
+ if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; applyTheme(message.theme); }
128
+ if (message.kind === 'theme') applyTheme(message.theme);
108
129
  if (message.kind === 'event') for (const [pattern, list] of handlers) if (matches(pattern, message.topic)) list.forEach(h => h(message));
109
130
  if (message.kind === 'drop') drops.forEach(h => h(message));
110
131
  });
@@ -1 +1 @@
1
- {"version":3,"file":"appFrame.js","sourceRoot":"","sources":["../../src/react/appFrame.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appFrame.js","sourceRoot":"","sources":["../../src/react/appFrame.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAErD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC;;;;;;;;GAQG;AAEH,oGAAoG;AACpG,MAAM,QAAQ,GAAG,CAAC,CAAA;AA+BlB,MAAM,YAAY,GAAG,CAAC,IAAa,EAAsB,EAAE,CACzD,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAK,IAA2B,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,CAAA;AA0BtJ,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,GAAG,EACH,MAAM,EACN,OAAO,GAAG,EAAE,EACZ,IAAI,GAAG,EAAE,EACT,KAAK,EACL,OAAO,EACP,KAAK,GAAG,EAAE,EACV,OAAO,GAAG,2BAA2B,EACrC,SAAS,GACK;IACd,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAE9B,MAAM,IAAI,GAAG,CAAC,OAAoB,EAAE,EAAE;QACpC,iFAAiF;QACjF,4EAA4E;QAC5E,uBAAuB;QACvB,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACzD,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAChE,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;IAE1D,0EAA0E;IAC1E,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;YACxC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAM;YACvG,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAA;YAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;YAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC,CAAA;YAC/I,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACtC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC5G,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACzE,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACnC,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAC7G,CAAC;QACH,CAAC,CAAA;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAC7C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAC/D,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IAEf,8FAA8F;IAC9F,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACpH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;YAAE,OAAM;QACjC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;QACpE,uDAAuD;IACzD,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,oFAAoF;IACpF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACnC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAM;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAClC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAgB,EAAE,EAAE;YAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,QAAQ;gBAAE,OAAM;YACzE,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QACvG,CAAC,CAAC,CACH,CAAA;QACD,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1C,4FAA4F;IAC9F,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAA;IAEpB,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;QAClC,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;QACjC,QAAQ,EAAE,OAAO,KAAK,SAAS;QAC/B,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;KAChH,CAAC,CAAA;IAEF,mFAAmF;IACnF,+CAA+C;IAC/C,MAAM,UAAU,GAAkB,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;IAE/E,OAAO,CACL,cAAK,SAAS,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAM,SAAS,YACpF,iBACE,GAAG,EAAE,KAAK,EACV,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,qBAAqB,EAC/B,OAAO,EAAE,OAAO,KACZ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC1E,KAAK,EAAE,UAAU,GACjB,GACE,CACP,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;qEAGoC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;wEAyBL,QAAQ;;;;;;;;;MAS1E,CAAA;AAEN,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAG,WAAW,iBAAiB,WAAW,CAAA;IACtD,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAA;AACpH,CAAC"}
package/llms.txt CHANGED
@@ -16,6 +16,8 @@ npm install @liberation-data/desk # peer: react ^19
16
16
  import { createDesk } from '@liberation-data/desk' // no DOM, no React
17
17
  import { Desktop, DeskProvider } from '@liberation-data/desk/react' // components and hooks
18
18
  import '@liberation-data/desk/desk.css' // tokens and styles
19
+ // or only the parts you draw: css/tokens.css (required) + windows|dock|menus|controls|overlays|
20
+ // conversation|search|setup|apps.css
19
21
  ```
20
22
 
21
23
  ## The shape of an app
@@ -65,6 +67,10 @@ interface Desk {
65
67
  fill(id: string): void // fill the desk; remembers the frame for float()
66
68
  toggleMode(id: string): void // zoom: fill ⇄ free
67
69
  placeAll(frames: Record<string, Frame>): void // free windows at these frames; Arrange uses it
70
+ fitToStage(): FitResult // the desk resized: bring windows back on, restore
71
+ // them when the room returns; <Desktop> calls it
72
+ // FitResult { moved, squeezed, restored }: >1 squeezed means the layout is gone, and <Desktop>
73
+ // then arranges for the screen there is now. Frames from the bigger screen still come back.
68
74
  restore(state: DeskState): void // e.g. from a URL; normalised, not trusted
69
75
  setStage(stage: () => Size): void
70
76
  }
@@ -184,6 +190,8 @@ useWindowId(): string | null // inside a window's content
184
190
  title={(id) => ReactNode}
185
191
  note?={(id) => ReactNode} // quiet text in the title bar: what this window is looking at
186
192
  info?={(id) => ReactNode} // an (i) at the end of the title bar: what this window IS
193
+ limits?={(id) => ({ maxWidth?, maxHeight?, minWidth?, minHeight? } | null)} // a window with a natural
194
+ // size is never stretched past it; filled, it centres
187
195
  actions?={(id) => ReactNode} // window-wide controls in the title bar
188
196
  loading?={(id) => ReactNode} // inside a window while its code loads
189
197
  failed?={(id, error, reload) => ReactNode} // inside a window that could not open
@@ -300,13 +308,16 @@ useDeskEvent<T>(topic, handler, { replay? }) // replay: deliver the las
300
308
 
301
309
  ```tsx
302
310
  <AppFrame title src?|srcDoc? listens?={string[]} says?={string[]} accepts?={Accepts} opens?={string[]}
311
+ theme?={{ mode: 'light'|'dark', tokens: Record<string,string> }}
303
312
  sandbox?="allow-scripts allow-forms" />
313
+ // theme: sent with hello and again on change; the bridge sets the tokens as custom properties on the
314
+ // app's root, with data-desk-theme and color-scheme. The app may read desk.theme / desk.onTheme(fn).
304
315
  withAppBridge(html): string // puts the app-side script in the page's <head>
305
316
  APP_BRIDGE_SCRIPT // the same script, to include some other way
306
317
  ```
307
318
 
308
319
  Inside the page: `desk.on(topic, message => …)`, `desk.onDrop(message => …)`, `desk.publish(topic, payload)`,
309
- `desk.open(window)`, and `desk.window` once connected. Messages carry `desk: 1`. The host ignores anything not
320
+ `desk.open(window)`, `desk.theme`, `desk.onTheme(fn)`, and `desk.window` once connected. Messages carry `desk: 1`. The host ignores anything not
310
321
  from its own frame, drops publishes outside `says` and opens outside `opens`, never echoes an app its own
311
322
  events, and sets the frame's `pointer-events: none` while a drag is in the air so drops reach it.
312
323
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liberation-data/desk",
3
- "version": "0.4.0",
3
+ "version": "0.7.0",
4
4
  "description": "A desktop for the web, for React: windows, a dock, menus and commands, controls, tours and setup assistants.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Jasper Blues",
@@ -27,10 +27,11 @@
27
27
  "types": "./dist/react/index.d.ts",
28
28
  "import": "./dist/react/index.js"
29
29
  },
30
- "./desk.css": "./dist/desk.css"
30
+ "./desk.css": "./dist/desk.css",
31
+ "./css/*": "./dist/css/*"
31
32
  },
32
33
  "scripts": {
33
- "build": "rm -rf dist && tsc -p tsconfig.build.json && cp src/desk.css dist/desk.css",
34
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/css.mjs",
34
35
  "typecheck": "tsc --noEmit",
35
36
  "test": "vitest run",
36
37
  "example": "vite examples/garage",
package/src/core/desk.ts CHANGED
@@ -31,6 +31,20 @@ export interface Desk {
31
31
  /** Replaces the whole state, e.g. from a URL. Unknown shapes are normalised, not trusted. */
32
32
  restore(state: DeskState): void
33
33
  setStage(stage: () => Size): void
34
+ /**
35
+ * The desk changed size — an external display unplugged, a window resized. Brings every free
36
+ * window back onto it, and puts each one back where it was when the room returns. Says which
37
+ * windows had to be made smaller to fit, because more than one of those means a layout that no
38
+ * longer exists and is worth laying out again.
39
+ */
40
+ fitToStage(): FitResult
41
+ }
42
+
43
+ /** What a resize did: nothing, moved a window in, shrank one, or gave one its old frame back. */
44
+ export interface FitResult {
45
+ readonly moved: readonly WindowId[]
46
+ readonly squeezed: readonly WindowId[]
47
+ readonly restored: readonly WindowId[]
34
48
  }
35
49
 
36
50
  export const EMPTY: DeskState = { windows: [], stack: [] }
@@ -93,6 +107,10 @@ export function nextCascadeFrame(windows: readonly DeskWindow[], stage: Size, op
93
107
  return cascadeFrame(taken.size % options.wrap, stage, options)
94
108
  }
95
109
 
110
+ /** Is this frame wholly on a desk of this size? */
111
+ const withinStage = (frame: Frame, stage: Size) =>
112
+ frame.x >= 0 && frame.y >= 0 && frame.x + frame.width <= stage.width && frame.y + frame.height <= stage.height
113
+
96
114
  /** Drops duplicate ids and makes the stack agree with the windows. */
97
115
  export function normalise(state: DeskState): DeskState {
98
116
  const windows = state.windows.filter((w, i, all) => all.findIndex(o => o.id === w.id) === i)
@@ -130,6 +148,16 @@ export function createDesk(options: DeskOptions = {}): Desk {
130
148
  /** Where each window was last free, so filling it and freeing it again is not a surprise. */
131
149
  const remembered = new Map<WindowId, Frame>()
132
150
 
151
+ /*
152
+ * Where a window was before the desk got smaller.
153
+ *
154
+ * Undocking a laptop is not a decision about your layout: the windows you spread across a big
155
+ * screen are suddenly past its edge, where they cannot be dragged back from. They are brought in
156
+ * — and kept, so plugging the display back in puts them out again exactly as they were. Move a
157
+ * window yourself while small and that is a decision, so the old frame is forgotten.
158
+ */
159
+ const beforeShrink = new Map<WindowId, Frame>()
160
+
133
161
  /** A remembered frame is only worth restoring while it still lands on this screen. */
134
162
  const fits = (frame: Frame | undefined) => {
135
163
  if (!frame) return undefined
@@ -143,7 +171,11 @@ export function createDesk(options: DeskOptions = {}): Desk {
143
171
  if (!window) return
144
172
  if (window.mode === 'floating' && !frame) return
145
173
  const next = frame ?? fits(remembered.get(id)) ?? nextFrame(state)
146
- if (frame) remembered.set(id, frame)
174
+ if (frame) {
175
+ remembered.set(id, frame)
176
+ // Put here on purpose, so this is where it belongs now.
177
+ beforeShrink.delete(id)
178
+ }
147
179
  layouts?.save(windowType(id), { mode: 'floating', frame: next })
148
180
  commit(toFront(replace(state, { id, mode: 'floating', frame: next }), id))
149
181
  }
@@ -240,5 +272,39 @@ export function createDesk(options: DeskOptions = {}): Desk {
240
272
  setStage(next) {
241
273
  stage = next
242
274
  },
275
+
276
+ fitToStage() {
277
+ const nothing: FitResult = { moved: [], squeezed: [], restored: [] }
278
+ const size = stage()
279
+ if (size.width <= 0 || size.height <= 0) return nothing
280
+ const moved: WindowId[] = []
281
+ const squeezed: WindowId[] = []
282
+ const restored: WindowId[] = []
283
+ const windows = state.windows.map(window => {
284
+ if (window.mode !== 'floating') return window
285
+ // The desk is big enough again for where this window used to be: put it back.
286
+ const before = beforeShrink.get(window.id)
287
+ if (before && withinStage(before, size)) {
288
+ beforeShrink.delete(window.id)
289
+ restored.push(window.id)
290
+ return { ...window, frame: before }
291
+ }
292
+ if (withinStage(window.frame, size)) return window
293
+ const fitted = fitFrame(window.frame, size)
294
+ if (!beforeShrink.has(window.id)) beforeShrink.set(window.id, before ?? window.frame)
295
+ if (!fitted) {
296
+ // Too small to be a window here at all: it fills the desk until there is room again.
297
+ squeezed.push(window.id)
298
+ return { id: window.id, mode: 'filled' as const }
299
+ }
300
+ // Only nudged back in, or actually made smaller? The second means its place is gone.
301
+ if (fitted.width < window.frame.width || fitted.height < window.frame.height) squeezed.push(window.id)
302
+ else moved.push(window.id)
303
+ return { ...window, frame: fitted }
304
+ })
305
+ if (!moved.length && !squeezed.length && !restored.length) return nothing
306
+ commit({ ...state, windows })
307
+ return { moved, squeezed, restored }
308
+ },
243
309
  }
244
310
  }
package/src/core/index.ts CHANGED
@@ -10,7 +10,7 @@ export {
10
10
  windowType,
11
11
  EMPTY,
12
12
  } from './desk.js'
13
- export type { Desk } from './desk.js'
13
+ export type { Desk, FitResult } from './desk.js'
14
14
  export {
15
15
  addCommandHandler,
16
16
  addDeskCommands,
@@ -41,5 +41,6 @@ export type {
41
41
  OpenOptions,
42
42
  Size,
43
43
  WindowId,
44
+ WindowLimits,
44
45
  WindowMode,
45
46
  } from './types.js'
package/src/core/types.ts CHANGED
@@ -51,3 +51,11 @@ export interface OpenOptions {
51
51
  readonly mode?: WindowMode
52
52
  readonly frame?: Frame
53
53
  }
54
+
55
+ /** How big a window may be. Everything is optional; a window with no limits takes what it is given. */
56
+ export interface WindowLimits {
57
+ readonly minWidth?: number
58
+ readonly minHeight?: number
59
+ readonly maxWidth?: number
60
+ readonly maxHeight?: number
61
+ }