@liberation-data/desk 0.6.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.
package/README.md CHANGED
@@ -84,6 +84,22 @@ what went wrong and offers Reload, which tries the import again rather than reme
84
84
  `renderWindow` is called with a window's id. The desk never owns your content, and a window keeps its DOM
85
85
  when focus moves, so scroll positions, carets and iframes survive.
86
86
 
87
+ ### How big a window may be
88
+
89
+ ```tsx
90
+ <Desktop
91
+ title={id => TITLES[id]}
92
+ limits={id => (id === 'about' ? { maxWidth: 720, maxHeight: 560 } : null)}
93
+ renderWindow={render}
94
+ />
95
+ ```
96
+
97
+ Most windows want the whole desk when filled and whatever they are dragged to when free, which is
98
+ what `null` says. A window whose content has a natural size — an About box, a short form — says so
99
+ and is never stretched past it, however it is filled, arranged or dragged; filled, it sits in the
100
+ middle of the room it was given rather than in a corner of it. `minWidth` and `minHeight` work the
101
+ same way.
102
+
87
103
  ### What a window is looking at
88
104
 
89
105
  ```tsx
@@ -322,8 +338,23 @@ part like any other:
322
338
  />
323
339
  ```
324
340
 
341
+ Give it `theme` and the app wears the desk's look instead of whatever its author hard-coded:
342
+
343
+ ```tsx
344
+ <AppFrame
345
+ title="Ride Card"
346
+ srcDoc={withAppBridge(generatedHtml)}
347
+ theme={{ mode: 'dark', tokens: { '--sb-bg-dark': '#0b0f1a', '--sb-accent': '#625fff' } }}
348
+ />
349
+ ```
350
+
351
+ The bridge sets those custom properties on the app's own root, stamps `data-desk-theme` and
352
+ `color-scheme` with the mode, and re-sends the lot whenever it changes — a person switching theme
353
+ switched the app too, not just the chrome around it. An app that would rather decide for itself can
354
+ read `desk.theme`, watch `desk.onTheme(…)`, or ignore both.
355
+
325
356
  Inside the page, the bridge gives it a small `desk` object: `desk.on(topic, …)`, `desk.onDrop(…)`,
326
- `desk.publish(topic, payload)` and `desk.open(window)`. The page runs sandboxed with no access to the host's
357
+ `desk.publish(topic, payload)`, `desk.open(window)`, `desk.theme` and `desk.onTheme()`. The page runs sandboxed with no access to the host's
327
358
  origin, and talks only through messages. The host grants each app its topics, drop types and windows;
328
359
  anything else it sends is dropped, and messages from anywhere but its own frame are ignored.
329
360
 
@@ -11,5 +11,5 @@ export { isTitleCase, titleCase } from './titles.js';
11
11
  export { fitFrame, localLayoutStore, stepFrom } from './layouts.js';
12
12
  export type { LayoutStore, SavedLayout } from './layouts.js';
13
13
  export type { LocationEnv, LocationOptions } from './location.js';
14
- export type { CascadeOptions, DeskOptions, DeskState, DeskWindow, Frame, OpenOptions, Size, WindowId, WindowMode, } from './types.js';
14
+ export type { CascadeOptions, DeskOptions, DeskState, DeskWindow, Frame, OpenOptions, Size, WindowId, WindowLimits, WindowMode, } from './types.js';
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,MAAM,EACN,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,KAAK,GACN,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,UAAU,EACV,YAAY,EACZ,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACpE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC/H,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACvE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACnE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACjE,YAAY,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,MAAM,EACN,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,KAAK,GACN,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,UAAU,EACV,YAAY,EACZ,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACpE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC/H,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACvE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACnE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACjE,YAAY,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAA"}
@@ -51,4 +51,11 @@ export interface OpenOptions {
51
51
  readonly mode?: WindowMode;
52
52
  readonly frame?: Frame;
53
53
  }
