Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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