@anthusai/papyrus 5.41.2 → 5.41.3
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/app/globals.css
CHANGED
|
@@ -10170,3 +10170,36 @@ img {
|
|
|
10170
10170
|
}
|
|
10171
10171
|
}
|
|
10172
10172
|
|
|
10173
|
+
|
|
10174
|
+
.papyrus-console-mobile-trigger { display: none; }
|
|
10175
|
+
@media (max-width: 900px) {
|
|
10176
|
+
.edition-progress__button--console { display: none; }
|
|
10177
|
+
.papyrus-console-mobile-trigger {
|
|
10178
|
+
display: inline-flex;
|
|
10179
|
+
align-items: center;
|
|
10180
|
+
justify-content: center;
|
|
10181
|
+
position: fixed;
|
|
10182
|
+
right: 16px;
|
|
10183
|
+
bottom: calc(76px + env(safe-area-inset-bottom));
|
|
10184
|
+
z-index: 1200;
|
|
10185
|
+
min-width: 64px;
|
|
10186
|
+
min-height: 44px;
|
|
10187
|
+
padding: 8px 16px;
|
|
10188
|
+
background: rgb(var(--paper-rgb));
|
|
10189
|
+
color: var(--ink);
|
|
10190
|
+
border: 1px solid currentColor;
|
|
10191
|
+
font: 600 14px Arial, sans-serif;
|
|
10192
|
+
}
|
|
10193
|
+
.papyrus-console-mobile-trigger:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
|
|
10194
|
+
.papyrus-console--open {
|
|
10195
|
+
--papyrus-console-width: 100vw;
|
|
10196
|
+
background: rgb(var(--paper-rgb));
|
|
10197
|
+
height: 100dvh;
|
|
10198
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
10199
|
+
box-sizing: border-box;
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
|
|
10203
|
+
@media (max-width: 900px) {
|
|
10204
|
+
.papyrus-console__header button { min-width: 44px; min-height: 44px; }
|
|
10205
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState, type ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
export function PapyrusConsoleFrame({ available, open, reserveSpace, onOpen, onClose, page, children }: {
|
|
6
|
+
available: boolean;
|
|
7
|
+
open: boolean;
|
|
8
|
+
reserveSpace: boolean;
|
|
9
|
+
onOpen: () => void;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
page: ReactNode;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
}) {
|
|
14
|
+
const [mobile, setMobile] = useState(false);
|
|
15
|
+
const [viewport, setViewport] = useState<{ top: number; height: number } | null>(null);
|
|
16
|
+
const panel = useRef<HTMLElement>(null);
|
|
17
|
+
const modal = available && open && mobile;
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const media = window.matchMedia("(max-width: 900px)");
|
|
21
|
+
const update = () => setMobile(media.matches);
|
|
22
|
+
update();
|
|
23
|
+
media.addEventListener("change", update);
|
|
24
|
+
return () => media.removeEventListener("change", update);
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!modal) return;
|
|
29
|
+
const visual = window.visualViewport;
|
|
30
|
+
const update = () => setViewport({ top: visual?.offsetTop ?? 0, height: visual?.height ?? window.innerHeight });
|
|
31
|
+
update();
|
|
32
|
+
visual?.addEventListener("resize", update);
|
|
33
|
+
visual?.addEventListener("scroll", update, { passive: true });
|
|
34
|
+
return () => {
|
|
35
|
+
visual?.removeEventListener("resize", update);
|
|
36
|
+
visual?.removeEventListener("scroll", update);
|
|
37
|
+
};
|
|
38
|
+
}, [modal]);
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!modal) return;
|
|
42
|
+
const previous = document.activeElement;
|
|
43
|
+
const frame = requestAnimationFrame(() => panel.current?.querySelector<HTMLElement>("button")?.focus());
|
|
44
|
+
return () => {
|
|
45
|
+
cancelAnimationFrame(frame);
|
|
46
|
+
requestAnimationFrame(() => {
|
|
47
|
+
if (previous instanceof HTMLElement && previous !== document.body && previous.isConnected && !previous.closest("[inert]")) previous.focus();
|
|
48
|
+
else Array.from(document.querySelectorAll<HTMLElement>(".papyrus-console-mobile-trigger, .edition-progress__button--console, .papyrus-console__header button")).find(element => element.getClientRects().length > 0)?.focus();
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
}, [modal]);
|
|
52
|
+
|
|
53
|
+
return <>
|
|
54
|
+
<div className={reserveSpace ? "papyrus-console-page papyrus-console-page--open" : "papyrus-console-page"} inert={modal || undefined}>{page}</div>
|
|
55
|
+
{available && !open ? <button className="papyrus-console-mobile-trigger" type="button" aria-label="Open private chat" aria-expanded={false} aria-controls="papyrus-console-panel" onClick={onOpen}>Chat</button> : null}
|
|
56
|
+
{available ? <aside ref={panel} id="papyrus-console-panel" className={open ? "papyrus-console papyrus-console--open" : "papyrus-console"} aria-label="Papyrus console" role={modal ? "dialog" : undefined} aria-modal={modal || undefined}
|
|
57
|
+
style={modal && viewport ? { top: viewport.top, height: viewport.height, bottom: "auto" } : undefined}
|
|
58
|
+
onKeyDown={event => {
|
|
59
|
+
if (!modal) return;
|
|
60
|
+
if (event.key === "Escape") { event.preventDefault(); onClose(); return; }
|
|
61
|
+
if (event.key !== "Tab") return;
|
|
62
|
+
const focusable = Array.from(panel.current?.querySelectorAll<HTMLElement>('button:not(:disabled), a[href], input:not(:disabled), textarea:not(:disabled), select:not(:disabled), [tabindex="0"]') ?? []).filter(element => element.getClientRects().length > 0);
|
|
63
|
+
const first = focusable[0], last = focusable.at(-1);
|
|
64
|
+
if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last?.focus(); }
|
|
65
|
+
else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first?.focus(); }
|
|
66
|
+
}}>{children}</aside> : null}
|
|
67
|
+
</>;
|
|
68
|
+
}
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type ReaderMotionSetting,
|
|
36
36
|
} from "./reader-settings";
|
|
37
37
|
import { PapyrusConsoleConversation, type ConsoleConversationMessage } from "./papyrus-console-conversation";
|
|
38
|
+
import { PapyrusConsoleFrame } from "./papyrus-console-frame";
|
|
38
39
|
import { PapyrusPrivateChatPanel } from "./papyrus-private-chat-panel";
|
|
39
40
|
import { ModelSelector } from "./ai-elements/model-selector";
|
|
40
41
|
import { Suggestion, Suggestions } from "./ai-elements/suggestion";
|
|
@@ -358,20 +359,15 @@ export function PapyrusConsoleShell({ children, privateChatEnabled = false }: Pa
|
|
|
358
359
|
|
|
359
360
|
return (
|
|
360
361
|
<PapyrusConsoleContext.Provider value={consoleContext}>
|
|
361
|
-
<
|
|
362
|
-
{
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
: <ConsolePanel actorEmail={session?.auth.status === "signedIn" ? (session.auth.email ?? null) : null} actorLabel={session?.auth.label ?? "Papyrus editor"} onClose={toggleOpen} />
|
|
371
|
-
: <ConsoleAccessPanel onClose={toggleOpen} session={session} />
|
|
372
|
-
) : null}
|
|
373
|
-
</aside>
|
|
374
|
-
) : null}
|
|
362
|
+
<PapyrusConsoleFrame available={shouldOfferConsole} open={open} reserveSpace={canUseConsole && open} onClose={toggleOpen} onOpen={openConsole} page={children}>
|
|
363
|
+
{open ? (
|
|
364
|
+
canUseConsole
|
|
365
|
+
? privateChatEnabled
|
|
366
|
+
? <PapyrusPrivateChatPanel onClose={toggleOpen} />
|
|
367
|
+
: <ConsolePanel actorEmail={session?.auth.status === "signedIn" ? (session.auth.email ?? null) : null} actorLabel={session?.auth.label ?? "Papyrus editor"} onClose={toggleOpen} />
|
|
368
|
+
: <ConsoleAccessPanel onClose={toggleOpen} session={session} />
|
|
369
|
+
) : null}
|
|
370
|
+
</PapyrusConsoleFrame>
|
|
375
371
|
</PapyrusConsoleContext.Provider>
|
|
376
372
|
);
|
|
377
373
|
}
|
package/package.json
CHANGED
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
"./components/newsroom-topics-view": "./components/newsroom-topics-view.tsx",
|
|
119
119
|
"./components/notification-center": "./components/notification-center.tsx",
|
|
120
120
|
"./components/papyrus-console-conversation": "./components/papyrus-console-conversation.tsx",
|
|
121
|
+
"./components/papyrus-console-frame": "./components/papyrus-console-frame.tsx",
|
|
121
122
|
"./components/papyrus-console-shell": "./components/papyrus-console-shell.tsx",
|
|
122
123
|
"./components/papyrus-private-chat-panel": "./components/papyrus-private-chat-panel.tsx",
|
|
123
124
|
"./components/pictogram-figure": "./components/pictogram-figure.tsx",
|
|
@@ -458,7 +459,7 @@
|
|
|
458
459
|
"optional": true
|
|
459
460
|
}
|
|
460
461
|
},
|
|
461
|
-
"version": "5.41.
|
|
462
|
+
"version": "5.41.3",
|
|
462
463
|
"dependencies": {
|
|
463
464
|
"@aws-amplify/adapter-nextjs": "^1.7.3",
|
|
464
465
|
"@aws-crypto/sha256-js": "5.2.0",
|
package/routes.manifest.json
CHANGED