54
+ /** How big a window may be. Everything is optional; a window with no limits takes what it is given. */
55
+ export interface WindowLimits {
56
+ readonly minWidth?: number;
57
+ readonly minHeight?: number;
58
+ readonly maxWidth?: number;
59
+ readonly maxHeight?: number;
60
+ }
54
61
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAA;AAE7B,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,UAAU;AACpB,oDAAoD;AAClD;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAE/E,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;AAE3C,MAAM,WAAW,SAAS;IACxB,0HAA0H;IAC1H,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IACvC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAA;AAE7B,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,UAAU;AACpB,oDAAoD;AAClD;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAE/E,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;AAE3C,MAAM,WAAW,SAAS;IACxB,0HAA0H;IAC1H,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IACvC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB;AAED,uGAAuG;AACvG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B"}
@@ -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;AAIxF,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,+BAqHrI"}
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);
@@ -118,7 +118,7 @@ export function Desktop({ renderWindow, title, note, info, actions, empty, loadi
118
118
  }, [focused]);
119
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,
120
120
  // One window at a time: the rest stay mounted, keeping their state, and simply wait offstage.
121
- 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)))] }));
122
122
  }
123
123
  // Each window loads and fails on its own: one fetching its code, or throwing, never blanks another.
124
124
  const WindowContent = memo(function WindowContent({ id, render, loading, failed }) {
@@ -161,7 +161,7 @@ function reshape(gesture, origin, dx, dy) {
161
161
  }
162
162
  }
163
163
  }
