@graview/primitives 0.1.65 → 0.1.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-bar.d.ts +114 -15
- package/dist/app-bar.d.ts.map +1 -1
- package/dist/app-bar.js +192 -130
- package/dist/app-bar.js.map +1 -1
- package/dist/app-menu.d.ts +9 -0
- package/dist/app-menu.d.ts.map +1 -0
- package/dist/app-menu.js +60 -0
- package/dist/app-menu.js.map +1 -0
- package/dist/bar-activity.d.ts +5 -9
- package/dist/bar-activity.d.ts.map +1 -1
- package/dist/bar-activity.js +24 -7
- package/dist/bar-activity.js.map +1 -1
- package/dist/bar-panes.d.ts +5 -5
- package/dist/bar-panes.d.ts.map +1 -1
- package/dist/bar-panes.js +9 -5
- package/dist/bar-panes.js.map +1 -1
- package/dist/bar-suggested.d.ts +9 -1
- package/dist/bar-suggested.d.ts.map +1 -1
- package/dist/bar-suggested.js +11 -17
- package/dist/bar-suggested.js.map +1 -1
- package/dist/better-bar.d.ts +77 -0
- package/dist/better-bar.d.ts.map +1 -0
- package/dist/better-bar.js +312 -0
- package/dist/better-bar.js.map +1 -0
- package/dist/better-panel.d.ts +55 -0
- package/dist/better-panel.d.ts.map +1 -0
- package/dist/better-panel.js +151 -0
- package/dist/better-panel.js.map +1 -0
- package/dist/editable.d.ts +8 -1
- package/dist/editable.d.ts.map +1 -1
- package/dist/editable.js +140 -16
- package/dist/editable.js.map +1 -1
- package/dist/first-look-door.d.ts +2 -2
- package/dist/first-look-door.js +2 -2
- package/dist/first-look.d.ts.map +1 -1
- package/dist/first-look.js +9 -7
- package/dist/first-look.js.map +1 -1
- package/dist/frame.d.ts +2 -2
- package/dist/frame.d.ts.map +1 -1
- package/dist/frame.js +1 -1
- package/dist/frame.js.map +1 -1
- package/dist/inbox-pane.d.ts +31 -0
- package/dist/inbox-pane.d.ts.map +1 -0
- package/dist/inbox-pane.js +89 -0
- package/dist/inbox-pane.js.map +1 -0
- package/dist/inbox.d.ts +17 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +84 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lens/calendar-drawing.js +7 -3
- package/dist/lens/calendar-drawing.js.map +1 -1
- package/dist/menu-suggested.d.ts +54 -0
- package/dist/menu-suggested.d.ts.map +1 -0
- package/dist/menu-suggested.js +140 -0
- package/dist/menu-suggested.js.map +1 -0
- package/dist/menu-told-door.js +1 -1
- package/dist/menu-told-door.js.map +1 -1
- package/dist/menu-told.d.ts +7 -0
- package/dist/menu-told.d.ts.map +1 -1
- package/dist/menu-told.js +24 -0
- package/dist/menu-told.js.map +1 -1
- package/dist/notify-sheet.js +2 -2
- package/dist/notify-sheet.js.map +1 -1
- package/dist/page-better.d.ts +27 -0
- package/dist/page-better.d.ts.map +1 -0
- package/dist/page-better.js +747 -0
- package/dist/page-better.js.map +1 -0
- package/dist/page-parts.d.ts +41 -0
- package/dist/page-parts.d.ts.map +1 -0
- package/dist/page-parts.js +101 -0
- package/dist/page-parts.js.map +1 -0
- package/dist/pages.d.ts +2 -3
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +2 -3
- package/dist/pages.js.map +1 -1
- package/dist/profile.d.ts +1 -10
- package/dist/profile.d.ts.map +1 -1
- package/dist/profile.js +2 -3
- package/dist/profile.js.map +1 -1
- package/dist/scene-bar.d.ts +1 -1
- package/dist/scene-bar.d.ts.map +1 -1
- package/dist/scene-bar.js +4 -7
- package/dist/scene-bar.js.map +1 -1
- package/dist/section-better.d.ts +66 -9
- package/dist/section-better.d.ts.map +1 -1
- package/dist/section-better.js +285 -136
- package/dist/section-better.js.map +1 -1
- package/dist/section-door.d.ts +7 -0
- package/dist/section-door.d.ts.map +1 -1
- package/dist/section-door.js +39 -5
- package/dist/section-door.js.map +1 -1
- package/dist/section-menu.d.ts +23 -9
- package/dist/section-menu.d.ts.map +1 -1
- package/dist/section-menu.js +176 -23
- package/dist/section-menu.js.map +1 -1
- package/dist/section-words.d.ts +8 -0
- package/dist/section-words.d.ts.map +1 -1
- package/dist/section-words.js +25 -0
- package/dist/section-words.js.map +1 -1
- package/dist/shell.d.ts +7 -1
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +4 -2
- package/dist/shell.js.map +1 -1
- package/dist/suggested.d.ts +21 -10
- package/dist/suggested.d.ts.map +1 -1
- package/dist/suggested.js +80 -66
- package/dist/suggested.js.map +1 -1
- package/dist/suggestion-sentence.d.ts +50 -0
- package/dist/suggestion-sentence.d.ts.map +1 -0
- package/dist/suggestion-sentence.js +119 -0
- package/dist/suggestion-sentence.js.map +1 -0
- package/dist/told-card.js +1 -1
- package/dist/told-card.js.map +1 -1
- package/dist/told-ui.d.ts +1 -1
- package/dist/told-ui.d.ts.map +1 -1
- package/dist/told-ui.js +1 -1
- package/dist/told-ui.js.map +1 -1
- package/dist/when-words.d.ts +21 -0
- package/dist/when-words.d.ts.map +1 -0
- package/dist/when-words.js +43 -0
- package/dist/when-words.js.map +1 -0
- package/dist/workbench/activity.d.ts +44 -0
- package/dist/workbench/activity.d.ts.map +1 -1
- package/dist/workbench/activity.js +74 -59
- package/dist/workbench/activity.js.map +1 -1
- package/dist/workbench/inspector.d.ts.map +1 -1
- package/dist/workbench/inspector.js +170 -31
- package/dist/workbench/inspector.js.map +1 -1
- package/dist/workbench/standing.d.ts.map +1 -1
- package/dist/workbench/standing.js +1 -1
- package/dist/workbench/standing.js.map +1 -1
- package/package.json +6 -6
package/dist/app-bar.js
CHANGED
|
@@ -2,12 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { allLabel, arrangedEntries, hueFor, isInlineSvg, kindPath, MOST_STANDING, offeredPlaces, onePerPicture, OVERVIEW_SLUG, placeLabel, placePath, pluralLabel, primaryOf, samePicture, sharesItsName, supportingKinds } from "@graview/core";
|
|
3
3
|
import { POPOVER_STYLE, useGraviewIfAny, usePopover } from "@graview/react/provider";
|
|
4
4
|
import { useQuickAskDrawn } from "./quick-ask-desk.js";
|
|
5
|
-
import { createContext, Suspense, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
5
|
+
import { createContext, Suspense, useCallback, useContext, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
6
6
|
import { AppMark } from "./app-title.js";
|
|
7
7
|
import { useMarkup } from "./markup.js";
|
|
8
8
|
import { barPanes } from "./bar-panes-door.js";
|
|
9
9
|
/* The places' foot, Hidden and Recently deleted (Roadmap f-place-menu-views): fetched with the panes, and the tidying with it, once there is something to list and the list is open. */
|
|
10
10
|
const TidyFoot = barPanes.part((panes, props) => _jsx(panes.TidyFoot, { ...props }), { quiet: true });
|
|
11
|
+
/* The app menu's rows (Roadmap f-app-bar-calm): fetched with the panes when it is first reached for. */
|
|
12
|
+
const AppMenuRows = barPanes.part((panes, props) => _jsx(panes.AppMenuPane, { ...props }), { what: "The app menu" });
|
|
11
13
|
/* Who else is here (FR-155): drawn once somebody is, so a reader alone never fetches it. */
|
|
12
14
|
const Here = barPanes.part((panes, props) => _jsx(panes.Here, { ...props }), { quiet: true });
|
|
13
15
|
/**
|
|
@@ -134,8 +136,10 @@ export const useBarFind = () => useContext(BarFindContext);
|
|
|
134
136
|
export const TOOL = 30;
|
|
135
137
|
/** The bar's one row, its rule under it included, on a desk and a phone alike (FR-138). */
|
|
136
138
|
export const BAR_HEIGHT = 48;
|
|
137
|
-
/** Below this width of its own the bar is a phone's: the place is the page's first line
|
|
139
|
+
/** Below this width of its own the bar is a phone's: the place is the page's first line. */
|
|
138
140
|
export const BAR_PHONE = 640;
|
|
141
|
+
/** Below this width of its own Find is the magnifier, which opens the box over the row (Roadmap f-app-bar-calm): sooner than a phone's. */
|
|
142
|
+
export const BAR_FIND_FOLDS = 900;
|
|
139
143
|
/** The room between two places standing on the row (FR-145). */
|
|
140
144
|
export const PLACE_GAP = 4;
|
|
141
145
|
/** The fewest places that stand on the row: fewer, and the one control says the same in less room. */
|
|
@@ -180,17 +184,15 @@ export function placesThatStand(input) {
|
|
|
180
184
|
* short, Find gives first (a small box that says its shortcut, drawn wide
|
|
181
185
|
* while it is used), then the place down to 9em of its name (whole in its
|
|
182
186
|
* title), then the app's name, which wraps between its words onto a second
|
|
183
|
-
* line and never inside one; the
|
|
184
|
-
*
|
|
185
|
-
* and the words fit is weighed with the name as it would stand on one line
|
|
187
|
+
* line and never inside one; the app menu's chevron keeps its size. Whether
|
|
188
|
+
* the places stand is weighed with the name as it would stand on one line
|
|
186
189
|
* (`nameGiven`), never as it is drawn now: the name drawn on two lines because
|
|
187
190
|
* the places stood would fold them, and the name back on one would stand
|
|
188
191
|
* them again, frame after frame.
|
|
189
192
|
*
|
|
190
193
|
* Where the places stand on the row (FR-145), Find gives first — down to
|
|
191
194
|
* its least — then the places fold into "More", then into the one control,
|
|
192
|
-
* which gives as above.
|
|
193
|
-
* kept: the words are worth more than a third place on the row.
|
|
195
|
+
* which gives as above.
|
|
194
196
|
*
|
|
195
197
|
* The order is the shrink factors: Find 600, the place 100, the app 1. A
|
|
196
198
|
* factor under 1 would not do — the free space is scaled by the factors
|
|
@@ -204,23 +206,34 @@ export function placesThatStand(input) {
|
|
|
204
206
|
const BAR_CSS = `
|
|
205
207
|
.graview-bar{display:block;margin:0;padding:0;container:graview-bar/inline-size;flex:0 0 auto;position:relative;background:var(--graview-bar);border-bottom:1px solid var(--graview-edge);color:var(--graview-ink);font-family:var(--graview-font-body,system-ui)}
|
|
206
208
|
.graview-bar-row{display:flex;flex-wrap:nowrap;align-items:center;gap:16px;height:${BAR_HEIGHT - 1}px;margin:0;padding:0 16px}
|
|
207
|
-
.graview-bar-home,.graview-bar-
|
|
208
|
-
.graview-bar-app{display:flex;flex:0 1 auto;max-width:50%}
|
|
209
|
+
.graview-bar-home,.graview-bar-place,.graview-bar-item,.graview-bar-at{display:inline-flex;align-items:center;box-sizing:border-box;min-width:0;margin:0;border:0;background:none;box-shadow:none;font:inherit;letter-spacing:normal;text-transform:none;text-decoration:none;color:var(--graview-ink);cursor:pointer;text-align:left}
|
|
210
|
+
.graview-bar-app{display:flex;align-items:center;gap:2px;flex:0 1 auto;max-width:50%}
|
|
209
211
|
.graview-bar-app::after{content:"";flex:0 100000 auto;width:2px;min-width:0}
|
|
210
212
|
.graview-bar-name{margin:0;display:flex;font-family:var(--graview-font-display,var(--graview-font-body,system-ui));font-size:.9375rem;font-weight:600;line-height:1.25}
|
|
211
213
|
.graview-bar-home{gap:8px;min-width:auto;min-height:30px;padding:0;letter-spacing:-.005em}
|
|
212
214
|
.graview-bar-app-name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;overflow-wrap:normal;word-break:normal}
|
|
213
|
-
.graview-bar-
|
|
214
|
-
.graview-bar-
|
|
215
|
-
.graview-bar-
|
|
216
|
-
.graview-bar-
|
|
217
|
-
[
|
|
218
|
-
.graview-bar-
|
|
215
|
+
.graview-bar-said{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
|
|
216
|
+
.graview-bar-menu-open{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;box-sizing:border-box;width:24px;height:30px;margin:0;padding:0;border:1px solid transparent;border-radius:6px;background:none;box-shadow:none;color:var(--graview-ink-muted);cursor:pointer}
|
|
217
|
+
.graview-bar-menu-open:is(:hover,[aria-expanded=true]){border-color:var(--graview-edge);color:var(--graview-ink)}
|
|
218
|
+
.graview-bar-tool{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:6px;flex:0 0 auto;box-sizing:border-box;min-width:${TOOL}px;height:${TOOL}px;margin:0;padding:0;border-radius:8px;border:1px solid transparent;background:none;box-shadow:none;font:inherit;font-size:.875rem;font-weight:500;letter-spacing:normal;text-transform:none;white-space:nowrap;color:var(--graview-ink-muted);cursor:pointer;text-decoration:none}
|
|
219
|
+
.graview-bar-tool:is(:hover,[aria-expanded=true]){border-color:var(--graview-edge);color:var(--graview-ink)}
|
|
220
|
+
.graview-bar-tool[data-running]{color:var(--graview-accent)}
|
|
221
|
+
.graview-bar-badge{position:absolute;top:-3px;right:-5px;box-sizing:border-box;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--graview-accent);color:var(--graview-accent-ink);font-size:.625rem;font-weight:700;line-height:16px;text-align:center;font-variant-numeric:tabular-nums;box-shadow:0 0 0 2px var(--graview-bar);pointer-events:none}
|
|
222
|
+
.graview-bar-badge[data-dot]{min-width:8px;width:8px;height:8px;padding:0;top:2px;right:2px}
|
|
223
|
+
.graview-bar-badge[data-tone=warn]{background:var(--graview-warn)}
|
|
224
|
+
.graview-bar-share{gap:6px;padding:0 10px}
|
|
225
|
+
.graview-bar-share-pane{display:grid;gap:10px;width:min(300px,calc(100vw - 24px));padding:14px;border-radius:10px;border:1px solid var(--graview-edge);background:var(--graview-float);box-shadow:var(--graview-lift-high);color:var(--graview-ink);font-size:.875rem;line-height:1.45}
|
|
226
|
+
.graview-bar-share-pane[hidden]{display:none}
|
|
227
|
+
.graview-bar-share-pane p{margin:0}
|
|
228
|
+
.graview-bar-share-links{display:flex;flex-wrap:wrap;gap:4px 16px}
|
|
229
|
+
.graview-bar-share-pane a,.graview-bar-share-pane button{justify-self:start;display:inline-flex;align-items:center;min-height:28px;padding:0;border:0;background:none;box-shadow:none;font:inherit;font-weight:600;color:var(--graview-accent);text-decoration:none;cursor:pointer}
|
|
230
|
+
.graview-bar-status{gap:6px;padding:0 8px;cursor:default;font-weight:400}
|
|
231
|
+
a.graview-bar-status{cursor:pointer}
|
|
219
232
|
.graview-bar-mid{display:flex;flex:1 100 0;min-width:0}
|
|
220
233
|
.graview-bar-mid[data-place]{min-width:9em;flex-basis:auto}
|
|
221
234
|
.graview-bar-place-at{position:relative;display:inline-flex;min-width:0;max-width:100%}
|
|
222
235
|
.graview-bar-place{gap:6px;height:30px;max-width:100%;padding:0 8px;border:1px solid transparent;border-radius:8px;font-size:.875rem;font-weight:600}
|
|
223
|
-
.graview-bar-
|
|
236
|
+
.graview-bar-place:hover{border-color:var(--graview-edge);color:var(--graview-ink)}
|
|
224
237
|
.graview-bar-place-words{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
225
238
|
.graview-bar-mid[data-places=standing]{flex:0 0 auto}
|
|
226
239
|
.graview-bar-places{display:flex;align-items:center;gap:${PLACE_GAP}px;min-width:0;margin:0;padding:0}
|
|
@@ -247,10 +260,11 @@ const BAR_CSS = `
|
|
|
247
260
|
.graview-bar-host{display:flex;align-items:center;gap:2px;flex:0 0 auto}
|
|
248
261
|
.graview-bar-host-action{display:inline-flex;align-items:center;gap:6px;box-sizing:border-box;min-width:${TOOL}px;height:${TOOL}px;margin:0;padding:0 10px;border-radius:8px;border:1px solid transparent;background:none;box-shadow:none;font:inherit;font-size:.875rem;font-weight:500;letter-spacing:normal;text-transform:none;white-space:nowrap;color:var(--graview-ink-muted);cursor:pointer}
|
|
249
262
|
.graview-bar-host-action:is(:hover,[aria-expanded=true]){border-color:var(--graview-edge);color:var(--graview-ink)}
|
|
250
|
-
.graview-bar-host-action[data-folded]{padding:0}
|
|
263
|
+
.graview-bar-host-action:is([data-folded],[data-icon-only]){padding:0;justify-content:center}
|
|
251
264
|
.graview-bar-host-mark{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;font-size:.9375rem;line-height:1}
|
|
252
265
|
.graview-bar-host-mark svg{width:16px;height:16px}
|
|
253
266
|
.graview-bar-list .graview-bar-host-action{width:100%;justify-content:flex-start;white-space:normal;overflow-wrap:anywhere}
|
|
267
|
+
.graview-bar-host-action[data-icon-only]>.graview-bar-host-words{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
254
268
|
.graview-bar-find{position:relative;display:flex;min-width:7.5rem;flex:0 600 9rem;--graview-bar-find-end:3.25em}
|
|
255
269
|
.graview-bar-find-slot{display:flex;flex:1;min-width:0}
|
|
256
270
|
.graview-bar-find-keys{position:absolute;right:10px;line-height:30px;pointer-events:none;font-size:.75rem;color:var(--graview-ink-faint)}
|
|
@@ -260,16 +274,23 @@ const BAR_CSS = `
|
|
|
260
274
|
.graview-bar-line .graview-bar-place{height:auto;min-height:32px}
|
|
261
275
|
.graview-bar-line .graview-bar-place-words{white-space:normal}
|
|
262
276
|
@media (pointer:coarse){.graview-bar-find-keys{display:none}}
|
|
277
|
+
@container graview-bar (max-width: ${BAR_FIND_FOLDS - 1}px){
|
|
278
|
+
.graview-bar-find{display:none}
|
|
279
|
+
.graview-bar-find-open{display:inline-flex}
|
|
280
|
+
.graview-bar-tools>.graview-bar-find-open{margin-left:auto}
|
|
281
|
+
.graview-bar[data-finding] :is(.graview-bar-app,.graview-bar-mid,.graview-bar-find-open){display:none}
|
|
282
|
+
.graview-bar[data-finding] .graview-bar-find{display:flex;flex:1 1 auto;min-width:0;margin-left:0}
|
|
283
|
+
}
|
|
263
284
|
@container graview-bar (max-width: ${BAR_PHONE - 1}px){
|
|
264
285
|
.graview-bar-row{gap:10px;padding:0 12px}
|
|
265
|
-
.graview-bar-app
|
|
286
|
+
.graview-bar-app{max-width:none;flex:1 1 auto;min-width:28px}
|
|
287
|
+
.graview-bar-home{min-width:28px}
|
|
266
288
|
.graview-bar-name,.graview-bar-app-name{min-width:0}
|
|
267
|
-
.graview-bar-mid
|
|
268
|
-
.graview-bar-
|
|
269
|
-
.graview-bar-
|
|
270
|
-
.graview-bar-
|
|
271
|
-
.graview-bar[data-
|
|
272
|
-
.graview-bar[data-finding] .graview-bar-find{display:flex;flex:1 1 auto;min-width:0}
|
|
289
|
+
.graview-bar-mid{display:none}
|
|
290
|
+
.graview-bar-share{padding:0}
|
|
291
|
+
.graview-bar-share>.graview-bar-share-words{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
292
|
+
.graview-bar-status[data-icon]{padding:0}
|
|
293
|
+
.graview-bar-status[data-icon]>.graview-bar-status-words{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
273
294
|
}
|
|
274
295
|
@container graview-bar (max-width: 300px){
|
|
275
296
|
.graview-bar-row{gap:4px;padding:0 10px}
|
|
@@ -295,22 +316,23 @@ export const toolStyle = {
|
|
|
295
316
|
};
|
|
296
317
|
/**
|
|
297
318
|
* THE BAR. The app at the left — its mark, its name as the page's heading,
|
|
298
|
-
* the way home —
|
|
299
|
-
* then, on Pages, the place you are
|
|
300
|
-
* right: the Find a face puts in it,
|
|
301
|
-
*
|
|
319
|
+
* the way home — and the app menu beside it, which holds the scene and the
|
|
320
|
+
* pages (FR-137, Roadmap f-app-bar-calm), then, on Pages, the place you are
|
|
321
|
+
* on (FR-138), and the tools at the right: the Find a face puts in it, the
|
|
322
|
+
* inbox, a host's buttons, the people and a host's Share, then `tools` (the
|
|
323
|
+
* standing and the person). One row of one height on a desk and a phone; on a phone the
|
|
302
324
|
* place is the page's first line, under the bar.
|
|
303
325
|
*/
|
|
304
|
-
export function AppBar({ brand, name, heading = 1, home, faces, places, current, reach, tools, find = true, description, findBox, onFind,
|
|
326
|
+
export function AppBar({ brand, name, heading = 1, home, faces, places, current, reach, tools, find = true, description, findBox, onFind, scenePlaces, skips, named = true, actions, appMenu = NO_ROWS, scheme, share, status, }) {
|
|
305
327
|
const bar = useRef(null);
|
|
306
328
|
// Anybody else here, by the provider's presence (FR-155); none where no provider is.
|
|
307
329
|
const company = useGraviewIfAny()?.who.size;
|
|
308
330
|
const [slot, setSlot] = useState(null);
|
|
309
331
|
const [own, setOwn] = useState(null);
|
|
310
332
|
const [compact, setCompact] = useState(false);
|
|
333
|
+
// Whether Find is the magnifier (below `BAR_FIND_FOLDS`), which opens the box over the row.
|
|
334
|
+
const [folded, setFolded] = useState(false);
|
|
311
335
|
const [finding, setFinding] = useState(false);
|
|
312
|
-
// Whether the switch's words fit beside everything else the row holds (`roomForWords`).
|
|
313
|
-
const [roomy, setRoomy] = useState(true);
|
|
314
336
|
// Which places stand on the row, by their place in the list ("0,1,2"); null, the one control (FR-145).
|
|
315
337
|
const [standing, setStanding] = useState(null);
|
|
316
338
|
// Whether the host's buttons stand on the row (FR-227): where the bar has their width over a phone's; folded where it does not.
|
|
@@ -327,21 +349,16 @@ export function AppBar({ brand, name, heading = 1, home, faces, places, current,
|
|
|
327
349
|
const shown = from && { ...from, places: offeredPlaces(from.places), here: from.places.find((place) => place.key === from.current)?.label };
|
|
328
350
|
const list = shown && shown.places.length > 0 ? shown : null;
|
|
329
351
|
const currentAt = list ? list.places.findIndex((place) => place.key === list.current) : -1;
|
|
330
|
-
const wordsAsked = Boolean(faces) && switchForm === "words";
|
|
331
352
|
// Which places may stand, as one word for the weighing to depend on ("110010…").
|
|
332
353
|
const ranks = list ? list.places.map((place) => (place.primary === false ? "0" : "1")).join("") : "";
|
|
333
354
|
const weigh = useCallback(() => {
|
|
334
355
|
const element = bar.current;
|
|
335
356
|
if (!element)
|
|
336
357
|
return;
|
|
337
|
-
const stand = standsIn(element, currentAt,
|
|
358
|
+
const stand = standsIn(element, currentAt, ranks);
|
|
338
359
|
if (stand !== undefined)
|
|
339
360
|
setStanding(stand);
|
|
340
|
-
|
|
341
|
-
const room = stand ? true : roomForWords(element);
|
|
342
|
-
if (room !== null)
|
|
343
|
-
setRoomy(room);
|
|
344
|
-
}, [currentAt, wordsAsked, ranks]);
|
|
361
|
+
}, [currentAt, ranks]);
|
|
345
362
|
useLayoutEffect(() => {
|
|
346
363
|
const element = bar.current;
|
|
347
364
|
if (!element)
|
|
@@ -349,8 +366,10 @@ export function AppBar({ brand, name, heading = 1, home, faces, places, current,
|
|
|
349
366
|
const read = () => {
|
|
350
367
|
const width = element.getBoundingClientRect().width;
|
|
351
368
|
setCompact(width < BAR_PHONE);
|
|
369
|
+
setFolded(width < BAR_FIND_FOLDS);
|
|
352
370
|
// The host's buttons as they would stand, off their ruler: they stand where the bar has their width over a phone's.
|
|
353
371
|
const host = element.querySelector("[data-graview-bar-host-ruler]");
|
|
372
|
+
// Two of the bar's tools drawn as marks alone stand at every width, as the bar's own do.
|
|
354
373
|
setHostStands(width >= BAR_PHONE + (host?.getBoundingClientRect().width ?? 0));
|
|
355
374
|
// What hangs from the bar as wide as it (a phone's Find sheet) is told the bar's width, not the screen's.
|
|
356
375
|
element.style.setProperty("--graview-bar-width", `${Math.round(width)}px`);
|
|
@@ -384,8 +403,8 @@ export function AppBar({ brand, name, heading = 1, home, faces, places, current,
|
|
|
384
403
|
const told = useRef(onFind);
|
|
385
404
|
told.current = onFind;
|
|
386
405
|
useLayoutEffect(() => {
|
|
387
|
-
told.current?.(find && slot ? { slot, compact, own } : null);
|
|
388
|
-
}, [find, slot,
|
|
406
|
+
told.current?.(find && slot ? { slot, compact: folded, own } : null);
|
|
407
|
+
}, [find, slot, folded, own]);
|
|
389
408
|
useLayoutEffect(() => () => told.current?.(null), []);
|
|
390
409
|
const openFind = useCallback(() => {
|
|
391
410
|
setFinding(true);
|
|
@@ -404,6 +423,50 @@ export function AppBar({ brand, name, heading = 1, home, faces, places, current,
|
|
|
404
423
|
escaping.current = false;
|
|
405
424
|
requestAnimationFrame(() => opener.current?.focus());
|
|
406
425
|
}, []);
|
|
426
|
+
/*
|
|
427
|
+
* HEARD ON THE ELEMENT ITSELF, not through React: the face's box is a
|
|
428
|
+
* portal from the face drawn under the bar, so its keys and its blur
|
|
429
|
+
* bubble through the face's tree and never reach a handler written here.
|
|
430
|
+
* Put away when folded (`BAR_FIND_FOLDS`) as the keyboard leaves it with
|
|
431
|
+
* nothing typed, or by Escape once its words are gone.
|
|
432
|
+
*/
|
|
433
|
+
const findAt = useRef(null);
|
|
434
|
+
useEffect(() => {
|
|
435
|
+
const at = findAt.current;
|
|
436
|
+
if (!at || !folded)
|
|
437
|
+
return;
|
|
438
|
+
const typed = () => Boolean(at.querySelector("input")?.value);
|
|
439
|
+
const left = (event) => {
|
|
440
|
+
const next = event.relatedTarget;
|
|
441
|
+
if (next instanceof Node && at.contains(next))
|
|
442
|
+
return;
|
|
443
|
+
if (!typed())
|
|
444
|
+
putAway();
|
|
445
|
+
};
|
|
446
|
+
const marked = (event) => {
|
|
447
|
+
if (event.key === "Escape")
|
|
448
|
+
escaping.current = true;
|
|
449
|
+
};
|
|
450
|
+
const escaped = (event) => {
|
|
451
|
+
if (event.key !== "Escape")
|
|
452
|
+
return;
|
|
453
|
+
// The scene's Find takes Escape for its words first; an empty box is put away. Weighed once the face's own handler (React's, at its root, after this one) has had the key.
|
|
454
|
+
queueMicrotask(() => {
|
|
455
|
+
if (!event.defaultPrevented || !typed())
|
|
456
|
+
putAway();
|
|
457
|
+
else
|
|
458
|
+
escaping.current = false;
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
at.addEventListener("focusout", left);
|
|
462
|
+
at.addEventListener("keydown", marked, true);
|
|
463
|
+
at.addEventListener("keydown", escaped);
|
|
464
|
+
return () => {
|
|
465
|
+
at.removeEventListener("focusout", left);
|
|
466
|
+
at.removeEventListener("keydown", marked, true);
|
|
467
|
+
at.removeEventListener("keydown", escaped);
|
|
468
|
+
};
|
|
469
|
+
}, [folded, putAway]);
|
|
407
470
|
const Heading = heading === false ? "span" : `h${heading}`;
|
|
408
471
|
const Home = (home.href !== undefined ? "a" : "button");
|
|
409
472
|
const press = (go) => (event) => {
|
|
@@ -423,83 +486,94 @@ export function AppBar({ brand, name, heading = 1, home, faces, places, current,
|
|
|
423
486
|
const placeControl = list ? _jsx(Places, { places: list.places, current: list.current, here: list.here, reach: list.reach, scene: scene, stands: stands }) : null;
|
|
424
487
|
const said = list ? list.places.map((place) => place.label).join("\n") : "";
|
|
425
488
|
// What the row holds changed — the name, the places, the face, the brand — so the places and the words may fit now, or no longer.
|
|
426
|
-
useLayoutEffect(weigh, [weigh, name, brand, said, list?.current, onPages, compact,
|
|
427
|
-
// The
|
|
428
|
-
const
|
|
429
|
-
return (_jsxs(_Fragment, { children: [_jsxs("header", { ref: bar, className: "graview-bar", "data-testid": "app-bar", "data-graview-app-bar": "", ...(finding &&
|
|
430
|
-
// Put away on a phone when the keyboard leaves it with nothing typed.
|
|
431
|
-
const next = event.relatedTarget;
|
|
432
|
-
if (next instanceof Node && event.currentTarget.contains(next))
|
|
433
|
-
return;
|
|
434
|
-
if (!event.currentTarget.querySelector("input")?.value)
|
|
435
|
-
putAway();
|
|
436
|
-
}, onKeyDownCapture: (event) => {
|
|
437
|
-
if (event.key === "Escape" && compact)
|
|
438
|
-
escaping.current = true;
|
|
439
|
-
}, onKeyDown: (event) => {
|
|
440
|
-
if (event.key !== "Escape" || !compact)
|
|
441
|
-
return;
|
|
442
|
-
// The scene's Find takes Escape for its words first; an empty box is put away.
|
|
443
|
-
if (!event.defaultPrevented || !event.currentTarget.querySelector("input")?.value)
|
|
444
|
-
putAway();
|
|
445
|
-
else
|
|
446
|
-
escaping.current = false;
|
|
447
|
-
}, children: [_jsx("div", { ref: setSlot, className: "graview-bar-find-slot", children: findBox }), _jsx(FindKeys, {})] })] })) : null, _jsx("div", { ref: setOwn, className: "graview-bar-own", "data-graview-bar-own": "" }), company ? (_jsx(Suspense, { fallback: null, children: _jsx(Here, { scene: !onPages, compact: compact }) })) : null, _jsx(TheirChanges, {}), actions && actions.length > 0 ? _jsx(HostButtons, { actions: actions, folded: compact || !hostStands }) : null, tools] })] })] }), compact && placeControl ? (_jsx("div", { className: "graview-bar-line", "data-graview-place-line": "", "data-testid": "app-place-line", children: placeControl })) : null] }));
|
|
489
|
+
useLayoutEffect(weigh, [weigh, name, brand, said, list?.current, onPages, compact, folded, find]);
|
|
490
|
+
// The app menu: the scene and the pages, the host's rows, the scheme — drawn where it holds anything.
|
|
491
|
+
const menuHolds = Boolean(faces) || appMenu.length > 0 || Boolean(scheme);
|
|
492
|
+
return (_jsxs(_Fragment, { children: [_jsxs("header", { ref: bar, className: "graview-bar", "data-testid": "app-bar", "data-graview-app-bar": "", ...(finding && folded ? { "data-finding": "" } : {}), children: [_jsx("style", { children: BAR_CSS }), skips, _jsxs("div", { className: "graview-bar-row", children: [named ? _jsxs("div", { className: "graview-bar-app", children: [_jsx(Heading, { className: "graview-bar-name", children: _jsxs(Home, { ...(home.href !== undefined ? { href: home.href, onClick: press(home.go) } : { type: "button", onClick: home.go }), "data-testid": "app-home", ...(home.current ? { "aria-current": "page" } : {}), title: description ? `${name} — ${description}` : `${name} — home`, className: "graview-bar-home", children: [_jsx(AppMark, { brand: brand, size: 20 }), _jsx("span", { className: "graview-bar-app-name", "data-testid": "app-name", children: name })] }) }), menuHolds ? _jsx(AppMenu, { name: name, faces: faces, rows: appMenu, scheme: scheme }) : null] }) : menuHolds ? _jsx(AppMenu, { name: name, faces: faces, rows: appMenu, scheme: scheme }) : null, _jsx("div", { className: "graview-bar-mid", ...(stands ? { "data-places": "standing" } : !compact && placeControl ? { "data-place": "" } : {}), children: compact ? null : placeControl }), !compact && list && list.places.length > 1 ? (_jsxs("span", { className: "graview-bar-ruler", "aria-hidden": "true", "data-graview-bar-ruler": "", children: [list.places.map((place) => (_jsx("span", { className: "graview-bar-at", children: place.label }, place.key))), _jsxs("span", { className: "graview-bar-at", children: [MORE, _jsx(Chevron, {})] })] })) : null, actions && actions.length > 0 ? (_jsx("span", { className: "graview-bar-ruler", "aria-hidden": "true", "data-graview-bar-host-ruler": "", children: _jsx("span", { className: "graview-bar-host", children: actions.map((action) => (_jsxs("span", { className: "graview-bar-host-action", ...(action.iconOnly && action.icon ? { "data-icon-only": "" } : {}), children: [action.icon ? _jsx(HostMark, { icon: action.icon }) : null, _jsx("span", { className: "graview-bar-host-words", children: action.label })] }, action.label))) }) })) : null, named ? (_jsx("span", { className: "graview-bar-ruler", "aria-hidden": "true", children: _jsx("span", { className: "graview-bar-name", children: name }) })) : null, _jsxs("div", { className: "graview-bar-tools", children: [find ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "graview-bar-find-open", ref: opener, "data-testid": "app-find-open", "aria-label": "Find", title: "Find", onClick: openFind, style: { ...toolStyle, display: undefined }, children: _jsx(FindMark, {}) }), _jsxs("div", { ref: findAt, className: "graview-bar-find", "data-testid": "app-find", children: [_jsx("div", { ref: setSlot, className: "graview-bar-find-slot", children: findBox }), _jsx(FindKeys, {})] })] })) : null, _jsx("div", { ref: setOwn, className: "graview-bar-own", "data-graview-bar-own": "" }), actions && actions.length > 0 ? _jsx(HostButtons, { actions: actions, folded: !(actions.length <= 2 && actions.every((action) => action.iconOnly && action.icon)) && (compact || !hostStands) }) : null, status ? _jsx(StatusItem, { status: status }) : null, company ? (_jsx(Suspense, { fallback: null, children: _jsx(Here, { scene: !onPages, compact: compact }) })) : null, share ? _jsx(ShareSlot, { share: share }) : null, _jsx(TheirChanges, {}), tools] })] })] }), compact && placeControl ? (_jsx("div", { className: "graview-bar-line", "data-graview-place-line": "", "data-testid": "app-place-line", children: placeControl })) : null] }));
|
|
448
493
|
}
|
|
494
|
+
const NO_ROWS = [];
|
|
449
495
|
/**
|
|
450
|
-
* THE
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
496
|
+
* THE APP MENU'S CONTROL (Roadmap f-app-bar-calm): a chevron beside the
|
|
497
|
+
* app's name — the name stays the way home, the page's heading — that opens
|
|
498
|
+
* the menu: the scene and the pages, a host's rows, the scheme. Its rows
|
|
499
|
+
* are fetched with the bar's panes when a hand first reaches for it.
|
|
454
500
|
*/
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
501
|
+
/**
|
|
502
|
+
* GOING TO THE OTHER FACE WITHOUT A BUTTON ON THE ROW (Roadmap
|
|
503
|
+
* f-app-bar-calm, f-make-any-page-better). The scene and the pages are rows
|
|
504
|
+
* of the app menu, drawn only while it is open, so a part that must switch
|
|
505
|
+
* faces — Better UI asked in the scene, opened on its page — cannot press
|
|
506
|
+
* them. It dispatches this on the app menu's control
|
|
507
|
+
* (`[data-testid="app-menu-open"]`, which says `data-pages` where the bar
|
|
508
|
+
* holds both faces), with the face as its detail, and the bar goes there as
|
|
509
|
+
* the menu's row would.
|
|
510
|
+
*/
|
|
511
|
+
export const FACE_EVENT = "graview:go-to-face";
|
|
512
|
+
function AppMenu({ name, faces, rows, scheme }) {
|
|
513
|
+
const popover = usePopover("app-menu", { align: "start" });
|
|
514
|
+
const reach = () => barPanes.prefetch();
|
|
515
|
+
/* A part asked to go to the other face (`FACE_EVENT`): gone to as the menu's row would, without opening the menu. */
|
|
516
|
+
const opener = useRef(null);
|
|
517
|
+
const held = useRef(faces);
|
|
518
|
+
held.current = faces;
|
|
519
|
+
useEffect(() => {
|
|
520
|
+
const element = opener.current;
|
|
521
|
+
if (!element)
|
|
522
|
+
return;
|
|
523
|
+
const go = (event) => {
|
|
524
|
+
const one = held.current?.[event.detail];
|
|
525
|
+
if (!one || one.current)
|
|
526
|
+
return;
|
|
527
|
+
one.reach?.();
|
|
528
|
+
one.go();
|
|
529
|
+
};
|
|
530
|
+
element.addEventListener(FACE_EVENT, go);
|
|
531
|
+
return () => element.removeEventListener(FACE_EVENT, go);
|
|
532
|
+
}, []);
|
|
533
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "graview-bar-menu-open", "data-testid": "app-menu-open", ...popover.trigger, ref: (element) => {
|
|
534
|
+
popover.trigger.ref(element);
|
|
535
|
+
opener.current = element;
|
|
536
|
+
}, onClick: popover.toggle, onPointerEnter: reach, onFocus: reach, "aria-label": `${name} — app menu`, title: "App menu", ...(faces ? { "data-scene": faces.scene.label, "data-pages": faces.pages.label } : {}), children: _jsx(Chevron, {}) }), _jsx("div", { ...popover.pane, "data-testid": "app-menu", hidden: !popover.open, className: "graview-bar-list graview-app-menu", style: POPOVER_STYLE, "aria-label": `${name} — app menu`, role: "group", children: popover.open ? (_jsx(Suspense, { fallback: null, children: _jsx(AppMenuRows, { faces: faces, rows: rows, scheme: scheme, close: () => popover.setOpen(false) }) })) : null })] }));
|
|
537
|
+
}
|
|
538
|
+
/** Share's marks: a lock, a globe, two people. */
|
|
539
|
+
function ShareMark({ mark = "lock" }) {
|
|
540
|
+
if (mark === "lock")
|
|
541
|
+
return (_jsxs(Mark, { size: 14, children: [_jsx("rect", { x: "2.75", y: "6.25", width: "8.5", height: "6", rx: "1.25", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("path", { d: "M4.75 6.25 V4.5 a2.25 2.25 0 0 1 4.5 0 V6.25", fill: "none", stroke: "currentColor", strokeWidth: "1.3" })] }));
|
|
542
|
+
if (mark === "globe")
|
|
543
|
+
return (_jsxs(Mark, { size: 14, children: [_jsx("circle", { cx: "7", cy: "7", r: "5.25", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("path", { d: "M1.75 7 H12.25 M7 1.75 C4.75 4.5 4.75 9.5 7 12.25 M7 1.75 C9.25 4.5 9.25 9.5 7 12.25", fill: "none", stroke: "currentColor", strokeWidth: "1.1" })] }));
|
|
544
|
+
if (mark === "people")
|
|
545
|
+
return (_jsxs(Mark, { size: 14, children: [_jsx("circle", { cx: "5", cy: "5", r: "2", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("path", { d: "M1.5 12 a3.5 3.5 0 0 1 7 0", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("circle", { cx: "10", cy: "5.5", r: "1.6", fill: "none", stroke: "currentColor", strokeWidth: "1.2" }), _jsx("path", { d: "M9.5 9 a3 3 0 0 1 3.5 3", fill: "none", stroke: "currentColor", strokeWidth: "1.2" })] }));
|
|
546
|
+
return _jsx(HostMark, { icon: mark });
|
|
464
547
|
}
|
|
465
548
|
/**
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* (`nameGiven`); none when the name is wider on one line than its room. The
|
|
471
|
-
* words fit when that room holds them — the words
|
|
472
|
-
* drawn already, or their width to come when the marks are drawn alone —
|
|
473
|
-
* so the switch never flips back and forth at one width. Not weighed while
|
|
474
|
-
* Find is in use (it is drawn wide then), on a phone's bar (the marks
|
|
475
|
-
* alone), or where nothing is laid out (null).
|
|
549
|
+
* A HOST'S SHARE (Roadmap f-app-bar-calm, f-bar-status-item): its mark and
|
|
550
|
+
* its word, the sentence its description — on hover and to a screen reader —
|
|
551
|
+
* and, pressed, the sentence again with the link to where it changes. One
|
|
552
|
+
* of the bar's family of popovers.
|
|
476
553
|
*/
|
|
477
|
-
function
|
|
478
|
-
const
|
|
479
|
-
const
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
spare -= Math.max(0, basis - find.getBoundingClientRect().width);
|
|
501
|
-
}
|
|
502
|
-
return faces.getAttribute("data-switch-drawn") === "icons" ? spare >= words + 2 : spare >= -1;
|
|
554
|
+
function ShareSlot({ share }) {
|
|
555
|
+
const popover = usePopover("share");
|
|
556
|
+
const said = `graview-share-said-${useId().replace(/:/g, "")}`;
|
|
557
|
+
const label = share.label ?? "Share";
|
|
558
|
+
const link = share.link;
|
|
559
|
+
return (_jsxs("div", { className: "graview-bar-share-at", children: [_jsxs("button", { type: "button", className: "graview-bar-tool graview-bar-share", "data-testid": "app-share-open", ...popover.trigger, onClick: popover.toggle, "aria-describedby": said, title: share.description, children: [_jsx(ShareMark, { mark: share.mark }), _jsx("span", { className: "graview-bar-share-words", children: label })] }), _jsx("span", { id: said, className: "graview-bar-said", children: share.description }), _jsxs("div", { ...popover.pane, "data-testid": "app-share", hidden: !popover.open, className: "graview-bar-share-pane", style: POPOVER_STYLE, role: "group", "aria-label": label, children: [_jsx("p", { "data-testid": "app-share-said", children: share.description }), link || share.secondLink ? (_jsxs("div", { className: "graview-bar-share-links", children: [link ? _jsx(ShareLink, { link: link, testId: "app-share-link", close: () => popover.setOpen(false) }) : null, share.secondLink ? _jsx(ShareLink, { link: share.secondLink, testId: "app-share-second-link", close: () => popover.setOpen(false) }) : null] })) : null] })] }));
|
|
560
|
+
}
|
|
561
|
+
/** A host's status: its mark and its word, the sentence on hover and as its description; a link where it has an `href`. */
|
|
562
|
+
function StatusItem({ status }) {
|
|
563
|
+
const said = `graview-status-said-${useId().replace(/:/g, "")}`;
|
|
564
|
+
const inner = (_jsxs(_Fragment, { children: [status.icon ? _jsx(ShareMark, { mark: status.icon }) : null, _jsx("span", { className: "graview-bar-status-words", children: status.label })] }));
|
|
565
|
+
const common = { className: "graview-bar-tool graview-bar-status", "data-testid": "app-status", title: status.description, "aria-describedby": said, ...(status.icon ? { "data-icon": "" } : {}) };
|
|
566
|
+
return (_jsxs(_Fragment, { children: [status.href !== undefined ? (_jsx("a", { ...common, href: status.href, ...(status.target ? { target: status.target, rel: "noopener" } : {}), children: inner })) : (_jsx("span", { ...common, tabIndex: 0, children: inner })), _jsx("span", { id: said, className: "graview-bar-said", children: status.description })] }));
|
|
567
|
+
}
|
|
568
|
+
/** One of Share's links: an anchor where it has an `href`, else a button; either closes the popover. */
|
|
569
|
+
function ShareLink({ link, testId, close }) {
|
|
570
|
+
return link.href !== undefined ? (_jsx("a", { href: link.href, "data-testid": testId, ...(link.target ? { target: link.target, rel: "noopener" } : {}), onClick: () => {
|
|
571
|
+
link.onSelect?.();
|
|
572
|
+
close();
|
|
573
|
+
}, children: link.label })) : (_jsx("button", { type: "button", "data-testid": testId, onClick: () => {
|
|
574
|
+
close();
|
|
575
|
+
link.onSelect?.();
|
|
576
|
+
}, children: link.label }));
|
|
503
577
|
}
|
|
504
578
|
/**
|
|
505
579
|
* HOW FAR THE ROW RUNS PAST ITS END, in pixels: what stands last on it — a
|
|
@@ -509,7 +583,7 @@ function roomForWords(header) {
|
|
|
509
583
|
* Activity arriving after the places were weighed, an iPad's 1024 px with
|
|
510
584
|
* five places standing), Find's end went past the row with them, the room
|
|
511
585
|
* read as enough, and the person stood off the screen. What runs over is
|
|
512
|
-
* room the places
|
|
586
|
+
* room the places do not have.
|
|
513
587
|
*/
|
|
514
588
|
function overrun(header) {
|
|
515
589
|
const row = header.querySelector(".graview-bar-row");
|
|
@@ -569,10 +643,6 @@ function Mark({ size, box = size, children }) {
|
|
|
569
643
|
function SceneMark() {
|
|
570
644
|
return (_jsxs(Mark, { size: 14, children: [_jsx("path", { d: "M7 1.5 L12.5 4.5 L7 7.5 L1.5 4.5 Z", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinejoin: "round" }), _jsx("path", { d: "M1.5 7.5 L7 10.5 L12.5 7.5", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinejoin: "round", strokeLinecap: "round" })] }));
|
|
571
645
|
}
|
|
572
|
-
/** The pages' mark: a page of lines. */
|
|
573
|
-
function PagesMark() {
|
|
574
|
-
return (_jsxs(Mark, { size: 14, children: [_jsx("rect", { x: "2.25", y: "1.75", width: "9.5", height: "10.5", rx: "1.5", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }), _jsx("path", { d: "M4.5 5 H9.5 M4.5 7.25 H9.5 M4.5 9.5 H7.5", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" })] }));
|
|
575
|
-
}
|
|
576
646
|
/** The way a menu opens: a chevron drawn, not a glyph a face may draw as a dot. */
|
|
577
647
|
function Chevron() {
|
|
578
648
|
return (_jsx(Mark, { size: 10, children: _jsx("path", { d: "M2 3.5 L5 6.5 L8 3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
@@ -612,10 +682,10 @@ const MORE = "More";
|
|
|
612
682
|
function HostButtons({ actions, folded }) {
|
|
613
683
|
const popover = usePopover("host-actions", { popover: folded });
|
|
614
684
|
const names = actions.map((action) => action.label).join(", ");
|
|
615
|
-
const buttons = (done) => actions.map((action) => (_jsxs("button", { type: "button", className: folded ? "graview-bar-host-action graview-bar-item" : "graview-bar-host-action", "data-testid": "host-bar-action", onClick: () => {
|
|
685
|
+
const buttons = (done) => actions.map((action) => (_jsxs("button", { type: "button", className: folded ? "graview-bar-host-action graview-bar-item" : "graview-bar-host-action", "data-testid": "host-bar-action", ...(!folded && action.iconOnly && action.icon ? { "data-icon-only": "", title: action.label } : {}), onClick: () => {
|
|
616
686
|
done();
|
|
617
687
|
action.onSelect();
|
|
618
|
-
}, children: [action.icon ? _jsx(HostMark, { icon: action.icon }) : null, _jsx("span", { children: action.label })] }, action.label)));
|
|
688
|
+
}, children: [action.icon ? _jsx(HostMark, { icon: action.icon }) : null, _jsx("span", { className: "graview-bar-host-words", children: action.label })] }, action.label)));
|
|
619
689
|
if (!folded) {
|
|
620
690
|
return (_jsx("div", { className: "graview-bar-host", "data-testid": "host-bar-actions-standing", role: "group", "aria-label": "From the host", children: buttons(() => undefined) }));
|
|
621
691
|
}
|
|
@@ -737,8 +807,7 @@ function usePlaceGestures(places, current, scene) {
|
|
|
737
807
|
* WHICH PLACES STAND ON THE ROW, WEIGHED FROM THE ROW AS DRAWN (FR-145):
|
|
738
808
|
* the places' widths read off the ruler (each at its weight as the place
|
|
739
809
|
* you are on, so marking one never moves the others), and the room from
|
|
740
|
-
* where the places begin to where Find ends, less Find at its least
|
|
741
|
-
* the switch's words when they are asked for. The same answer whichever way
|
|
810
|
+
* where the places begin to where Find ends, less Find at its least. The same answer whichever way
|
|
742
811
|
* the places are drawn, so the row never flips between the two at one
|
|
743
812
|
* width. The places begin where they would with the app's name on one
|
|
744
813
|
* line (`nameGiven`), so they stand only where they leave it there, and the
|
|
@@ -747,7 +816,7 @@ function usePlaceGestures(places, current, scene) {
|
|
|
747
816
|
* name is wider on one line than its room, or where nothing is laid out
|
|
748
817
|
* (null).
|
|
749
818
|
*/
|
|
750
|
-
function standsIn(header, current,
|
|
819
|
+
function standsIn(header, current, ranks) {
|
|
751
820
|
const ruler = header.querySelector("[data-graview-bar-ruler]");
|
|
752
821
|
const mid = header.querySelector(".graview-bar-mid");
|
|
753
822
|
if (!ruler || !mid)
|
|
@@ -762,11 +831,8 @@ function standsIn(header, current, wordsAsked, ranks) {
|
|
|
762
831
|
return null;
|
|
763
832
|
const widths = [...ruler.children].map((one) => one.getBoundingClientRect().width);
|
|
764
833
|
const more = widths.pop() ?? 0;
|
|
765
|
-
const faces = header.querySelector(".graview-bar-faces");
|
|
766
|
-
const words = faces && wordsAsked ? wordsOf(faces) : 0;
|
|
767
|
-
const drawnWords = faces?.getAttribute("data-switch-drawn") === "words" ? words : 0;
|
|
768
834
|
const from = mid.getBoundingClientRect().left + given;
|
|
769
|
-
const end = find
|
|
835
|
+
const end = find && getComputedStyle(find).display !== "none" ? find.getBoundingClientRect() : undefined;
|
|
770
836
|
/*
|
|
771
837
|
* To Find's end, less Find at its least and the room between them — the
|
|
772
838
|
* row's whole gap: Find stands at `margin-left:auto`, which is nothing
|
|
@@ -776,10 +842,6 @@ function standsIn(header, current, wordsAsked, ranks) {
|
|
|
776
842
|
*/
|
|
777
843
|
const room = (end && end.width > 0 ? end.right - from - (parseFloat(getComputedStyle(find).minWidth) || 0) - 16 : mid.getBoundingClientRect().width - given) - overrun(header);
|
|
778
844
|
const primary = [...ranks].map((rank) => rank !== "0");
|
|
779
|
-
return placesThatStand({ widths, current, room: Math.floor(room
|
|
780
|
-
}
|
|
781
|
-
/** The switch's words, beside each mark: the word, the gap before it, and the button's wider padding. */
|
|
782
|
-
function wordsOf(faces) {
|
|
783
|
-
return [...faces.querySelectorAll(".graview-bar-face span")].reduce((sum, span) => sum + span.scrollWidth + 10, 0);
|
|
845
|
+
return placesThatStand({ widths, current, room: Math.floor(room), more, primary })?.join(",") ?? null;
|
|
784
846
|
}
|
|
785
847
|
//# sourceMappingURL=app-bar.js.map
|