Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/feat-sidebar-settings-discoverability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'default': minor
---

Add sidebar three dot menu for quick access to related settings
116 changes: 103 additions & 13 deletions src/app/pages/client/SidebarNav.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useRef } from 'react';
import { Scroll } from 'folds';

import { MouseEventHandler, useRef, useState } from 'react';
import { Box, Checkbox, config, Line, Menu, MenuItem, PopOut, Scroll, Text, toRem } from 'folds';
import FocusTrap from 'focus-trap-react';
import { stopPropagation } from '$utils/keyboard';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
import { Sidebar, SidebarContent, SidebarStackSeparator, SidebarStack } from '$components/sidebar';
import {
DirectTab,
Expand All @@ -17,9 +20,99 @@ import { CreateTab } from './sidebar/CreateTab';

export function SidebarNav() {
const scrollRef = useRef<HTMLDivElement>(null);
const [menuAnchor, setMenuAnchor] = useState<DOMRect>();

const [uniformIcons, setUniformIcons] = useSetting(settingsAtom, 'uniformIcons');
const [showUnreadCounts, setShowUnreadCounts] = useSetting(settingsAtom, 'showUnreadCounts');
const [badgeCountDMsOnly, setBadgeCountDMsOnly] = useSetting(settingsAtom, 'badgeCountDMsOnly');
const [showPingCounts, setShowPingCounts] = useSetting(settingsAtom, 'showPingCounts');

const handleContextMenu: MouseEventHandler<HTMLDivElement> = (evt) => {
const target = evt.target as HTMLElement;
if (target.closest('button, a, [role="button"]')) return;
evt.preventDefault();
const cords = new DOMRect(evt.clientX, evt.clientY, 0, 0);
setMenuAnchor((current) => (current ? undefined : cords));
};

return (
<Sidebar>
<Sidebar onContextMenu={handleContextMenu}>
{menuAnchor && (
<PopOut
anchor={menuAnchor}
position="Right"
align="Start"
content={
<FocusTrap
focusTrapOptions={{
initialFocus: false,
returnFocusOnDeactivate: false,
onDeactivate: () => setMenuAnchor(undefined),
clickOutsideDeactivates: true,
isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown',
isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp',
escapeDeactivates: stopPropagation,
}}
>
<Menu style={{ maxWidth: toRem(208), width: '100vw' }}>
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
<MenuItem
size="300"
radii="300"
aria-pressed={showUnreadCounts}
onClick={() => setShowUnreadCounts(!showUnreadCounts)}
after={
<Checkbox size="100" checked={showUnreadCounts} readOnly tabIndex={-1} />
}
>
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
Show Room Counts
</Text>
</MenuItem>
<MenuItem
size="300"
radii="300"
aria-pressed={badgeCountDMsOnly}
onClick={() => setBadgeCountDMsOnly(!badgeCountDMsOnly)}
after={
<Checkbox size="100" checked={badgeCountDMsOnly} readOnly tabIndex={-1} />
}
>
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
Show DM Counts
</Text>
</MenuItem>
<MenuItem
size="300"
radii="300"
aria-pressed={showPingCounts}
onClick={() => setShowPingCounts(!showPingCounts)}
after={<Checkbox size="100" checked={showPingCounts} readOnly tabIndex={-1} />}
>
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
Show Mention Counts
</Text>
</MenuItem>
</Box>
<Line variant="Surface" size="300" />
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
<MenuItem
size="300"
radii="300"
aria-pressed={uniformIcons}
onClick={() => setUniformIcons(!uniformIcons)}
after={<Checkbox size="100" checked={uniformIcons} readOnly tabIndex={-1} />}
>
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
Consistent Icon Style
</Text>
</MenuItem>
</Box>
</Menu>
</FocusTrap>
}
/>
)}
<SidebarContent
scrollable={
<Scroll ref={scrollRef} variant="Background" size="0">
Expand All @@ -37,15 +130,12 @@ export function SidebarNav() {
</Scroll>
}
sticky={
<>
<SidebarStackSeparator />
<SidebarStack>
<SearchTab />
<UnverifiedTab />
<InboxTab />
<AccountSwitcherTab />
</SidebarStack>
</>
<SidebarStack>
<SearchTab />
<UnverifiedTab />
<InboxTab />
<AccountSwitcherTab />
</SidebarStack>
}
/>
</Sidebar>
Expand Down
Loading