164
- 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 }) {
165
165
  const desk = useDesk();
166
166
  // While dragging, the frame lives here and commits once on release, so a drag
167
167
  // re-renders one window rather than notifying every subscriber per pixel.
@@ -246,11 +246,24 @@ function WindowView({ window, layout, hidden, depth, focused, title, note, info,
246
246
  desk.toggleMode(window.id);
247
247
  };
248
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
+ };
249
262
  const style = layout !== 'desktop'
250
- ? undefined
263
+ ? capped
251
264
  : frame
252
- ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth }
253
- : { 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 };
254
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: () => {
255
268
  if (!focused)
256
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":"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"}
package/llms.txt CHANGED
@@ -190,6 +190,8 @@ useWindowId(): string | null // inside a window's content
190
190
  title={(id) => ReactNode}
191
191
  note?={(id) => ReactNode} // quiet text in the title bar: what this window is looking at
192
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
193
195
  actions?={(id) => ReactNode} // window-wide controls in the title bar
194
196
  loading?={(id) => ReactNode} // inside a window while its code loads
195
197
  failed?={(id, error, reload) => ReactNode} // inside a window that could not open
@@ -306,13 +308,16 @@ useDeskEvent<T>(topic, handler, { replay? }) // replay: deliver the las
306
308
 
307
309
  ```tsx
308
310
  <AppFrame title src?|srcDoc? listens?={string[]} says?={string[]} accepts?={Accepts} opens?={string[]}
311
+ theme?={{ mode: 'light'|'dark', tokens: Record<string,string> }}
309
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).
310
315
  withAppBridge(html): string // puts the app-side script in the page's <head>
311
316
  APP_BRIDGE_SCRIPT // the same script, to include some other way
312
317
  ```
313
318
 
314
319
  Inside the page: `desk.on(topic, message => …)`, `desk.onDrop(message => …)`, `desk.publish(topic, payload)`,
315
- `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
316
321
  from its own frame, drops publishes outside `says` and opens outside `opens`, never echoes an app its own
317
322
  events, and sets the frame's `pointer-events: none` while a drag is in the air so drops reach it.
318
323
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liberation-data/desk",
3
- "version": "0.6.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",
package/src/core/index.ts CHANGED
@@ -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
+ }
@@ -3,7 +3,7 @@ import type { CSSProperties, PointerEvent as ReactPointerEvent, ReactNode } from
3
3
  import { addCommandHandler, addDeskCommands, DeskCommands, STAGE_ATTRIBUTE, WINDOW_ATTRIBUTE, windowElement } from '../core/commands.js'
4
4
  import { focusedId } from '../core/desk.js'
5
5
  import type { Desk } from '../core/desk.js'
6
- import type { DeskWindow, Frame, WindowId } from '../core/types.js'
6
+ import type { DeskWindow, Frame, WindowId, WindowLimits } from '../core/types.js'
7
7
  import { arrangement } from './arrange.js'
8
8
  import { InfoTip } from './infoTip.js'
9
9
  import { useDesk, useDeskState, WindowContext } from './context.js'
@@ -21,6 +21,13 @@ export interface DesktopProps {
21
21
  * gives way to the actions and disappears before the title does when the window is narrow.
22
22
  */
23
23
  readonly note?: (id: WindowId) => ReactNode
24
+ /**
25
+ * How big this window may be. Most windows want the whole desk when filled and whatever they are
26
+ * dragged to when free, which is what `null` says. A window whose content has a natural size —
27
+ * an About box, a small form — says so, and is never stretched past it, however it is filled,
28
+ * arranged or dragged.
29
+ */
30
+ readonly limits?: (id: WindowId) => WindowLimits | null
24
31
  /**
25
32
  * What this window is, behind an (i) at the end of its title bar — the same place in every window,
26
33
  * so a person who wonders what they are looking at always knows where to ask. Explanation only: a
@@ -84,7 +91,7 @@ const halfFrame = (stage: HTMLElement, side: 'start' | 'end'): Frame => {
84
91
  return { x: side === 'start' ? area.x : area.x + width + area.gap, y: area.y, width, height: area.height }
85
92
  }
86
93
 
87
- export function Desktop({ renderWindow, title, note, info, actions, empty, loading, failed, layout = 'auto', className }: DesktopProps) {
94
+ export function Desktop({ renderWindow, title, note, info, actions, limits, empty, loading, failed, layout = 'auto', className }: DesktopProps) {
88
95
  const desk = useDesk()
89
96
  const state = useDeskState()
90
97
  const stage = useRef<HTMLDivElement>(null)
@@ -192,6 +199,7 @@ export function Desktop({ renderWindow, title, note, info, actions, empty, loadi
192
199
  title={title(window.id)}
193
200
  note={note?.(window.id)}
194
201
  info={info?.(window.id)}
202
+ limits={limits?.(window.id) ?? null}
195
203
  actions={actions?.(window.id)}
196
204
  >
197
205
  {/* Memoised on the id and the render function: moving or focusing a window
@@ -228,6 +236,7 @@ interface WindowViewProps {
228
236
  readonly title: ReactNode
229
237
  readonly note?: ReactNode
230
238
  readonly info?: ReactNode
239
+ readonly limits?: WindowLimits | null
231
240
  readonly actions?: ReactNode
232
241
  readonly children: ReactNode
233
242
  }
@@ -276,7 +285,7 @@ function reshape(gesture: Gesture, origin: Frame, dx: number, dy: number): Frame
276
285
  }
277
286
  }
278
287
 
279
- function WindowView({ window, layout, hidden, depth, focused, title, note, info, actions, children }: WindowViewProps) {
288
+ function WindowView({ window, layout, hidden, depth, focused, title, note, info, actions, limits, children }: WindowViewProps) {
280
289
  const desk = useDesk()
281
290
  // While dragging, the frame lives here and commits once on release, so a drag
282
291
  // re-renders one window rather than notifying every subscriber per pixel.
@@ -355,12 +364,25 @@ function WindowView({ window, layout, hidden, depth, focused, title, note, info,
355
364
  }
356
365
 
357
366
  const frame = layout === 'desktop' ? (live ?? (window.mode === 'floating' ? window.frame : null)) : null
367
+ /*
368
+ * A window that says how big it may be is capped in the browser rather than in the state: filling
369
+ * the desk, being arranged into a cell and being dragged wider all end at the same place, and the
370
+ * window sits in the middle of whatever room it was given rather than pinned to a corner of it.
371
+ */
372
+ const capped: CSSProperties = {
373
+ ...(limits?.maxWidth ? { maxWidth: limits.maxWidth } : {}),
374
+ ...(limits?.maxHeight ? { maxHeight: limits.maxHeight } : {}),
375
+ ...(limits?.minWidth ? { minWidth: limits.minWidth } : {}),
376
+ ...(limits?.minHeight ? { minHeight: limits.minHeight } : {}),
377
+ // Filled and capped: it sits in the middle of the room, not in the corner of it.
378
+ ...(limits && (limits.maxWidth || limits.maxHeight) && !frame ? { margin: 'auto' } : {}),
379
+ }
358
380
  const style: CSSProperties | undefined =
359
381
  layout !== 'desktop'
360
- ? undefined
382
+ ? capped
361
383
  : frame
362
- ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth }
363
- : { zIndex: 10 + depth }
384
+ ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth, ...capped }
385
+ : { zIndex: 10 + depth, ...capped }
364
386
 
365
387
  return (
366
388
  <WindowContext.Provider value={context}>
@@ -20,8 +20,27 @@ import { useBus } from './events.js'
20
20
  /** The protocol version. Every message carries it, so a mismatch is ignored rather than misread. */
21
21
  const PROTOCOL = 1
22
22
 
23
+ /*
24
+ * THE HOST'S LOOK, OFFERED TO THE APP.
25
+ *
26
+ * An app runs in a frame of its own, so by default it wears whatever its author hard-coded: a white
27
+ * page inside a dark desk, a dark one inside a light desk. Switching the desk's theme should carry
28
+ * the app too — the person switched the whole thing, not the chrome around it.
29
+ *
30
+ * So the host offers its palette, and the app takes it or ignores it. `mode` says which way round
31
+ * the page is, for an app that decides its own colours but wants to know; `tokens` are custom
32
+ * properties the bridge sets on the app's own root, so an app that reads them gets the desk's
33
+ * colours with nothing to write.
34
+ */
35
+ export interface AppTheme {
36
+ readonly mode: 'light' | 'dark'
37
+ /** Custom properties, named as they will be set: `{ '--sb-bg-dark': '#0b0f1a' }`. */
38
+ readonly tokens: Readonly<Record<string, string>>
39
+ }
40
+
23
41
  type HostMessage =
24
- | { readonly desk: 1; readonly kind: 'hello'; readonly window: string | null; readonly listens: readonly string[]; readonly says: readonly string[] }
42
+ | { readonly desk: 1; readonly kind: 'hello'; readonly window: string | null; readonly listens: readonly string[]; readonly says: readonly string[]; readonly theme: AppTheme | null }
43
+ | { readonly desk: 1; readonly kind: 'theme'; readonly theme: AppTheme }
25
44
  | { readonly desk: 1; readonly kind: 'event'; readonly topic: string; readonly payload: unknown; readonly from: string | null }
26
45
  | { readonly desk: 1; readonly kind: 'drop'; readonly type: string; readonly payload: unknown; readonly from: string | null }
27
46
 
@@ -43,6 +62,8 @@ export interface AppFrameProps {
43
62
  readonly listens?: readonly string[]
44
63
  /** Topics the app may say. Anything else it publishes is dropped. Default: none. */
45
64
  readonly says?: readonly string[]
65
+ /** The desk's own look, offered to the app: it is applied to the app's root and re-sent on change. */
66
+ readonly theme?: AppTheme
46
67
  /** What may be dropped on it. Default: nothing. */
47
68
  readonly accepts?: Accepts
48
69
  /** Windows the app may ask to open. Default: none. */
@@ -61,6 +82,7 @@ export function AppFrame({
61
82
  srcDoc,
62
83
  listens = [],
63
84
  says = [],
85
+ theme,
64
86
  accepts,
65
87
  opens = [],
66
88
  sandbox = 'allow-scripts allow-forms',
@@ -79,8 +101,8 @@ export function AppFrame({
79
101
  frame.current?.contentWindow?.postMessage(message, '*')
80
102
  }
81
103
 
82
- const latest = useRef({ listens, says, opens, windowId })
83
- latest.current = { listens, says, opens, windowId }
104
+ const latest = useRef({ listens, says, opens, windowId, theme })
105
+ latest.current = { listens, says, opens, windowId, theme }
84
106
 
85
107
  // What the app says: only from this frame, only on topics it was granted.
86
108
  useEffect(() => {
@@ -89,7 +111,7 @@ export function AppFrame({
89
111
  const message = event.data
90
112
  const granted = latest.current
91
113
  if (message.kind === 'ready') {
92
- post({ desk: PROTOCOL, kind: 'hello', window: granted.windowId, listens: granted.listens, says: granted.says })
114
+ post({ desk: PROTOCOL, kind: 'hello', window: granted.windowId, listens: granted.listens, says: granted.says, theme: granted.theme ?? null })
93
115
  } else if (message.kind === 'publish') {
94
116
  if (typeof message.topic === 'string' && granted.says.some(pattern => topicMatches(pattern, message.topic))) {
95
117
  bus.publish(message.topic, message.payload, { from: granted.windowId })
@@ -102,6 +124,14 @@ export function AppFrame({
102
124
  return () => window.removeEventListener('message', onMessage)
103
125
  }, [bus, desk])
104
126
 
127
+ // The desk's look, again, whenever it changes: a person switching theme switches the app too.
128
+ const themeKey = theme ? `${theme.mode}|${Object.entries(theme.tokens).map(([k, v]) => `${k}:${v}`).join(';')}` : ''
129
+ useEffect(() => {
130
+ if (!latest.current.theme) return
131
+ post({ desk: PROTOCOL, kind: 'theme', theme: latest.current.theme })
132
+ // eslint-disable-next-line react-hooks/exhaustive-deps
133
+ }, [themeKey])
134
+
105
135
  // What the app hears: only the topics it was granted, and never its own words back.
106
136
  const listenKey = listens.join('|')
107
137
  useEffect(() => {
@@ -154,10 +184,22 @@ export const APP_BRIDGE_SCRIPT = `(() => {
154
184
  const handlers = new Map();
155
185
  const drops = [];
156
186
  const send = message => parent.postMessage(Object.assign({ desk: ${PROTOCOL} }, message), '*');
187
+ const applyTheme = theme => {
188
+ if (!theme) return;
189
+ desk.theme = theme;
190
+ const root = document.documentElement;
191
+ root.dataset.deskTheme = theme.mode;
192
+ root.style.colorScheme = theme.mode;
193
+ for (const [name, value] of Object.entries(theme.tokens || {})) root.style.setProperty(name, value);
194
+ themed.forEach(h => h(theme));
195
+ };
196
+ const themed = [];
157
197
  const desk = {
158
198
  window: null,
159
199
  listens: [],
160
200
  says: [],
201
+ theme: null,
202
+ onTheme(handler) { themed.push(handler); if (desk.theme) handler(desk.theme); },
161
203
  on(topic, handler) { (handlers.get(topic) || handlers.set(topic, []).get(topic)).push(handler); },
162
204
  onDrop(handler) { drops.push(handler); },
163
205
  publish(topic, payload) { send({ kind: 'publish', topic, payload }); },
@@ -168,7 +210,8 @@ export const APP_BRIDGE_SCRIPT = `(() => {
168
210
  addEventListener('message', event => {
169
211
  if (event.source !== parent || !event.data || event.data.desk !== ${PROTOCOL}) return;
170
212
  const message = event.data;
171
- if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; }
213
+ if (message.kind === 'hello') { desk.window = message.window; desk.listens = message.listens; desk.says = message.says; applyTheme(message.theme); }
214
+ if (message.kind === 'theme') applyTheme(message.theme);
172
215
  if (message.kind === 'event') for (const [pattern, list] of handlers) if (matches(pattern, message.topic)) list.forEach(h => h(message));
173
216
  if (message.kind === 'drop') drops.forEach(h => h(message));
174
217
  });