Skip to content

Commit

Permalink
refactor: useRovingTabindex: expose className
Browse files Browse the repository at this point in the history
It's harder to forget to set it this way.
  • Loading branch information
WofWca committed Oct 30, 2024
1 parent 60bf008 commit 621fdd0
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default function AccountItem({

return (
<button
className={classNames(styles.account, 'roving-tabindex', {
className={classNames(styles.account, rovingTabindex.className, {
[styles.active]: isSelected,
[styles['context-menu-active']]: isContextMenuActive,
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function AddAccountButton(props: { onClick: () => void }) {
<button
ref={ref}
aria-label={tx('add_account')}
className={classNames(styles.addButton, 'roving-tabindex')}
className={classNames(styles.addButton, rovingTabindex.className)}
tabIndex={rovingTabindex.tabIndex}
onKeyDown={rovingTabindex.onKeydown}
onFocus={rovingTabindex.setAsActiveElement}
Expand Down
12 changes: 8 additions & 4 deletions packages/frontend/src/components/chat/ChatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ function ChatListItemArchiveLink({
tabIndex,
onKeydown: tabindexOnKeydown,
setAsActiveElement: tabindexSetAsActiveElement,
className: tabindexClassName,
} = useRovingTabindex(ref)

return (
Expand All @@ -190,7 +191,7 @@ function ChatListItemArchiveLink({
onKeyDown={tabindexOnKeydown}
onFocus={tabindexSetAsActiveElement}
onContextMenu={onContextMenu}
className={`chat-list-item archive-link-item roving-tabindex ${
className={`chat-list-item archive-link-item ${tabindexClassName} ${
isContextMenuActive ? 'context-menu-active' : ''
}`}
>
Expand Down Expand Up @@ -228,6 +229,7 @@ function ChatListItemError({
tabIndex,
onKeydown: tabindexOnKeydown,
setAsActiveElement: tabindexSetAsActiveElement,
className: tabindexClassName,
} = useRovingTabindex(ref)

return (
Expand All @@ -238,7 +240,7 @@ function ChatListItemError({
onKeyDown={tabindexOnKeydown}
onFocus={tabindexSetAsActiveElement}
onContextMenu={onContextMenu}
className={classNames('chat-list-item roving-tabindex', {
className={classNames('chat-list-item', tabindexClassName, {
isError: true,
selected: isSelected,
})}
Expand Down Expand Up @@ -290,6 +292,7 @@ function ChatListItemNormal({
tabIndex,
onKeydown: tabindexOnKeydown,
setAsActiveElement: tabindexSetAsActiveElement,
className: tabindexClassName,
} = useRovingTabindex(ref)
// TODO `setAsActiveElement` if `isSelected` and `activeElement === null`

Expand All @@ -301,7 +304,7 @@ function ChatListItemNormal({
onKeyDown={tabindexOnKeydown}
onFocus={tabindexSetAsActiveElement}
onContextMenu={onContextMenu}
className={classNames('chat-list-item roving-tabindex', {
className={classNames('chat-list-item', tabindexClassName, {
'has-unread': chatListItem.freshMessageCounter > 0,
'is-contact-request': chatListItem.isContactRequest,
pinned: chatListItem.isPinned,
Expand Down Expand Up @@ -416,6 +419,7 @@ export const ChatListItemMessageResult = React.memo<{
tabIndex,
onKeydown: tabindexOnKeydown,
setAsActiveElement: tabindexSetAsActiveElement,
className: tabindexClassName,
} = useRovingTabindex(ref)

if (typeof msr === 'undefined') return <PlaceholderChatListItem />
Expand All @@ -427,7 +431,7 @@ export const ChatListItemMessageResult = React.memo<{
onClick={onClick}
onKeyDown={tabindexOnKeydown}
onFocus={tabindexSetAsActiveElement}
className='pseudo-chat-list-item message-search-result roving-tabindex'
className={`pseudo-chat-list-item message-search-result ${tabindexClassName}`}
>
<div className='avatars'>
<Avatar
Expand Down
9 changes: 9 additions & 0 deletions packages/frontend/src/contexts/RovingTabindex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export function useRovingTabindex(elementRef: RefObject<HTMLElement>) {
// if this means something to us practically.
setAsActiveElement: () => context.setActiveElement(elementRef.current),
activeElement: context.activeElement,
/**
* The target elements must have this class name set.
* It's the same value that is provided to
* {@link ProviderProps.classNameOfTargetElements}.
*/
className: context.classNameOfTargetElements,
}
}

Expand All @@ -75,6 +81,7 @@ type ContextValue = {
activeElement: HTMLElement | null
onKeydown: (event: React.KeyboardEvent) => void
setActiveElement: (element: HTMLElement | null) => void
classNameOfTargetElements: string
}

type ProviderProps = PropsWithChildren<{
Expand All @@ -95,6 +102,7 @@ export const RovingTabindexContext = createContext<ContextValue>({
activeElement: null,
onKeydown: () => {},
setActiveElement: () => {},
classNameOfTargetElements: 'roving-tabindex',
})

/** @see {@link useRovingTabindex} */
Expand Down Expand Up @@ -211,6 +219,7 @@ export function RovingTabindexProvider({
activeElement,
onKeydown,
setActiveElement,
classNameOfTargetElements,
}}
>
{children}
Expand Down

0 comments on commit 621fdd0

Please sign in to comment.