@remit/web-client 0.0.108 → 0.0.109
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remit/web-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.109",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Remit web client, published as composable primitives — the app shell, auth shells, and runtime config. A distributor imports what it composes and bundles it.",
|
|
6
6
|
"exports": {
|
package/src/auth/AccountMenu.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Avatar } from "@remit/ui";
|
|
2
|
-
import {
|
|
3
|
-
import { LogOut, Settings } from "lucide-react";
|
|
2
|
+
import { LogOut } from "lucide-react";
|
|
4
3
|
import {
|
|
5
4
|
DropdownMenu,
|
|
6
5
|
DropdownMenuItem,
|
|
@@ -14,7 +13,6 @@ interface AccountMenuViewProps {
|
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
const AccountMenuView = ({ email, onSignOut }: AccountMenuViewProps) => {
|
|
17
|
-
const navigate = useNavigate();
|
|
18
16
|
const displayName = email ?? "Account";
|
|
19
17
|
|
|
20
18
|
return (
|
|
@@ -36,11 +34,6 @@ const AccountMenuView = ({ email, onSignOut }: AccountMenuViewProps) => {
|
|
|
36
34
|
<DropdownMenuSeparator />
|
|
37
35
|
</>
|
|
38
36
|
)}
|
|
39
|
-
<DropdownMenuItem onClick={() => navigate({ to: "/settings/accounts" })}>
|
|
40
|
-
<Settings className="size-4" />
|
|
41
|
-
Settings
|
|
42
|
-
</DropdownMenuItem>
|
|
43
|
-
<DropdownMenuSeparator />
|
|
44
37
|
<DropdownMenuItem onClick={onSignOut}>
|
|
45
38
|
<LogOut className="size-4" />
|
|
46
39
|
Sign out
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MailTopBar — the app's one search surface and its global actions.
|
|
3
3
|
*
|
|
4
|
-
* Mounted by the `/mail` shell
|
|
5
|
-
*
|
|
6
|
-
* not the list's: the list header drops its own field wherever this bar
|
|
7
|
-
* mounted, so exactly one search input exists on the page and the "/"
|
|
8
|
-
* has one target.
|
|
4
|
+
* Mounted by the `/mail` shell across the top of the whole layout — the nav
|
|
5
|
+
* column, the list, the reading pane and the intelligence rail. It is the app's
|
|
6
|
+
* search, not the list's: the list header drops its own field wherever this bar
|
|
7
|
+
* is mounted, so exactly one search input exists on the page and the "/"
|
|
8
|
+
* shortcut has one target.
|
|
9
9
|
*
|
|
10
10
|
* The actions here are the ones that belong to the app rather than to whatever
|
|
11
|
-
* is currently listed or open — compose, bug report,
|
|
12
|
-
* move and the rest stay on the reading pane's own
|
|
11
|
+
* is currently listed or open — the nav toggle, compose, bug report, settings,
|
|
12
|
+
* account. Reply, delete, move and the rest stay on the reading pane's own
|
|
13
|
+
* toolbar, under this bar.
|
|
13
14
|
*
|
|
14
15
|
* The field carries one chip: the scope of the view the user navigated into
|
|
15
16
|
* (`in:spam` in Spam, nothing on the brief). Removing it goes to the brief and
|
|
@@ -19,8 +20,9 @@
|
|
|
19
20
|
* sections instead, where the text is not repeated.
|
|
20
21
|
*/
|
|
21
22
|
import type { RemitImapAccountResponse } from "@remit/api-http-client/types.gen.ts";
|
|
22
|
-
import { AppTopBar, Button, SearchBar } from "@remit/ui";
|
|
23
|
-
import {
|
|
23
|
+
import { AppTopBar, Button, NavToggleButton, SearchBar } from "@remit/ui";
|
|
24
|
+
import { useNavigate } from "@tanstack/react-router";
|
|
25
|
+
import { Settings, SquarePen } from "lucide-react";
|
|
24
26
|
import { AccountMenu } from "@/auth/AccountMenu";
|
|
25
27
|
import { BugReportButton } from "@/components/ui/BugReportButton";
|
|
26
28
|
import { useGlobalCompose } from "@/hooks/useComposeTarget";
|
|
@@ -42,6 +44,7 @@ interface MailTopBarProps {
|
|
|
42
44
|
export function MailTopBar({ accounts }: MailTopBarProps) {
|
|
43
45
|
const { searchInput, onSearchChange, onSearchClear, onSearchClearQuery } =
|
|
44
46
|
useMailContext();
|
|
47
|
+
const navigate = useNavigate();
|
|
45
48
|
const compose = useGlobalCompose(accounts);
|
|
46
49
|
const { scope, clearScope } = useSearchScope(accounts);
|
|
47
50
|
const chips =
|
|
@@ -55,6 +58,7 @@ export function MailTopBar({ accounts }: MailTopBarProps) {
|
|
|
55
58
|
|
|
56
59
|
return (
|
|
57
60
|
<AppTopBar
|
|
61
|
+
leading={<NavToggleButton />}
|
|
58
62
|
search={
|
|
59
63
|
<SearchBar
|
|
60
64
|
value={searchInput}
|
|
@@ -64,7 +68,6 @@ export function MailTopBar({ accounts }: MailTopBarProps) {
|
|
|
64
68
|
chips={chips}
|
|
65
69
|
onRemoveChip={clearScope}
|
|
66
70
|
placeholder={placeholder}
|
|
67
|
-
size="lg"
|
|
68
71
|
/>
|
|
69
72
|
}
|
|
70
73
|
actions={
|
|
@@ -78,6 +81,14 @@ export function MailTopBar({ accounts }: MailTopBarProps) {
|
|
|
78
81
|
onClick={compose}
|
|
79
82
|
/>
|
|
80
83
|
<BugReportButton />
|
|
84
|
+
<Button
|
|
85
|
+
variant="ghost"
|
|
86
|
+
size="sm"
|
|
87
|
+
icon={<Settings className="size-4" />}
|
|
88
|
+
title="Settings"
|
|
89
|
+
aria-label="Settings"
|
|
90
|
+
onClick={() => navigate({ to: "/settings/accounts" })}
|
|
91
|
+
/>
|
|
81
92
|
<AccountMenu />
|
|
82
93
|
</>
|
|
83
94
|
}
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
import {
|
|
42
42
|
Button,
|
|
43
43
|
type FilterSheetProps,
|
|
44
|
+
FilterToggle,
|
|
44
45
|
isConvertible,
|
|
45
46
|
MakeFilterAction,
|
|
46
47
|
MobileSearchView,
|
|
@@ -435,9 +436,12 @@ export function MailListHeader({
|
|
|
435
436
|
/>
|
|
436
437
|
),
|
|
437
438
|
titleMeta: (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
439
|
+
<>
|
|
440
|
+
<span className="shrink-0 text-2xs text-fg-subtle">
|
|
441
|
+
{unreadCount.toLocaleString()} unread
|
|
442
|
+
</span>
|
|
443
|
+
{!hasQuery && <FilterToggle />}
|
|
444
|
+
</>
|
|
441
445
|
),
|
|
442
446
|
searchSlot: ownsSearch && !searchExpanded && (
|
|
443
447
|
<Button
|
|
@@ -488,6 +492,7 @@ export function MailListHeader({
|
|
|
488
492
|
chromeResults,
|
|
489
493
|
makeFilterAction,
|
|
490
494
|
searchConversion,
|
|
495
|
+
hasQuery,
|
|
491
496
|
],
|
|
492
497
|
);
|
|
493
498
|
|
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
* surface and the section headers flatten correctly when filtered).
|
|
19
19
|
*/
|
|
20
20
|
import {
|
|
21
|
+
FilterPanelProvider,
|
|
21
22
|
type FilterPreset,
|
|
22
23
|
FilterSheet,
|
|
23
24
|
type FilterSheetProps,
|
|
24
25
|
type SearchResult,
|
|
25
26
|
} from "@remit/ui";
|
|
26
|
-
import {
|
|
27
|
+
import type { ReactNode } from "react";
|
|
27
28
|
import { useMailContext } from "@/lib/mail-context";
|
|
28
29
|
import { MailListHeader } from "./MailListHeader";
|
|
29
30
|
|
|
@@ -81,7 +82,6 @@ export function MailViewChrome({
|
|
|
81
82
|
relatedResultsLabel,
|
|
82
83
|
searchResultsInBody,
|
|
83
84
|
}: MailViewChromeProps) {
|
|
84
|
-
const [expanded, setExpanded] = useState(false);
|
|
85
85
|
// A query owns the pane: the filter chrome and the search's own affordance
|
|
86
86
|
// narrow the same list from the same place, so the filter sheet stands down
|
|
87
87
|
// for as long as something is being searched. Its state survives — clearing
|
|
@@ -95,8 +95,6 @@ export function MailViewChrome({
|
|
|
95
95
|
sources: preset.sources,
|
|
96
96
|
selectedCategory,
|
|
97
97
|
activeFilters,
|
|
98
|
-
expanded,
|
|
99
|
-
onExpandedChange: setExpanded,
|
|
100
98
|
onSelectCategory,
|
|
101
99
|
onSelectSource,
|
|
102
100
|
onToggleFilter,
|
|
@@ -104,26 +102,28 @@ export function MailViewChrome({
|
|
|
104
102
|
};
|
|
105
103
|
|
|
106
104
|
return (
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
105
|
+
<FilterPanelProvider>
|
|
106
|
+
<MailListHeader
|
|
107
|
+
title={title}
|
|
108
|
+
unreadCount={unreadCount}
|
|
109
|
+
footer={footer}
|
|
110
|
+
searchFilter={filterConfig}
|
|
111
|
+
searchResults={searchResults}
|
|
112
|
+
searchLoading={searchLoading}
|
|
113
|
+
relatedResults={relatedResults}
|
|
114
|
+
relatedLoading={relatedLoading}
|
|
115
|
+
onSelectSearchResult={onSelectSearchResult}
|
|
116
|
+
searchResultsLabel={searchResultsLabel}
|
|
117
|
+
relatedResultsLabel={relatedResultsLabel}
|
|
118
|
+
searchResultsInBody={searchResultsInBody}
|
|
119
|
+
>
|
|
120
|
+
{/* One shell either way: the children's parent must not change when a
|
|
121
|
+
query starts, or everything under it — including the header's own
|
|
122
|
+
search field — remounts mid-keystroke. */}
|
|
123
|
+
<FilterSheet {...filterConfig} hideChrome={searching}>
|
|
124
|
+
{children}
|
|
125
|
+
</FilterSheet>
|
|
126
|
+
</MailListHeader>
|
|
127
|
+
</FilterPanelProvider>
|
|
128
128
|
);
|
|
129
129
|
}
|