waybetter 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 +1 -2
- package/bin/waybetter.mjs +2 -5
- package/cli/buildenv.mjs +1 -1
- package/cli/release.mjs +11 -18
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +4 -4
- package/cli/store.mjs +80 -28
- package/cli/strings.mjs +2 -0
- package/dist/runtime/stringPackHook.js +2 -2
- package/dist/runtime/stringPackHook.js.map +1 -1
- package/dist/runtime/stringPackTranslate.d.ts +3 -1
- package/dist/runtime/stringPackTranslate.js +6 -3
- package/dist/runtime/stringPackTranslate.js.map +1 -1
- package/dist/runtime/stringPacks.d.ts +53 -5
- package/dist/runtime/stringPacks.js +161 -25
- package/dist/runtime/stringPacks.js.map +1 -1
- package/dist/runtime/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.js.map +1 -0
- package/dist/runtime/themeComponents.js +16 -3
- package/dist/runtime/themeComponents.js.map +1 -1
- package/dist/runtime/themeDecor.js +3 -1
- package/dist/runtime/themeDecor.js.map +1 -1
- package/dist/runtime/themeDerive.d.ts +69 -0
- package/dist/runtime/themeDerive.js +117 -0
- package/dist/runtime/themeDerive.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +44 -3
- package/dist/runtime/themeDoctor.js +86 -25
- package/dist/runtime/themeDoctor.js.map +1 -1
- package/dist/runtime/themeGuards.d.ts +60 -0
- package/dist/runtime/themeGuards.js +235 -0
- package/dist/runtime/themeGuards.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +1 -1
- package/dist/runtime/themeIcons.js +13 -5
- package/dist/runtime/themeIcons.js.map +1 -1
- package/dist/runtime/themeInk.d.ts +37 -0
- package/dist/runtime/themeInk.js +111 -0
- package/dist/runtime/themeInk.js.map +1 -0
- package/dist/runtime/themeInvariants.d.ts +39 -0
- package/dist/runtime/themeInvariants.js +273 -0
- package/dist/runtime/themeInvariants.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +15 -1
- package/dist/runtime/themeRuntime.js +78 -5
- package/dist/runtime/themeRuntime.js.map +1 -1
- package/dist/runtime/themeSpec.d.ts +5 -1
- package/dist/runtime/themeSpec.js +9 -13
- package/dist/runtime/themeSpec.js.map +1 -1
- package/dist/shell/InstallDialog.js +14 -8
- package/dist/shell/InstallDialog.js.map +1 -1
- package/dist/shell/StoreView.d.ts +12 -0
- package/dist/shell/StoreView.js +9 -4
- package/dist/shell/StoreView.js.map +1 -1
- package/dist/shell/frame/AppMenu.d.ts +26 -3
- package/dist/shell/frame/AppMenu.js +106 -27
- package/dist/shell/frame/AppMenu.js.map +1 -1
- package/dist/shell/frame/FindBar.js +1 -1
- package/dist/shell/frame/FindBar.js.map +1 -1
- package/dist/shell/frame/Shell.d.ts +1 -0
- package/dist/shell/frame/Shell.js +10 -2
- package/dist/shell/frame/Shell.js.map +1 -1
- package/dist/shell/frame/Titlebar.d.ts +2 -1
- package/dist/shell/frame/Titlebar.js +5 -3
- package/dist/shell/frame/Titlebar.js.map +1 -1
- package/dist/shell/frame/WebPanel.js +4 -1
- package/dist/shell/frame/WebPanel.js.map +1 -1
- package/dist/shell/frame/accountSwitcher.css +10 -10
- package/dist/shell/frame/appMenu.css +19 -13
- package/dist/shell/frame/boot.js +2 -0
- package/dist/shell/frame/boot.js.map +1 -1
- package/dist/shell/frame/chromeTheme.d.ts +19 -1
- package/dist/shell/frame/chromeTheme.js +51 -14
- package/dist/shell/frame/chromeTheme.js.map +1 -1
- package/dist/shell/frame/deck.css +30 -30
- package/dist/shell/frame/edges.css +159 -0
- package/dist/shell/frame/index.d.ts +2 -2
- package/dist/shell/frame/index.js +1 -1
- package/dist/shell/frame/index.js.map +1 -1
- package/dist/shell/frame/mediaModel.d.ts +13 -0
- package/dist/shell/frame/mediaModel.js +14 -0
- package/dist/shell/frame/mediaModel.js.map +1 -1
- package/dist/shell/frame/menuMessages.en.json +43 -1
- package/dist/shell/frame/menuModel.d.ts +42 -0
- package/dist/shell/frame/menuModel.js +8 -0
- package/dist/shell/frame/menuModel.js.map +1 -1
- package/dist/shell/frame/nativeMenu.d.ts +5 -0
- package/dist/shell/frame/nativeMenu.js +178 -0
- package/dist/shell/frame/nativeMenu.js.map +1 -0
- package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
- package/dist/shell/frame/nativeMenuModel.js +186 -0
- package/dist/shell/frame/nativeMenuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.js +3 -1
- package/dist/shell/frame/paletteModel.js.map +1 -1
- package/dist/shell/frame/paneTheme.css +1 -1
- package/dist/shell/frame/reportModel.d.ts +1 -1
- package/dist/shell/frame/reportModel.js +1 -1
- package/dist/shell/frame/reportModel.js.map +1 -1
- package/dist/shell/frame/shell.css +56 -51
- package/dist/shell/frame/state.d.ts +2 -0
- package/dist/shell/frame/state.js +3 -1
- package/dist/shell/frame/state.js.map +1 -1
- package/dist/shell/frame/themeStore.js +21 -6
- package/dist/shell/frame/themeStore.js.map +1 -1
- package/dist/shell/frame/workspaces.css +12 -12
- package/dist/shell/installController.d.ts +16 -1
- package/dist/shell/installController.js +31 -5
- package/dist/shell/installController.js.map +1 -1
- package/dist/shell/panel/Appearance.js +12 -3
- package/dist/shell/panel/Appearance.js.map +1 -1
- package/dist/shell/panel/Settings.d.ts +1 -1
- package/dist/shell/panel/Settings.js +4 -3
- package/dist/shell/panel/Settings.js.map +1 -1
- package/dist/shell/panel/StoreSection.d.ts +2 -1
- package/dist/shell/panel/StoreSection.js +31 -1
- package/dist/shell/panel/StoreSection.js.map +1 -1
- package/dist/shell/panel/StringPacks.d.ts +12 -3
- package/dist/shell/panel/StringPacks.js +33 -8
- package/dist/shell/panel/StringPacks.js.map +1 -1
- package/dist/shell/panel/backup.css +1 -1
- package/dist/shell/panel/builder.css +48 -40
- package/dist/shell/panel/make.css +8 -7
- package/dist/shell/panel/panel.css +401 -401
- package/dist/shell/panel/panelMessages.d.ts +41 -1
- package/dist/shell/panel/panelMessages.js +13 -1
- package/dist/shell/panel/panelMessages.js.map +1 -1
- package/dist/shell/panel/plugins.css +5 -5
- package/dist/shell/panel/strings.css +1 -1
- package/dist/shell/store.css +34 -14
- package/dist/shell/storeMessages.d.ts +24 -0
- package/dist/shell/storeMessages.js +24 -0
- package/dist/shell/storeMessages.js.map +1 -1
- package/dist/shell/storeModel.d.ts +31 -7
- package/dist/shell/storeModel.js +15 -2
- package/dist/shell/storeModel.js.map +1 -1
- package/dist/shell/stringPacksModel.js +7 -2
- package/dist/shell/stringPacksModel.js.map +1 -1
- package/icons.schema.json +9 -0
- package/locales/ar.json +109 -2
- package/locales/bg.json +109 -2
- package/locales/bn.json +109 -2
- package/locales/ca.json +109 -2
- package/locales/cs.json +109 -2
- package/locales/da.json +109 -2
- package/locales/de.json +109 -2
- package/locales/el.json +109 -2
- package/locales/en.json +108 -2
- package/locales/es.json +109 -2
- package/locales/eu.json +109 -2
- package/locales/fa.json +109 -2
- package/locales/fi.json +109 -2
- package/locales/fil.json +109 -2
- package/locales/fr.json +109 -2
- package/locales/ga.json +109 -2
- package/locales/gl.json +109 -2
- package/locales/gu.json +109 -2
- package/locales/ha.json +109 -2
- package/locales/he.json +109 -2
- package/locales/hi.json +109 -2
- package/locales/hr.json +109 -2
- package/locales/hu.json +110 -2
- package/locales/id.json +109 -2
- package/locales/ig.json +109 -2
- package/locales/it.json +109 -2
- package/locales/ja.json +109 -2
- package/locales/kn.json +109 -2
- package/locales/ko.json +109 -2
- package/locales/mr.json +109 -2
- package/locales/ms.json +109 -2
- package/locales/nb.json +109 -2
- package/locales/nl.json +109 -2
- package/locales/pl.json +109 -2
- package/locales/pt.json +109 -2
- package/locales/ro.json +109 -2
- package/locales/ru.json +109 -2
- package/locales/sk.json +109 -2
- package/locales/sr.json +109 -2
- package/locales/sv.json +109 -2
- package/locales/ta.json +109 -2
- package/locales/th.json +109 -2
- package/locales/tr.json +109 -2
- package/locales/uk.json +109 -2
- package/locales/ur.json +109 -2
- package/locales/vi.json +109 -2
- package/locales/yo.json +109 -2
- package/locales/zh-Hans.json +109 -2
- package/locales/zh-Hant.json +109 -2
- package/package.json +2 -3
- package/store-catalog.schema.json +18 -5
- package/theme.schema.json +9 -0
- package/windows/installer.nsi +22 -2
- package/cli/privacy.mjs +0 -768
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
// The app menu
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
2
|
+
// The app menu ("Settings and more"). Its trigger is the app's choice (`ShellMenu.trigger`): by
|
|
3
|
+
// default each pane's wayBetter button at the end of its toolbar (`PaneMenuButton`; the menu hangs
|
|
4
|
+
// under the button that was clicked, so in split view each pane opens it under itself), else a
|
|
5
|
+
// button at the end of the titlebar or the titlebar's logo. It also opens on Alt+F and F10
|
|
6
|
+
// (Shell.tsx; a focused tab forwards the keys), from the command palette and from the last row of
|
|
7
|
+
// the account menu: under the focused pane's button (the first one on screen when no pane is
|
|
8
|
+
// focused). Its rows are the app's (`ShellSite.menu`, menuModel.ts): built-in ones by name, each
|
|
9
|
+
// shown only when the app serves what it needs, and the app's own.
|
|
8
10
|
//
|
|
9
11
|
// Like every shell menu it is an overlay: while open the shell is raised above the tab webviews
|
|
10
12
|
// (`setOverlay`), panes stay visible and nothing is dimmed. Keyboard: arrows, Home/End, type-ahead,
|
|
@@ -21,7 +23,7 @@ import { refreshDev } from "./devHost.js";
|
|
|
21
23
|
import { useDev, usePaneTick, useT } from "./hooks.js";
|
|
22
24
|
import { formatNumber } from "./i18n.js";
|
|
23
25
|
import { Icon } from "./icons.js";
|
|
24
|
-
import { DEFAULT_MENU, ZOOM_MAX, ZOOM_MIN, findSpec, joinGroups, languageChoice, languageRows, menuText, moveStop, planMenu, shortcutText, specRows, submenuKeys, submenuLeft, typeahead, updateRow, } from "./menuModel.js";
|
|
26
|
+
import { DEFAULT_MENU, ZOOM_MAX, ZOOM_MIN, findSpec, joinGroups, languageChoice, languageRows, menuText, moveStop, planMenu, resolveTrigger, shortcutText, specRows, submenuKeys, submenuLeft, typeahead, updateRow, } from "./menuModel.js";
|
|
25
27
|
import { ReportDialog } from "./ReportDialog.js";
|
|
26
28
|
import { safe, setSafeMode } from "./safeStore.js";
|
|
27
29
|
import { hasFeature, site } from "./site.js";
|
|
@@ -33,19 +35,40 @@ import { readZoom, stepZoom, zoomOf, zoomTarget } from "./zoomStore.js";
|
|
|
33
35
|
import './appMenu.css';
|
|
34
36
|
/** Opens the app menu (Alt+F / F10, the palette, the account menu's last row). */
|
|
35
37
|
export const openAppMenu = (request = {}) => window.dispatchEvent(new CustomEvent('bt-app-menu', { detail: request }));
|
|
38
|
+
/** Opens the "Report a problem" summary (the native menu bar's Help item). */
|
|
39
|
+
export const openReport = () => window.dispatchEvent(new CustomEvent('bt-report'));
|
|
36
40
|
const mac = os === 'macos';
|
|
37
41
|
/** The keys that open the menu, as the button's tooltip and the account menu write them. */
|
|
38
42
|
export const APP_MENU_KEYS = mac ? 'F10' : 'Alt+F';
|
|
39
43
|
const getError = (error) => (error instanceof Error ? error.message : String(error)).replace(/^Error: /, '');
|
|
40
44
|
const percent = (factor) => formatNumber(factor, { style: 'percent', maximumFractionDigits: 0 });
|
|
45
|
+
/** One trigger, as a key: `pane:<id>` for a pane's button. */
|
|
46
|
+
const triggerKey = (at, pane) => (at === 'pane' ? `pane:${pane ?? ''}` : at);
|
|
41
47
|
/** Which trigger the open menu hangs from (null: closed), for the triggers' `aria-expanded`. */
|
|
42
48
|
let openAt = null;
|
|
43
|
-
function noteOpen(
|
|
44
|
-
if (openAt ===
|
|
49
|
+
function noteOpen(key) {
|
|
50
|
+
if (openAt === key)
|
|
45
51
|
return;
|
|
46
|
-
openAt =
|
|
52
|
+
openAt = key;
|
|
47
53
|
window.dispatchEvent(new CustomEvent('bt-app-menu-state'));
|
|
48
54
|
}
|
|
55
|
+
/** `aria-expanded` of one trigger. */
|
|
56
|
+
function useExpanded(key) {
|
|
57
|
+
const [expanded, setExpanded] = useState(openAt === key);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const update = () => setExpanded(openAt === key);
|
|
60
|
+
update();
|
|
61
|
+
window.addEventListener('bt-app-menu-state', update);
|
|
62
|
+
return () => window.removeEventListener('bt-app-menu-state', update);
|
|
63
|
+
}, [key]);
|
|
64
|
+
return expanded;
|
|
65
|
+
}
|
|
66
|
+
/** Pane `id`'s menu button on screen; else the focused pane's; else the first one on screen. */
|
|
67
|
+
function paneButton(id) {
|
|
68
|
+
const shown = Array.from(document.querySelectorAll('.bt-pane-menu[data-pane]')).filter(el => el.getClientRects().length > 0);
|
|
69
|
+
const find = (want) => (want ? shown.find(el => el.dataset.pane === want) : undefined);
|
|
70
|
+
return find(id) ?? find(shell.api?.activePanel?.id) ?? shown[0] ?? null;
|
|
71
|
+
}
|
|
49
72
|
/** The rows of one level a key can stop on: enabled items; the zoom row counts once. */
|
|
50
73
|
function stopsOf(menu) {
|
|
51
74
|
const all = Array.from(menu.querySelectorAll('[data-item]:not(:disabled)'));
|
|
@@ -54,7 +77,11 @@ function stopsOf(menu) {
|
|
|
54
77
|
const keep = zoom.find(el => el === active) ?? zoom.find(el => el.getAttribute('aria-disabled') !== 'true') ?? zoom[0];
|
|
55
78
|
return all.filter(el => !('zoom' in el.dataset) || el === keep);
|
|
56
79
|
}
|
|
57
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The menu (mounted once, in the titlebar). `trigger`: where clicks and keys open it; default the
|
|
82
|
+
* app's `ShellMenu.trigger`, else `pane`. `true` / `false` are the older spellings of `button` / `logo`.
|
|
83
|
+
*/
|
|
84
|
+
export function AppMenu({ trigger } = {}) {
|
|
58
85
|
const t = useT();
|
|
59
86
|
usePaneTick();
|
|
60
87
|
const dev = useDev();
|
|
@@ -93,16 +120,36 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
93
120
|
dispose?.();
|
|
94
121
|
};
|
|
95
122
|
}, []);
|
|
96
|
-
/** Where a request without an anchor opens: the
|
|
97
|
-
const home = () => (trigger
|
|
123
|
+
/** Where a request without an anchor opens: the app's trigger. */
|
|
124
|
+
const home = () => menuTrigger(trigger);
|
|
125
|
+
/** The element a request hangs the menu under (null: none on screen). */
|
|
126
|
+
function triggerOf(at, pane) {
|
|
127
|
+
if (at === 'pane')
|
|
128
|
+
return paneButton(pane);
|
|
129
|
+
if (at === 'logo')
|
|
130
|
+
return document.querySelector('button.bt-titlebar-logo');
|
|
131
|
+
return button.current;
|
|
132
|
+
}
|
|
98
133
|
function show(request = {}) {
|
|
99
134
|
const at = request.anchor ?? home();
|
|
135
|
+
const el = triggerOf(at, request.pane);
|
|
136
|
+
const pane = at === 'pane' ? el?.dataset.pane : undefined;
|
|
100
137
|
diag(`menu open: anchor=${at} keyboard=${!!request.keyboard} hasFocus=${document.hasFocus()} active=${describe(document.activeElement)}`);
|
|
101
|
-
const
|
|
102
|
-
const rect = (logo ?? button.current)?.getBoundingClientRect();
|
|
138
|
+
const rect = el?.getBoundingClientRect();
|
|
103
139
|
if (rect) {
|
|
104
140
|
const top = Math.round(rect.bottom + 6);
|
|
105
|
-
|
|
141
|
+
const rtl = getComputedStyle(el).direction === 'rtl';
|
|
142
|
+
if (at === 'logo')
|
|
143
|
+
setAnchor({ at, top, left: Math.max(8, Math.round(rect.left - 3)) });
|
|
144
|
+
// The menu's end edge lines up with its button's, so it opens over the pane the button is in.
|
|
145
|
+
else if (rtl)
|
|
146
|
+
setAnchor({ at, pane, top, left: Math.max(8, Math.round(rect.left)) });
|
|
147
|
+
else
|
|
148
|
+
setAnchor({ at, pane, top, right: Math.max(8, Math.round(window.innerWidth - rect.right)) });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// No trigger on screen (only the app's own tab, a deck): under the titlebar, at its end.
|
|
152
|
+
setAnchor({ at, pane, top: 50, right: 8 });
|
|
106
153
|
}
|
|
107
154
|
const active = document.activeElement;
|
|
108
155
|
before.current = active && active !== document.body && document.hasFocus() ? active : null;
|
|
@@ -161,8 +208,10 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
161
208
|
useEffect(() => {
|
|
162
209
|
const onRequest = (event) => {
|
|
163
210
|
const request = event.detail ?? {};
|
|
164
|
-
// Asked again from
|
|
165
|
-
|
|
211
|
+
// Asked again from another trigger, the open menu moves there instead of closing.
|
|
212
|
+
const at = request.anchor ?? home();
|
|
213
|
+
const key = triggerKey(at, at === 'pane' ? request.pane ?? paneButton()?.dataset.pane : undefined);
|
|
214
|
+
if (live.current.open && request.toggle && key === openAt)
|
|
166
215
|
close('escape');
|
|
167
216
|
else
|
|
168
217
|
show(request);
|
|
@@ -170,12 +219,16 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
170
219
|
window.addEventListener('bt-app-menu', onRequest);
|
|
171
220
|
return () => window.removeEventListener('bt-app-menu', onRequest);
|
|
172
221
|
}, [version]);
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
const show = () => setReporting(true);
|
|
224
|
+
window.addEventListener('bt-report', show);
|
|
225
|
+
return () => window.removeEventListener('bt-report', show);
|
|
226
|
+
}, []);
|
|
173
227
|
useEffect(() => {
|
|
174
228
|
if (!open)
|
|
175
229
|
return;
|
|
176
230
|
// Native tab webviews would cover the menu.
|
|
177
231
|
setOverlay(1);
|
|
178
|
-
noteOpen(anchor.at);
|
|
179
232
|
// The window lost the keyboard: the menu closes, unless the focus is back a moment later (taking the
|
|
180
233
|
// keyboard from a tab for Alt+F / F10 can pass through a blur on its way to the shell).
|
|
181
234
|
let leaving;
|
|
@@ -206,13 +259,31 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
206
259
|
window.addEventListener('blur', away);
|
|
207
260
|
window.addEventListener('resize', resized);
|
|
208
261
|
window.addEventListener('keydown', onKey);
|
|
209
|
-
return () => { clearTimeout(leaving); setOverlay(-1);
|
|
262
|
+
return () => { clearTimeout(leaving); setOverlay(-1); window.removeEventListener('blur', away); window.removeEventListener('resize', resized); window.removeEventListener('keydown', onKey); };
|
|
210
263
|
}, [open, anchor.at]);
|
|
264
|
+
// The trigger the menu hangs from shows it is open.
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
noteOpen(open ? triggerKey(anchor.at, anchor.pane) : null);
|
|
267
|
+
return () => noteOpen(null);
|
|
268
|
+
}, [open, anchor.at, anchor.pane]);
|
|
211
269
|
const layer = (level) => layers.current?.querySelector(`[data-level="${level}"]`) ?? null;
|
|
212
270
|
// After every render: submenus sit beside their row, inside the window; then the focus that was asked for.
|
|
213
271
|
useLayoutEffect(() => {
|
|
214
272
|
if (!open)
|
|
215
273
|
return;
|
|
274
|
+
// The menu stays inside the window: a button near the start edge (a narrow pane in split view)
|
|
275
|
+
// would push it out, so it slides back in.
|
|
276
|
+
const root = layer(0);
|
|
277
|
+
if (root) {
|
|
278
|
+
const edge = 8;
|
|
279
|
+
root.style.left = anchor.left === undefined ? '' : `${anchor.left}px`;
|
|
280
|
+
root.style.right = anchor.right === undefined ? '' : `${anchor.right}px`;
|
|
281
|
+
const box = root.getBoundingClientRect();
|
|
282
|
+
if (box.left < edge || box.right > window.innerWidth - edge) {
|
|
283
|
+
root.style.left = `${Math.round(Math.max(edge, Math.min(box.left, window.innerWidth - edge - box.width)))}px`;
|
|
284
|
+
root.style.right = 'auto';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
216
287
|
for (let level = 1; level <= path.length; level += 1) {
|
|
217
288
|
const el = layer(level);
|
|
218
289
|
const parent = layer(level - 1);
|
|
@@ -599,7 +670,7 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
599
670
|
return levels.map(({ rows, label }, level) => _jsx("div", { role: "menu", "aria-label": label, tabIndex: -1, "data-level": level, className: level === 0 ? `bt-menu bt-app-menu bt-pop${anchor.at === 'logo' ? '' : ' bt-pop--right'}` : 'bt-menu bt-app-menu bt-app-sub', style: level === 0 ? { top: anchor.top, left: anchor.left, right: anchor.right, maxHeight: `calc(100vh - ${anchor.top + 8}px)` } : undefined, children: rows.map((row, index) => renderRow(row, level, index)) }, level === 0 ? 'root' : `${level}:${path[level - 1]}`));
|
|
600
671
|
}
|
|
601
672
|
const label = menuText('label');
|
|
602
|
-
return _jsxs(_Fragment, { children: [
|
|
673
|
+
return _jsxs(_Fragment, { children: [home() === 'button' && _jsx("button", { ref: button, type: "button", className: "bt-app-button", "aria-haspopup": "menu", "aria-expanded": open && anchor.at === 'button', "aria-label": label, title: `${label} (${APP_MENU_KEYS})`, onClick: event => (open && anchor.at === 'button' ? close('escape') : show({ keyboard: event.detail === 0 })), children: _jsxs("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("circle", { cx: "12", cy: "5.75", r: "1.6" }), _jsx("circle", { cx: "12", cy: "12", r: "1.6" }), _jsx("circle", { cx: "12", cy: "18.25", r: "1.6" })] }) }), open && createPortal(_jsx("div", { className: "bt-menu-backdrop", onMouseDown: () => close(), onContextMenu: event => { event.preventDefault(); close(); }, children: _jsx("div", { ref: layers, className: "bt-app-layers", onMouseDown: event => event.stopPropagation(), onContextMenu: event => { event.preventDefault(); event.stopPropagation(); }, onKeyDown: onKey, children: renderMenus() }) }), document.body), reporting && _jsx(ReportDialog, { onClose: () => setReporting(false) })] });
|
|
603
674
|
}
|
|
604
675
|
/**
|
|
605
676
|
* The app's logo at the start of the titlebar: a second trigger of the same menu, hung under the
|
|
@@ -608,13 +679,8 @@ export function AppMenu({ trigger = true } = {}) {
|
|
|
608
679
|
*/
|
|
609
680
|
export function AppMenuLogo() {
|
|
610
681
|
useT();
|
|
611
|
-
const
|
|
682
|
+
const expanded = useExpanded('logo');
|
|
612
683
|
const press = useRef(null);
|
|
613
|
-
useEffect(() => {
|
|
614
|
-
const update = () => setExpanded(openAt === 'logo');
|
|
615
|
-
window.addEventListener('bt-app-menu-state', update);
|
|
616
|
-
return () => window.removeEventListener('bt-app-menu-state', update);
|
|
617
|
-
}, []);
|
|
618
684
|
const { product, logo } = site();
|
|
619
685
|
const label = menuText('label');
|
|
620
686
|
return _jsx("button", { type: "button", className: "bt-titlebar-logo", "aria-haspopup": "menu", "aria-expanded": expanded, "aria-label": `${product}: ${label}`, title: `${product} · ${label}`, onPointerDown: event => { if (event.button === 0)
|
|
@@ -639,4 +705,17 @@ export function AppMenuLogo() {
|
|
|
639
705
|
systemMenu(Math.round(event.screenX * scale), Math.round(event.screenY * scale));
|
|
640
706
|
}, children: _jsx("img", { src: logo, alt: "", draggable: false }) });
|
|
641
707
|
}
|
|
708
|
+
/** The app's menu trigger: `trigger` as `AppMenu` takes it, else `ShellMenu.trigger`, else `pane`. */
|
|
709
|
+
export const menuTrigger = (trigger) => resolveTrigger(trigger, site().menu?.trigger);
|
|
710
|
+
/**
|
|
711
|
+
* One pane's menu button, at the end of its toolbar (the app's mark inside): opens the app menu
|
|
712
|
+
* under itself, or closes it when it is open there. Shown when the app's trigger is `pane`.
|
|
713
|
+
*/
|
|
714
|
+
export function PaneMenuButton({ pane, children }) {
|
|
715
|
+
useT();
|
|
716
|
+
const expanded = useExpanded(triggerKey('pane', pane));
|
|
717
|
+
const label = menuText('label');
|
|
718
|
+
const { product } = site();
|
|
719
|
+
return _jsx("button", { type: "button", className: "bt-brand-button bt-pane-menu", "data-pane": pane, "aria-haspopup": "menu", "aria-expanded": expanded, "aria-label": `${product}: ${label}`, title: `${product} · ${label} (${APP_MENU_KEYS})`, onClick: event => openAppMenu({ anchor: 'pane', pane, toggle: true, keyboard: event.detail === 0 }), children: children });
|
|
720
|
+
}
|
|
642
721
|
//# sourceMappingURL=AppMenu.js.map
|