@liberation-data/desk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +4 -0
  3. package/README.md +436 -0
  4. package/dist/core/commands.d.ts +40 -0
  5. package/dist/core/commands.d.ts.map +1 -0
  6. package/dist/core/commands.js +92 -0
  7. package/dist/core/commands.js.map +1 -0
  8. package/dist/core/desk.d.ts +46 -0
  9. package/dist/core/desk.d.ts.map +1 -0
  10. package/dist/core/desk.js +178 -0
  11. package/dist/core/desk.js.map +1 -0
  12. package/dist/core/events.d.ts +42 -0
  13. package/dist/core/events.d.ts.map +1 -0
  14. package/dist/core/events.js +54 -0
  15. package/dist/core/events.js.map +1 -0
  16. package/dist/core/index.d.ts +13 -0
  17. package/dist/core/index.d.ts.map +1 -0
  18. package/dist/core/index.js +7 -0
  19. package/dist/core/index.js.map +1 -0
  20. package/dist/core/location.d.ts +30 -0
  21. package/dist/core/location.d.ts.map +1 -0
  22. package/dist/core/location.js +99 -0
  23. package/dist/core/location.js.map +1 -0
  24. package/dist/core/shortcuts.d.ts +36 -0
  25. package/dist/core/shortcuts.d.ts.map +1 -0
  26. package/dist/core/shortcuts.js +73 -0
  27. package/dist/core/shortcuts.js.map +1 -0
  28. package/dist/core/titles.d.ts +3 -0
  29. package/dist/core/titles.d.ts.map +1 -0
  30. package/dist/core/titles.js +26 -0
  31. package/dist/core/titles.js.map +1 -0
  32. package/dist/core/types.d.ts +51 -0
  33. package/dist/core/types.d.ts.map +1 -0
  34. package/dist/core/types.js +2 -0
  35. package/dist/core/types.js.map +1 -0
  36. package/dist/desk.css +2550 -0
  37. package/dist/react/Desktop.d.ts +24 -0
  38. package/dist/react/Desktop.d.ts.map +1 -0
  39. package/dist/react/Desktop.js +212 -0
  40. package/dist/react/Desktop.js.map +1 -0
  41. package/dist/react/Dock.d.ts +42 -0
  42. package/dist/react/Dock.d.ts.map +1 -0
  43. package/dist/react/Dock.js +103 -0
  44. package/dist/react/Dock.js.map +1 -0
  45. package/dist/react/MenuBar.d.ts +64 -0
  46. package/dist/react/MenuBar.d.ts.map +1 -0
  47. package/dist/react/MenuBar.js +245 -0
  48. package/dist/react/MenuBar.js.map +1 -0
  49. package/dist/react/appFrame.d.ts +37 -0
  50. package/dist/react/appFrame.d.ts.map +1 -0
  51. package/dist/react/appFrame.js +119 -0
  52. package/dist/react/appFrame.js.map +1 -0
  53. package/dist/react/arrange.d.ts +24 -0
  54. package/dist/react/arrange.d.ts.map +1 -0
  55. package/dist/react/arrange.js +61 -0
  56. package/dist/react/arrange.js.map +1 -0
  57. package/dist/react/commands.d.ts +23 -0
  58. package/dist/react/commands.d.ts.map +1 -0
  59. package/dist/react/commands.js +41 -0
  60. package/dist/react/commands.js.map +1 -0
  61. package/dist/react/context.d.ts +25 -0
  62. package/dist/react/context.d.ts.map +1 -0
  63. package/dist/react/context.js +28 -0
  64. package/dist/react/context.js.map +1 -0
  65. package/dist/react/controls.d.ts +111 -0
  66. package/dist/react/controls.d.ts.map +1 -0
  67. package/dist/react/controls.js +83 -0
  68. package/dist/react/controls.js.map +1 -0
  69. package/dist/react/conversation.d.ts +41 -0
  70. package/dist/react/conversation.d.ts.map +1 -0
  71. package/dist/react/conversation.js +73 -0
  72. package/dist/react/conversation.js.map +1 -0
  73. package/dist/react/dnd.d.ts +51 -0
  74. package/dist/react/dnd.d.ts.map +1 -0
  75. package/dist/react/dnd.js +138 -0
  76. package/dist/react/dnd.js.map +1 -0
  77. package/dist/react/dragContext.d.ts +32 -0
  78. package/dist/react/dragContext.d.ts.map +1 -0
  79. package/dist/react/dragContext.js +14 -0
  80. package/dist/react/dragContext.js.map +1 -0
  81. package/dist/react/events.d.ts +41 -0
  82. package/dist/react/events.d.ts.map +1 -0
  83. package/dist/react/events.js +91 -0
  84. package/dist/react/events.js.map +1 -0
  85. package/dist/react/index.d.ts +43 -0
  86. package/dist/react/index.d.ts.map +1 -0
  87. package/dist/react/index.js +22 -0
  88. package/dist/react/index.js.map +1 -0
  89. package/dist/react/layers.d.ts +5 -0
  90. package/dist/react/layers.d.ts.map +1 -0
  91. package/dist/react/layers.js +65 -0
  92. package/dist/react/layers.js.map +1 -0
  93. package/dist/react/overlays.d.ts +67 -0
  94. package/dist/react/overlays.d.ts.map +1 -0
  95. package/dist/react/overlays.js +98 -0
  96. package/dist/react/overlays.js.map +1 -0
  97. package/dist/react/popup.d.ts +21 -0
  98. package/dist/react/popup.d.ts.map +1 -0
  99. package/dist/react/popup.js +94 -0
  100. package/dist/react/popup.js.map +1 -0
  101. package/dist/react/search.d.ts +33 -0
  102. package/dist/react/search.d.ts.map +1 -0
  103. package/dist/react/search.js +82 -0
  104. package/dist/react/search.js.map +1 -0
  105. package/dist/react/setupProgress.d.ts +35 -0
  106. package/dist/react/setupProgress.d.ts.map +1 -0
  107. package/dist/react/setupProgress.js +68 -0
  108. package/dist/react/setupProgress.js.map +1 -0
  109. package/dist/react/shell.d.ts +17 -0
  110. package/dist/react/shell.d.ts.map +1 -0
  111. package/dist/react/shell.js +13 -0
  112. package/dist/react/shell.js.map +1 -0
  113. package/dist/react/sidebar.d.ts +23 -0
  114. package/dist/react/sidebar.d.ts.map +1 -0
  115. package/dist/react/sidebar.js +26 -0
  116. package/dist/react/sidebar.js.map +1 -0
  117. package/dist/react/table.d.ts +39 -0
  118. package/dist/react/table.d.ts.map +1 -0
  119. package/dist/react/table.js +86 -0
  120. package/dist/react/table.js.map +1 -0
  121. package/dist/react/tasks.d.ts +41 -0
  122. package/dist/react/tasks.d.ts.map +1 -0
  123. package/dist/react/tasks.js +79 -0
  124. package/dist/react/tasks.js.map +1 -0
  125. package/dist/react/tour.d.ts +42 -0
  126. package/dist/react/tour.d.ts.map +1 -0
  127. package/dist/react/tour.js +68 -0
  128. package/dist/react/tour.js.map +1 -0
  129. package/dist/react/windowBoundary.d.ts +22 -0
  130. package/dist/react/windowBoundary.d.ts.map +1 -0
  131. package/dist/react/windowBoundary.js +50 -0
  132. package/dist/react/windowBoundary.js.map +1 -0
  133. package/dist/react/wizard.d.ts +41 -0
  134. package/dist/react/wizard.d.ts.map +1 -0
  135. package/dist/react/wizard.js +60 -0
  136. package/dist/react/wizard.js.map +1 -0
  137. package/llms.txt +410 -0
  138. package/package.json +64 -0
  139. package/src/core/commands.ts +142 -0
  140. package/src/core/desk.ts +229 -0
  141. package/src/core/events.ts +99 -0
  142. package/src/core/index.ts +43 -0
  143. package/src/core/location.ts +127 -0
  144. package/src/core/shortcuts.ts +119 -0
  145. package/src/core/titles.ts +28 -0
  146. package/src/core/types.ts +49 -0
  147. package/src/desk.css +2550 -0
  148. package/src/react/Desktop.tsx +349 -0
  149. package/src/react/Dock.tsx +258 -0
  150. package/src/react/MenuBar.tsx +350 -0
  151. package/src/react/appFrame.tsx +183 -0
  152. package/src/react/arrange.ts +82 -0
  153. package/src/react/commands.ts +60 -0
  154. package/src/react/context.tsx +55 -0
  155. package/src/react/controls.tsx +364 -0
  156. package/src/react/conversation.tsx +208 -0
  157. package/src/react/dnd.tsx +189 -0
  158. package/src/react/dragContext.tsx +60 -0
  159. package/src/react/events.tsx +149 -0
  160. package/src/react/index.ts +64 -0
  161. package/src/react/layers.ts +66 -0
  162. package/src/react/overlays.tsx +254 -0
  163. package/src/react/popup.tsx +176 -0
  164. package/src/react/search.tsx +177 -0
  165. package/src/react/setupProgress.ts +113 -0
  166. package/src/react/shell.tsx +27 -0
  167. package/src/react/sidebar.tsx +84 -0
  168. package/src/react/table.tsx +176 -0
  169. package/src/react/tasks.tsx +176 -0
  170. package/src/react/tour.tsx +183 -0
  171. package/src/react/windowBoundary.tsx +110 -0
  172. package/src/react/wizard.tsx +150 -0
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { WindowId } from '../core/types.js';
3
+ import type { WindowFailed, WindowLoading } from './windowBoundary.js';
4
+ export type DeskLayout = 'desktop' | 'fullscreen';
5
+ export interface DesktopProps {
6
+ readonly renderWindow: (id: WindowId) => ReactNode;
7
+ readonly title: (id: WindowId) => ReactNode;
8
+ /** Window-wide controls on the trailing side of the title bar. One or two; more belongs in a toolbar. */
9
+ readonly actions?: (id: WindowId) => ReactNode;
10
+ /** Shown when no window is open. */
11
+ readonly empty?: ReactNode;
12
+ /** Shown inside a window while its code loads. Default: a quiet "Loading…". */
13
+ readonly loading?: WindowLoading;
14
+ /** Shown inside a window that could not open, with a way to try again. */
15
+ readonly failed?: WindowFailed;
16
+ /**
17
+ * `auto` (the default) reads the device: a touch screen gets `fullscreen`, one
18
+ * window at a time; anything with a pointer gets the layered `desktop`.
19
+ */
20
+ readonly layout?: DeskLayout | 'auto';
21
+ readonly className?: string;
22
+ }
23
+ export declare function Desktop({ renderWindow, title, actions, empty, loading, failed, layout, className }: DesktopProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=Desktop.d.ts.map
@@ -0,0 +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;AAInE,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,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,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAe,EAAE,SAAS,EAAE,EAAE,YAAY,+BAyFzH"}
@@ -0,0 +1,212 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
3
+ import { addCommandHandler, addDeskCommands, DeskCommands, STAGE_ATTRIBUTE, WINDOW_ATTRIBUTE, windowElement } from '../core/commands.js';
4
+ import { focusedId } from '../core/desk.js';
5
+ import { arrangement } from './arrange.js';
6
+ import { useDesk, useDeskState, WindowContext } from './context.js';
7
+ import { WindowBoundary } from './windowBoundary.js';
8
+ /** Touch-first: a coarse pointer that cannot hover. A tablet with a trackpad reports otherwise. */
9
+ const TOUCH = '(pointer: coarse) and (hover: none)';
10
+ function useMediaQuery(query) {
11
+ const subscribe = useCallback((onChange) => {
12
+ const list = globalThis.matchMedia?.(query);
13
+ list?.addEventListener('change', onChange);
14
+ return () => list?.removeEventListener('change', onChange);
15
+ }, [query]);
16
+ return useSyncExternalStore(subscribe, () => globalThis.matchMedia?.(query).matches ?? false, () => false);
17
+ }
18
+ const MIN_WIDTH = 240;
19
+ const MIN_HEIGHT = 160;
20
+ /** How close to the edge a dragged window has to get before it takes that half. */
21
+ const SNAP_MARGIN = 56;
22
+ /** The part of the stage windows are arranged in: inside its padding, with its gap. */
23
+ function arrangementArea(stage) {
24
+ const style = getComputedStyle(stage);
25
+ const left = parseFloat(style.paddingLeft) || 0;
26
+ const right = parseFloat(style.paddingRight) || 0;
27
+ const top = parseFloat(style.paddingTop) || 0;
28
+ const bottom = parseFloat(style.paddingBottom) || 0;
29
+ const gap = parseFloat(style.columnGap) || 0;
30
+ return { x: left, y: top, width: stage.clientWidth - left - right, height: stage.clientHeight - top - bottom, gap };
31
+ }
32
+ const halfFrame = (stage, side) => {
33
+ const area = arrangementArea(stage);
34
+ const width = (area.width - area.gap) / 2;
35
+ return { x: side === 'start' ? area.x : area.x + width + area.gap, y: area.y, width, height: area.height };
36
+ };
37
+ export function Desktop({ renderWindow, title, actions, empty, loading, failed, layout = 'auto', className }) {
38
+ const desk = useDesk();
39
+ const state = useDeskState();
40
+ const stage = useRef(null);
41
+ const touch = useMediaQuery(TOUCH);
42
+ const mode = layout === 'auto' ? (touch ? 'fullscreen' : 'desktop') : layout;
43
+ useLayoutEffect(() => {
44
+ desk.setStage(() => ({ width: stage.current?.clientWidth ?? 1024, height: stage.current?.clientHeight ?? 768 }));
45
+ }, [desk]);
46
+ useEffect(() => (stage.current ? addDeskCommands(stage.current, desk) : undefined), [desk]);
47
+ // Arrange lays every window out once, as free windows that can be moved again straight away.
48
+ useEffect(() => {
49
+ const element = stage.current;
50
+ if (!element || mode !== 'desktop')
51
+ return undefined;
52
+ return addCommandHandler(element, DeskCommands.arrange, () => {
53
+ const { windows, stack } = desk.getState();
54
+ const [focused, previous] = [stack.at(-1), stack.at(-2)];
55
+ if (windows.length === 1) {
56
+ if (focused)
57
+ desk.fill(focused);
58
+ return;
59
+ }
60
+ const frames = arrangement(windows.map(w => w.id), focused ?? null, previous ?? null, arrangementArea(element), { minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT });
61
+ desk.placeAll(frames);
62
+ // Windows that cascade come in front of the half they cascade over; the focused window stays in front of all.
63
+ if (previous)
64
+ desk.focus(previous);
65
+ windows.forEach(w => w.id !== focused && w.id !== previous && desk.focus(w.id));
66
+ if (focused)
67
+ desk.focus(focused);
68
+ }, {
69
+ enabled: () => {
70
+ const { windows } = desk.getState();
71
+ return windows.length > 1 || windows.some(w => w.mode === 'floating');
72
+ },
73
+ });
74
+ }, [desk, mode]);
75
+ const focused = focusedId(state);
76
+ // Keyboard focus follows the key window, so commands and typing reach the window the person just chose.
77
+ // Not on first render: loading a page should not pull focus away from wherever the browser put it.
78
+ const previousFocus = useRef(undefined);
79
+ useEffect(() => {
80
+ const before = previousFocus.current;
81
+ previousFocus.current = focused;
82
+ if (before === undefined || before === focused || !focused || !stage.current)
83
+ return;
84
+ const element = windowElement(stage.current, focused);
85
+ if (element instanceof HTMLElement && !element.contains(document.activeElement))
86
+ element.focus({ preventScroll: true });
87
+ }, [focused]);
88
+ 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,
89
+ // One window at a time: the rest stay mounted, keeping their state, and simply wait offstage.
90
+ hidden: mode === 'fullscreen' && window.id !== focused, title: title(window.id), actions: actions?.(window.id), children: _jsx(WindowContent, { id: window.id, render: renderWindow, loading: loading, failed: failed }) }, window.id)))] }));
91
+ }
92
+ // Each window loads and fails on its own: one fetching its code, or throwing, never blanks another.
93
+ const WindowContent = memo(function WindowContent({ id, render, loading, failed }) {
94
+ return (_jsx(WindowBoundary, { id: id, loading: loading, failed: failed, children: render(id) }));
95
+ });
96
+ /** The frame a gesture makes of `origin` after the pointer has travelled dx, dy. */
97
+ function reshape(gesture, origin, dx, dy) {
98
+ switch (gesture) {
99
+ case 'move':
100
+ return { ...origin, x: origin.x + dx, y: Math.max(0, origin.y + dy) };
101
+ case 'resize':
102
+ return { ...origin, width: Math.max(MIN_WIDTH, origin.width + dx), height: Math.max(MIN_HEIGHT, origin.height + dy) };
103
+ case 'right':
104
+ return { ...origin, width: Math.max(MIN_WIDTH, origin.width + dx) };
105
+ case 'bottom':
106
+ return { ...origin, height: Math.max(MIN_HEIGHT, origin.height + dy) };
107
+ case 'left': {
108
+ // The right edge stays put, however far the left one is pulled.
109
+ const shift = Math.min(dx, origin.width - MIN_WIDTH);
110
+ return { ...origin, x: origin.x + shift, width: origin.width - shift };
111
+ }
112
+ }
113
+ }
114
+ function WindowView({ window, layout, hidden, depth, focused, title, actions, children }) {
115
+ const desk = useDesk();
116
+ // While dragging, the frame lives here and commits once on release, so a drag
117
+ // re-renders one window rather than notifying every subscriber per pixel.
118
+ const [live, setLive] = useState(null);
119
+ const element = useRef(null);
120
+ const context = useMemo(() => ({ id: window.id, element }), [window.id]);
121
+ const titleId = `desk-title-${window.id}`;
122
+ const startGesture = (gesture) => (event) => {
123
+ if (event.button !== 0 || layout === 'fullscreen')
124
+ return;
125
+ if (gesture === 'move' && event.target.closest('button'))
126
+ return;
127
+ event.preventDefault();
128
+ const stageBox = event.currentTarget.closest(`[${STAGE_ATTRIBUTE}]`)?.getBoundingClientRect();
129
+ const windowBox = event.currentTarget.closest(`[${WINDOW_ATTRIBUTE}]`)?.getBoundingClientRect();
130
+ // A filled window is freed exactly where it already sits, so it does not jump under the pointer.
131
+ const origin = window.mode === 'floating'
132
+ ? window.frame
133
+ : {
134
+ x: (windowBox?.left ?? 0) - (stageBox?.left ?? 0),
135
+ y: (windowBox?.top ?? 0) - (stageBox?.top ?? 0),
136
+ width: windowBox?.width ?? 480,
137
+ height: windowBox?.height ?? 360,
138
+ };
139
+ let pulledOut = window.mode === 'floating';
140
+ const startX = event.clientX;
141
+ const startY = event.clientY;
142
+ const handle = event.currentTarget;
143
+ handle.setPointerCapture?.(event.pointerId);
144
+ const stage = handle.closest(`[${STAGE_ATTRIBUTE}]`);
145
+ let latest = origin;
146
+ let snap = null;
147
+ // Dragging a window against an edge offers it that half of the desk.
148
+ const snapAt = (clientX) => {
149
+ if (gesture !== 'move' || !stage)
150
+ return null;
151
+ const box = stage.getBoundingClientRect();
152
+ if (clientX - box.left < SNAP_MARGIN)
153
+ return 'start';
154
+ if (box.right - clientX < SNAP_MARGIN)
155
+ return 'end';
156
+ return null;
157
+ };
158
+ const onMove = (move) => {
159
+ const dx = move.clientX - startX;
160
+ const dy = move.clientY - startY;
161
+ if (!pulledOut && Math.hypot(dx, dy) > 5) {
162
+ pulledOut = true;
163
+ if (window.mode === 'filled')
164
+ desk.float(window.id, origin);
165
+ }
166
+ latest = reshape(gesture, origin, dx, dy);
167
+ setLive(latest);
168
+ snap = snapAt(move.clientX);
169
+ if (stage) {
170
+ if (snap)
171
+ stage.dataset.snap = snap;
172
+ else
173
+ delete stage.dataset.snap;
174
+ }
175
+ };
176
+ const onUp = () => {
177
+ handle.removeEventListener('pointermove', onMove);
178
+ handle.removeEventListener('pointerup', onUp);
179
+ handle.removeEventListener('pointercancel', onUp);
180
+ setLive(null);
181
+ if (stage)
182
+ delete stage.dataset.snap;
183
+ // Dropped against an edge, it takes that half of the desk — and nothing else moves.
184
+ if (snap && stage)
185
+ desk.float(window.id, halfFrame(stage, snap));
186
+ else if (pulledOut && latest !== origin)
187
+ desk.float(window.id, latest);
188
+ };
189
+ handle.addEventListener('pointermove', onMove);
190
+ handle.addEventListener('pointerup', onUp);
191
+ handle.addEventListener('pointercancel', onUp);
192
+ };
193
+ // Double-clicking a title bar, or the green control, fills the desk with the window and back — as on a Mac.
194
+ const zoom = () => {
195
+ if (layout === 'desktop')
196
+ desk.toggleMode(window.id);
197
+ };
198
+ const frame = layout === 'desktop' ? (live ?? (window.mode === 'floating' ? window.frame : null)) : null;
199
+ const style = layout !== 'desktop'
200
+ ? undefined
201
+ : frame
202
+ ? { left: frame.x, top: frame.y, width: frame.width, height: frame.height, zIndex: 10 + depth }
203
+ : { zIndex: 10 + depth };
204
+ 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: () => {
205
+ if (!focused)
206
+ desk.focus(window.id);
207
+ }, children: [_jsxs("header", { className: "desk-titlebar", onPointerDown: startGesture('move'), onDoubleClick: event => {
208
+ if (!event.target.closest('button'))
209
+ zoom();
210
+ }, "data-draggable": layout === 'desktop' || undefined, children: [_jsxs("div", { className: "desk-controls", children: [_jsx("button", { type: "button", className: "desk-control", "data-control": "close", "aria-label": "Close", onClick: () => desk.close(window.id) }), layout === 'desktop' && (_jsx("button", { type: "button", className: "desk-control", "data-control": "mode", "aria-label": "Zoom", onClick: zoom }))] }), _jsx("h2", { id: titleId, className: "desk-title", children: title }), actions && _jsx("div", { className: "desk-window-actions", children: actions })] }), _jsx("div", { className: "desk-body", children: children }), layout === 'desktop' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "desk-edge", "data-edge": "left", "aria-hidden": "true", onPointerDown: startGesture('left') }), _jsx("div", { className: "desk-edge", "data-edge": "right", "aria-hidden": "true", onPointerDown: startGesture('right') }), _jsx("div", { className: "desk-edge", "data-edge": "bottom", "aria-hidden": "true", onPointerDown: startGesture('bottom') }), _jsx("div", { className: "desk-grip", "aria-hidden": "true", onPointerDown: startGesture('resize') })] }))] }) }));
211
+ }
212
+ //# sourceMappingURL=Desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Desktop.js","sourceRoot":"","sources":["../../src/react/Desktop.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { WindowId } from '../core/types.js';
3
+ export interface DockItem {
4
+ readonly id: string;
5
+ readonly label: string;
6
+ readonly icon: ReactNode;
7
+ /** The window this item opens and reports as running. Defaults to the item's id. */
8
+ readonly window?: WindowId;
9
+ /** One line under the label inside a stack. */
10
+ readonly description?: string;
11
+ readonly badge?: ReactNode;
12
+ /** Replaces the default of opening the item's window. */
13
+ readonly onSelect?: () => void;
14
+ readonly disabled?: boolean;
15
+ }
16
+ export interface DockStack {
17
+ readonly id: string;
18
+ readonly label: string;
19
+ readonly items: readonly DockItem[];
20
+ /** Defaults to the first four item icons, the way a folder previews its contents. */
21
+ readonly icon?: ReactNode;
22
+ }
23
+ export type DockEntry = ({
24
+ readonly type: 'item';
25
+ } & DockItem) | ({
26
+ readonly type: 'stack';
27
+ } & DockStack) | {
28
+ readonly type: 'separator';
29
+ readonly id: string;
30
+ };
31
+ export declare const dockItem: (item: DockItem) => DockEntry;
32
+ export declare const dockStack: (stack: DockStack) => DockEntry;
33
+ export declare const dockSeparator: (id: string) => DockEntry;
34
+ export interface DockProps {
35
+ readonly entries: readonly DockEntry[];
36
+ readonly label?: string;
37
+ /** `overlay` floats the dock over the bottom of its positioned parent; `inline` leaves layout to you. */
38
+ readonly placement?: 'overlay' | 'inline';
39
+ readonly className?: string;
40
+ }
41
+ export declare function Dock({ entries, label, placement, className }: DockProps): import("react").JSX.Element;
42
+ //# sourceMappingURL=Dock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dock.d.ts","sourceRoot":"","sources":["../../src/react/Dock.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAG3D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;IACnC,qFAAqF;IACrF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAC1B;AAED,MAAM,MAAM,SAAS,GACjB,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,GACtC,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,GACxC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,eAAO,MAAM,QAAQ,SAAU,QAAQ,KAAG,SAAwC,CAAA;AAClF,eAAO,MAAM,SAAS,UAAW,SAAS,KAAG,SAA0C,CAAA;AACvF,eAAO,MAAM,aAAa,OAAQ,MAAM,KAAG,SAAwC,CAAA;AAEnF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAA;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,yGAAyG;IACzG,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAkCD,wBAAgB,IAAI,CAAC,EAAE,OAAO,EAAE,KAAc,EAAE,SAAqB,EAAE,SAAS,EAAE,EAAE,SAAS,+BAgC5F"}
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useId, useRef, useState } from 'react';
3
+ import { focusedId, instancesOf, windowType } from '../core/desk.js';
4
+ import { useDesk, useDeskState } from './context.js';
5
+ export const dockItem = (item) => ({ type: 'item', ...item });
6
+ export const dockStack = (stack) => ({ type: 'stack', ...stack });
7
+ export const dockSeparator = (id) => ({ type: 'separator', id });
8
+ const windowOf = (item) => item.window ?? item.id;
9
+ const statusOf = (state, items) => {
10
+ const key = focusedId(state);
11
+ return {
12
+ // Any window of this kind counts: a second query window is still Query, running.
13
+ running: items.some(i => instancesOf(state, windowOf(i)).length > 0),
14
+ focused: items.some(i => key !== null && windowType(key) === windowOf(i)),
15
+ };
16
+ };
17
+ /** Moves focus among the buttons in a container with arrow keys, Home and End. */
18
+ function roveFocus(event, keys) {
19
+ // Only this container's own buttons: the dock must not rove into an open stack, nor a stack back out.
20
+ const container = event.currentTarget;
21
+ const buttons = [...container.querySelectorAll('[data-rove]:not(:disabled)')].filter(b => b.parentElement?.closest('[role="toolbar"], .desk-stack') === container);
22
+ const index = buttons.indexOf(document.activeElement);
23
+ if (index < 0)
24
+ return;
25
+ const target = keys.next.includes(event.key) ? buttons[(index + 1) % buttons.length]
26
+ : keys.previous.includes(event.key) ? buttons[(index - 1 + buttons.length) % buttons.length]
27
+ : event.key === 'Home' ? buttons[0]
28
+ : event.key === 'End' ? buttons.at(-1)
29
+ : undefined;
30
+ if (!target)
31
+ return;
32
+ event.preventDefault();
33
+ buttons.forEach(b => (b.tabIndex = b === target ? 0 : -1));
34
+ target.focus();
35
+ }
36
+ export function Dock({ entries, label = 'Dock', placement = 'overlay', className }) {
37
+ const [openStack, setOpenStack] = useState(null);
38
+ const firstFocusable = entries.find(e => e.type !== 'separator')?.id;
39
+ return (_jsx("div", { role: "toolbar", "aria-label": label, "aria-orientation": "horizontal", className: ['desk-dock', className].filter(Boolean).join(' '), "data-placement": placement, onKeyDown: event => {
40
+ if (event.target.closest('.desk-stack'))
41
+ return;
42
+ roveFocus(event, { next: ['ArrowRight'], previous: ['ArrowLeft'] });
43
+ }, children: entries.map(entry => {
44
+ if (entry.type === 'separator')
45
+ return _jsx("span", { className: "desk-dock-separator", role: "separator" }, entry.id);
46
+ if (entry.type === 'item')
47
+ return _jsx(DockButton, { item: entry, tabIndex: entry.id === firstFocusable ? 0 : -1 }, entry.id);
48
+ return (_jsx(StackButton, { stack: entry, tabIndex: entry.id === firstFocusable ? 0 : -1, open: openStack === entry.id, setOpenStack: setOpenStack }, entry.id));
49
+ }) }));
50
+ }
51
+ function Badge({ children }) {
52
+ return _jsx("span", { className: "desk-dock-badge", children: children });
53
+ }
54
+ function DockButton({ item, tabIndex }) {
55
+ const desk = useDesk();
56
+ const { running, focused } = statusOf(useDeskState(), [item]);
57
+ return (_jsxs("button", { type: "button", "data-rove": true, tabIndex: tabIndex, className: "desk-dock-item", "aria-label": item.label, "data-running": running || undefined, "data-focused": focused || undefined, disabled: item.disabled, onClick: () => (item.onSelect ? item.onSelect() : desk.open(windowOf(item))), children: [_jsx("span", { className: "desk-dock-icon", "aria-hidden": "true", children: item.icon }), item.badge != null && _jsx(Badge, { children: item.badge }), _jsx("span", { className: "desk-dock-tip", "aria-hidden": "true", children: item.label })] }));
58
+ }
59
+ function StackButton({ stack, tabIndex, open, setOpenStack }) {
60
+ const desk = useDesk();
61
+ const state = useDeskState();
62
+ const { running, focused } = statusOf(state, stack.items);
63
+ const onOpenChange = (next) => setOpenStack(next ? stack.id : null);
64
+ const button = useRef(null);
65
+ const panel = useRef(null);
66
+ const panelId = useId();
67
+ useEffect(() => {
68
+ if (!open)
69
+ return;
70
+ panel.current?.querySelector('[data-rove]:not(:disabled)')?.focus();
71
+ const onPointerDown = (event) => {
72
+ const target = event.target;
73
+ if (!panel.current?.contains(target) && !button.current?.contains(target))
74
+ setOpenStack(null);
75
+ };
76
+ document.addEventListener('pointerdown', onPointerDown);
77
+ return () => document.removeEventListener('pointerdown', onPointerDown);
78
+ }, [open, setOpenStack]);
79
+ const close = () => {
80
+ onOpenChange(false);
81
+ button.current?.focus();
82
+ };
83
+ const select = (item) => {
84
+ if (item.onSelect)
85
+ item.onSelect();
86
+ else
87
+ desk.open(windowOf(item));
88
+ onOpenChange(false);
89
+ };
90
+ const badges = stack.items.filter(i => i.badge != null).length;
91
+ return (_jsxs("span", { className: "desk-dock-slot", children: [_jsxs("button", { ref: button, type: "button", "data-rove": true, tabIndex: tabIndex, className: "desk-dock-item", "data-stack": true, "aria-label": stack.label, "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": open ? panelId : undefined, "data-running": running || undefined, "data-focused": focused || undefined, onClick: () => onOpenChange(!open), children: [_jsx("span", { className: "desk-dock-icon", "aria-hidden": "true", children: stack.icon ?? (_jsx("span", { className: "desk-dock-preview", children: stack.items.slice(0, 4).map(i => (_jsx("span", { children: i.icon }, i.id))) })) }), badges > 0 && _jsx(Badge, { children: badges }), _jsx("span", { className: "desk-dock-tip", "aria-hidden": "true", children: stack.label })] }), open && (_jsxs("div", { ref: panel, id: panelId, role: "dialog", "aria-label": stack.label, className: "desk-stack", onKeyDown: event => {
92
+ if (event.key === 'Escape') {
93
+ event.preventDefault();
94
+ close();
95
+ return;
96
+ }
97
+ roveFocus(event, { next: ['ArrowRight', 'ArrowDown'], previous: ['ArrowLeft', 'ArrowUp'] });
98
+ }, children: [_jsx("p", { className: "desk-stack-title", children: stack.label }), _jsx("div", { className: "desk-stack-grid", children: stack.items.map(item => {
99
+ const status = statusOf(state, [item]);
100
+ return (_jsxs("button", { type: "button", "data-rove": true, className: "desk-stack-item", "data-running": status.running || undefined, disabled: item.disabled, onClick: () => select(item), children: [_jsxs("span", { className: "desk-dock-icon", "aria-hidden": "true", children: [item.icon, item.badge != null && _jsx(Badge, { children: item.badge })] }), _jsx("span", { className: "desk-stack-label", children: item.label }), item.description && _jsx("span", { className: "desk-stack-description", children: item.description })] }, item.id));
101
+ }) })] }))] }));
102
+ }
103
+ //# sourceMappingURL=Dock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dock.js","sourceRoot":"","sources":["../../src/react/Dock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { CommandId } from '../core/commands.js';
3
+ import type { DeskState, WindowId } from '../core/types.js';
4
+ type Flag = boolean | (() => boolean);
5
+ interface ItemCommon {
6
+ readonly label: string;
7
+ /** Shown after the label, muted. */
8
+ readonly detail?: string;
9
+ readonly shortcut?: string;
10
+ readonly checked?: Flag;
11
+ }
12
+ export type MenuItem = ({
13
+ readonly type: 'command';
14
+ readonly command: CommandId;
15
+ readonly args?: unknown;
16
+ } & ItemCommon) | ({
17
+ readonly type: 'action';
18
+ readonly onSelect: () => void;
19
+ readonly disabled?: Flag;
20
+ } & ItemCommon) | {
21
+ readonly type: 'separator';
22
+ } | {
23
+ readonly type: 'header';
24
+ readonly label: string;
25
+ };
26
+ export interface Menu {
27
+ readonly id: string;
28
+ /** The accessible name, and the title when `title` is not given. */
29
+ readonly label: string;
30
+ /** A richer title: an icon, a badge. */
31
+ readonly title?: ReactNode;
32
+ /** The app's own menu: its name, set in bold. Conventionally the first one. */
33
+ readonly emphasis?: boolean;
34
+ /** Items, or a function called each time the menu opens — for lists that change, like open windows. */
35
+ readonly items: readonly MenuItem[] | (() => readonly MenuItem[]);
36
+ }
37
+ type Options<T> = Omit<T, 'type' | 'label'>;
38
+ export declare const menuCommand: (label: string, command: CommandId, options?: Omit<Options<Extract<MenuItem, {
39
+ type: 'command';
40
+ }>>, 'command'>) => MenuItem;
41
+ export declare const menuAction: (label: string, onSelect: () => void, options?: Omit<Options<Extract<MenuItem, {
42
+ type: 'action';
43
+ }>>, 'onSelect'>) => MenuItem;
44
+ export declare const menuSeparator: () => MenuItem;
45
+ export declare const menuHeader: (label: string) => MenuItem;
46
+ /** One item per open window, the key window checked — what a Window menu lists at its foot. */
47
+ export declare function windowMenuItems(state: DeskState, focus: (id: WindowId) => void, title: (id: WindowId) => string): MenuItem[];
48
+ export interface MenuBarProps {
49
+ /** Menus on the leading side, in order. The first is conventionally the app's own. */
50
+ readonly menus: readonly Menu[];
51
+ /** Status menus on the trailing side. */
52
+ readonly status?: readonly Menu[];
53
+ /** Leading content before the menus, e.g. the app's mark. */
54
+ readonly leading?: ReactNode;
55
+ /** Trailing content after the status menus, e.g. a clock. */
56
+ readonly trailing?: ReactNode;
57
+ readonly label?: string;
58
+ /** Bind the shortcuts of command items, in every menu. Default true. */
59
+ readonly shortcuts?: boolean;
60
+ readonly className?: string;
61
+ }
62
+ export declare function MenuBar({ menus, status, leading, trailing, label, shortcuts, className }: MenuBarProps): import("react").JSX.Element;
63
+ export {};
64
+ //# sourceMappingURL=MenuBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MenuBar.d.ts","sourceRoot":"","sources":["../../src/react/MenuBar.tsx"],"names":[],"mappings":"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"}