From 5d4c0eb1eaefbcd6bf6b0b0022bb32382c1dee26 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 26 Jan 2024 14:20:20 -0300 Subject: [PATCH 01/14] feat: `MessageHeader` navigation --- .../components/message/MessageHeader.tsx | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/apps/meteor/client/components/message/MessageHeader.tsx b/apps/meteor/client/components/message/MessageHeader.tsx index 3189aa2972bca..a49637992e195 100644 --- a/apps/meteor/client/components/message/MessageHeader.tsx +++ b/apps/meteor/client/components/message/MessageHeader.tsx @@ -8,7 +8,7 @@ import { MessageNameContainer, } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { KeyboardEvent, ReactElement } from 'react'; import React, { memo } from 'react'; import { getUserDisplayName } from '../../../lib/getUserDisplayName'; @@ -45,37 +45,35 @@ const MessageHeader = ({ message }: MessageHeaderProps): ReactElement => { return ( - + ) => { + (e.code === 'Enter' || e.code === 'Space') && chat?.userCard.open(message.u.username)(e); + }, + style: { cursor: 'pointer' }, + })} + > {message.alias || getUserDisplayName(user.name, user.username, showRealName)} {showUsername && ( <> {' '} - + @{user.username} )} - {shouldShowRolesList && } {formatTime(message.ts)} {message.private && {t('Only_you_can_see_this_message')}} From b38abb0e782c3651928ef2fea07990253466b6f6 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 26 Jan 2024 14:23:00 -0300 Subject: [PATCH 02/14] feat: `MessageToolbar` navigation --- .../components/message/toolbar/MessageToolbar.tsx | 13 +++++++++---- .../views/composer/EmojiPicker/EmojiElement.tsx | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx index 81385d673749d..408c715c965ee 100644 --- a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx +++ b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx @@ -1,11 +1,12 @@ +import { useToolbar } from '@react-aria/toolbar'; import type { IMessage, IRoom, ISubscription, ITranslatedMessage } from '@rocket.chat/core-typings'; import { isThreadMessage, isRoomFederated, isVideoConfMessage } from '@rocket.chat/core-typings'; import { MessageToolbar as FuselageMessageToolbar, MessageToolbarItem } from '@rocket.chat/fuselage'; import { useFeaturePreview } from '@rocket.chat/ui-client'; import { useUser, useSettings, useTranslation, useMethod, useLayoutHiddenActions } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; -import type { ReactElement } from 'react'; -import React, { memo, useMemo } from 'react'; +import type { ComponentProps, ReactElement } from 'react'; +import React, { memo, useMemo, useRef } from 'react'; import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction'; import { MessageAction } from '../../../../app/ui-utils/client/lib/MessageAction'; @@ -44,7 +45,7 @@ type MessageToolbarProps = { room: IRoom; subscription?: ISubscription; onChangeMenuVisibility: (visible: boolean) => void; -}; +} & ComponentProps; const MessageToolbar = ({ message, @@ -52,11 +53,15 @@ const MessageToolbar = ({ room, subscription, onChangeMenuVisibility, + ...props }: MessageToolbarProps): ReactElement | null => { const t = useTranslation(); const user = useUser() ?? undefined; const settings = useSettings(); + const toolbarRef = useRef(null); + const { toolbarProps } = useToolbar(props, toolbarRef); + const quickReactionsEnabled = useFeaturePreview('quickReactions'); const setReaction = useMethod('setReaction'); @@ -102,7 +107,7 @@ const MessageToolbar = ({ }; return ( - + {quickReactionsEnabled && isReactionAllowed && quickReactions.slice(0, 3).map(({ emoji, image }) => { diff --git a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx index 9577e3def7826..38ac7c2de7a10 100644 --- a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx +++ b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx @@ -30,7 +30,6 @@ const EmojiElement = ({ emoji, image, onClick, small = false, ...props }: EmojiE return ( ); }; From 27c75adf723a261d5e8096da41e30293fe943230 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 26 Jan 2024 14:28:01 -0300 Subject: [PATCH 03/14] feat: message navigation --- .../message/variants/RoomMessage.tsx | 11 ++-- .../message/variants/SystemMessage.tsx | 9 ++-- .../message/variants/ThreadMessagePreview.tsx | 33 +++++++----- apps/meteor/client/views/room/Room.tsx | 53 ++++++++++--------- .../client/views/room/body/RoomBody.tsx | 5 +- .../views/room/hooks/useRoomNavigation.ts | 35 ++++++++++++ 6 files changed, 98 insertions(+), 48 deletions(-) create mode 100644 apps/meteor/client/views/room/hooks/useRoomNavigation.ts diff --git a/apps/meteor/client/components/message/variants/RoomMessage.tsx b/apps/meteor/client/components/message/variants/RoomMessage.tsx index af8a6c08297cd..5b5295d284ba0 100644 --- a/apps/meteor/client/components/message/variants/RoomMessage.tsx +++ b/apps/meteor/client/components/message/variants/RoomMessage.tsx @@ -2,7 +2,7 @@ import type { IMessage } from '@rocket.chat/core-typings'; import { Message, MessageLeftContainer, MessageContainer, CheckBox } from '@rocket.chat/fuselage'; import { useToggle } from '@rocket.chat/fuselage-hooks'; import { useUserId } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ComponentProps, ReactElement } from 'react'; import React, { useRef, memo } from 'react'; import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction'; @@ -32,7 +32,7 @@ type RoomMessageProps = { context?: MessageActionContext; ignoredUser?: boolean; searchText?: string; -}; +} & ComponentProps; const RoomMessage = ({ message, @@ -44,6 +44,7 @@ const RoomMessage = ({ context, ignoredUser, searchText, + ...props }: RoomMessageProps): ReactElement => { const uid = useUserId(); const editing = useIsMessageHighlight(message._id); @@ -59,10 +60,13 @@ const RoomMessage = ({ useCountSelected(); useJumpToMessage(message._id, messageRef); + return ( {!sequential && message.u.username && !selecting && showUserAvatar && ( @@ -94,10 +99,8 @@ const RoomMessage = ({ {selecting && } {sequential && } - {!sequential && } - {ignored ? ( ) : ( diff --git a/apps/meteor/client/components/message/variants/SystemMessage.tsx b/apps/meteor/client/components/message/variants/SystemMessage.tsx index bef39112bb112..8b9234b02b960 100644 --- a/apps/meteor/client/components/message/variants/SystemMessage.tsx +++ b/apps/meteor/client/components/message/variants/SystemMessage.tsx @@ -13,7 +13,7 @@ import { } from '@rocket.chat/fuselage'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ComponentProps, ReactElement } from 'react'; import React, { memo } from 'react'; import { MessageTypes } from '../../../../app/ui-utils/client'; @@ -37,9 +37,9 @@ import { useMessageListShowRealName, useMessageListShowUsername } from '../list/ type SystemMessageProps = { message: IMessage; showUserAvatar: boolean; -}; +} & ComponentProps; -const SystemMessage = ({ message, showUserAvatar }: SystemMessageProps): ReactElement => { +const SystemMessage = ({ message, showUserAvatar, ...props }: SystemMessageProps): ReactElement => { const t = useTranslation(); const formatTime = useFormatTime(); const formatDateAndTime = useFormatDateAndTime(); @@ -59,11 +59,14 @@ const SystemMessage = ({ message, showUserAvatar }: SystemMessageProps): ReactEl return ( {!isSelecting && showUserAvatar && } diff --git a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx index eb6fe03d9d0fc..9401e32967149 100644 --- a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx +++ b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx @@ -13,7 +13,7 @@ import { MessageStatusIndicatorItem, } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ComponentProps, ReactElement } from 'react'; import React, { memo } from 'react'; import { MessageTypes } from '../../../../app/ui-utils/client'; @@ -35,7 +35,7 @@ type ThreadMessagePreviewProps = { message: IThreadMessage; showUserAvatar: boolean; sequential: boolean; -}; +} & ComponentProps; const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: ThreadMessagePreviewProps): ReactElement => { const parentMessage = useParentMessage(message.tmid); @@ -55,23 +55,30 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: const goToThread = useGoToThread(); + const handleThreadClick = () => { + if (!isSelecting) { + if (!sequential) { + return parentMessage.isSuccess && goToThread({ rid: message.rid, tmid: message.tmid, msg: parentMessage.data?._id }); + } + + return goToThread({ rid: message.rid, tmid: message.tmid, msg: message._id }); + } + + return toggleSelected(); + }; + return ( e.code === 'Enter' && handleThreadClick()} isSelected={isSelected} data-qa-selected={isSelected} role='link' + {...props} > {!sequential && ( - goToThread({ rid: message.rid, tmid: message.tmid, msg: parentMessage.data?._id }) - : undefined - } - > + @@ -99,7 +106,7 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: )} - goToThread({ rid: message.rid, tmid: message.tmid, msg: message._id }) : undefined}> + {!isSelecting && showUserAvatar && } {isSelecting && } diff --git a/apps/meteor/client/views/room/Room.tsx b/apps/meteor/client/views/room/Room.tsx index 665adaa3fbe98..a33f762d8b360 100644 --- a/apps/meteor/client/views/room/Room.tsx +++ b/apps/meteor/client/views/room/Room.tsx @@ -1,6 +1,6 @@ -import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { createElement, lazy, memo, Suspense } from 'react'; +import { FocusScope } from 'react-aria'; import { ErrorBoundary } from 'react-error-boundary'; import { ContextualbarSkeleton } from '../../components/Contextualbar'; @@ -17,7 +17,6 @@ import { SelectedMessagesProvider } from './providers/SelectedMessagesProvider'; const UiKitContextualBar = lazy(() => import('./contextualBar/uikit/UiKitContextualBar')); const Room = (): ReactElement => { - const t = useTranslation(); const room = useRoom(); const toolbox = useRoomToolbox(); const contextualBarView = useAppsContextualBar(); @@ -25,30 +24,32 @@ const Room = (): ReactElement => { return ( - } - body={} - aside={ - (toolbox.tab?.tabComponent && ( - - - }>{createElement(toolbox.tab.tabComponent)} - - - )) || - (contextualBarView && ( - - - }> - - - - - )) - } - /> + + } + body={} + aside={ + (toolbox.tab?.tabComponent && ( + + + }>{createElement(toolbox.tab.tabComponent)} + + + )) || + (contextualBarView && ( + + + }> + + + + + )) + } + /> + ); diff --git a/apps/meteor/client/views/room/body/RoomBody.tsx b/apps/meteor/client/views/room/body/RoomBody.tsx index d2722200b2df9..cb3a2a3d8df5e 100644 --- a/apps/meteor/client/views/room/body/RoomBody.tsx +++ b/apps/meteor/client/views/room/body/RoomBody.tsx @@ -35,6 +35,7 @@ import RoomComposer from '../composer/RoomComposer/RoomComposer'; import { useChat } from '../contexts/ChatContext'; import { useRoom, useRoomSubscription, useRoomMessages } from '../contexts/RoomContext'; import { useRoomToolbox } from '../contexts/RoomToolboxContext'; +import { useRoomNavigation } from '../hooks/useRoomNavigation'; import { useScrollMessageList } from '../hooks/useScrollMessageList'; import DropTargetOverlay from './DropTargetOverlay'; import JumpToRecentMessageButton from './JumpToRecentMessageButton'; @@ -531,6 +532,7 @@ const RoomBody = (): ReactElement => { ); useReadMessageWindowEvents(); + const { roomListRef } = useRoomNavigation(); return ( <> @@ -539,7 +541,6 @@ const RoomBody = (): ReactElement => {
@@ -600,7 +601,7 @@ const RoomBody = (): ReactElement => { > -
    +
      {canPreview ? ( <> {hasMorePreviousMessages ? ( diff --git a/apps/meteor/client/views/room/hooks/useRoomNavigation.ts b/apps/meteor/client/views/room/hooks/useRoomNavigation.ts new file mode 100644 index 0000000000000..f30a161824f1b --- /dev/null +++ b/apps/meteor/client/views/room/hooks/useRoomNavigation.ts @@ -0,0 +1,35 @@ +import { type KeyboardEvent, useCallback } from 'react'; +import { useFocusManager } from 'react-aria'; + +const isListItem = (node: EventTarget) => + (node as HTMLElement).getAttribute('role') === 'listitem' || (node as HTMLElement).getAttribute('role') === 'link'; + +export const useRoomNavigation = () => { + const focusManager = useFocusManager(); + + const roomListRef = useCallback( + (node) => { + if (!node) { + return; + } + + const handleKeyDown = (e: KeyboardEvent) => { + if (!isListItem(e.target)) { + return; + } + + switch (e.key) { + case 'ArrowUp': + return focusManager.focusPrevious({ wrap: true, accept: (node) => isListItem(node) }); + case 'ArrowDown': + return focusManager.focusNext({ wrap: true, accept: (node) => isListItem(node) }); + } + }; + + node.addEventListener('keydown', handleKeyDown); + }, + [focusManager], + ); + + return { roomListRef }; +}; From 86e8fa55fc5e20039bb8402007c3d0e01e646c48 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Mon, 29 Jan 2024 17:48:32 -0300 Subject: [PATCH 04/14] chore: tweak --- apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx index 38ac7c2de7a10..2440a940d995a 100644 --- a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx +++ b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx @@ -37,6 +37,7 @@ const EmojiElement = ({ emoji, image, onClick, small = false, ...props }: EmojiE onMouseLeave={handleRemovePreview} onClick={onClick} data-emoji={emoji} + aria-label={emoji} icon={emojiElement} {...props} /> From 691a1d23a33e4992a4acfe8d6b5fdf1e888827a3 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Mon, 29 Jan 2024 17:49:19 -0300 Subject: [PATCH 05/14] feat: `useMessageListNavigation` --- apps/meteor/client/views/room/Room.tsx | 2 +- .../client/views/room/body/RoomBody.tsx | 14 +++- .../room/hooks/useMessageListNavigation.ts | 77 +++++++++++++++++++ .../views/room/hooks/useRoomNavigation.ts | 35 --------- 4 files changed, 89 insertions(+), 39 deletions(-) create mode 100644 apps/meteor/client/views/room/hooks/useMessageListNavigation.ts delete mode 100644 apps/meteor/client/views/room/hooks/useRoomNavigation.ts diff --git a/apps/meteor/client/views/room/Room.tsx b/apps/meteor/client/views/room/Room.tsx index a33f762d8b360..7ec6eab586994 100644 --- a/apps/meteor/client/views/room/Room.tsx +++ b/apps/meteor/client/views/room/Room.tsx @@ -24,7 +24,7 @@ const Room = (): ReactElement => { return ( - + { ); useReadMessageWindowEvents(); - const { roomListRef } = useRoomNavigation(); + const roomListRef = useRef(null); + const { messageListProps } = useMessageListNavigation(roomListRef); return ( <> @@ -601,7 +602,14 @@ const RoomBody = (): ReactElement => { > -
        +
          {canPreview ? ( <> {hasMorePreviousMessages ? ( diff --git a/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts new file mode 100644 index 0000000000000..1f070e9ee7e4c --- /dev/null +++ b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts @@ -0,0 +1,77 @@ +import { createFocusManager } from '@react-aria/focus'; +import type { RefObject, FocusEvent } from 'react'; +import { type KeyboardEvent, useRef } from 'react'; +import { useFocusManager } from 'react-aria'; + +const isListItem = (node: EventTarget) => + (node as HTMLElement).getAttribute('role') === 'listitem' || (node as HTMLElement).getAttribute('role') === 'link'; +const isMessageToolbarAction = (node: EventTarget) => (node as HTMLElement).parentElement?.getAttribute('role') === 'toolbar'; +const isSystemMessage = (node: EventTarget) => (node as HTMLElement).classList.contains('rcx-message-system'); +const isThreadMessage = (node: EventTarget) => (node as HTMLElement).classList.contains('rcx-message-thread'); + +/** + * Custom hook to provide the room navigation by keyboard. + * @param ref - A ref to the message list DOM element. + */ +export const useMessageListNavigation = (ref: RefObject) => { + const lastMessageFocused = useRef(null); + const massageListFocusManager = createFocusManager(ref); + const roomFocusManager = useFocusManager(); + + const handleKeyDown = (e: KeyboardEvent) => { + if (!isListItem(e.target)) { + return; + } + + if (e.key === 'Tab') { + if (e.shiftKey) { + e.preventDefault(); + e.stopPropagation(); + + roomFocusManager.focusFirst({ + from: document.getElementsByClassName('rcx-room-header')[0], + }); + } else if (isThreadMessage(e.target) || isSystemMessage(e.target) || isMessageToolbarAction(e.target)) { + e.preventDefault(); + e.stopPropagation(); + + roomFocusManager.focusNext({ + accept: (node) => node.tagName === 'TEXTAREA', + }); + } + } + + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + if (e.key === 'ArrowUp') { + massageListFocusManager.focusPrevious({ wrap: true, accept: (node) => isListItem(node) }); + } + + if (e.key === 'ArrowDown') { + massageListFocusManager.focusNext({ wrap: true, accept: (node) => isListItem(node) }); + } + + lastMessageFocused.current = document.activeElement as HTMLElement; + } + }; + + const handleOnBlur = (e: FocusEvent) => { + if (!e.currentTarget.contains(e.relatedTarget) && !lastMessageFocused.current) { + lastMessageFocused.current = e.target; + } + }; + + const handleFocus = (e: FocusEvent) => { + if (lastMessageFocused.current && !e.currentTarget.contains(e.relatedTarget) && ref.current?.contains(e.target)) { + lastMessageFocused.current?.focus(); + lastMessageFocused.current = null; + } + }; + + return { + messageListProps: { + onBlurCapture: handleOnBlur, + onFocusCapture: handleFocus, + onKeyDownCapture: handleKeyDown, + }, + }; +}; diff --git a/apps/meteor/client/views/room/hooks/useRoomNavigation.ts b/apps/meteor/client/views/room/hooks/useRoomNavigation.ts deleted file mode 100644 index f30a161824f1b..0000000000000 --- a/apps/meteor/client/views/room/hooks/useRoomNavigation.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { type KeyboardEvent, useCallback } from 'react'; -import { useFocusManager } from 'react-aria'; - -const isListItem = (node: EventTarget) => - (node as HTMLElement).getAttribute('role') === 'listitem' || (node as HTMLElement).getAttribute('role') === 'link'; - -export const useRoomNavigation = () => { - const focusManager = useFocusManager(); - - const roomListRef = useCallback( - (node) => { - if (!node) { - return; - } - - const handleKeyDown = (e: KeyboardEvent) => { - if (!isListItem(e.target)) { - return; - } - - switch (e.key) { - case 'ArrowUp': - return focusManager.focusPrevious({ wrap: true, accept: (node) => isListItem(node) }); - case 'ArrowDown': - return focusManager.focusNext({ wrap: true, accept: (node) => isListItem(node) }); - } - }; - - node.addEventListener('keydown', handleKeyDown); - }, - [focusManager], - ); - - return { roomListRef }; -}; From 5656608f6dede1c1421a85a77b39b16ae6d5aecd Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 15 Feb 2024 12:34:39 -0300 Subject: [PATCH 06/14] chore: `MessageToolbar` props --- .../meteor/client/components/message/toolbar/MessageToolbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx index 47ed4d25f264a..04ef43678f783 100644 --- a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx +++ b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx @@ -111,7 +111,7 @@ const MessageToolbar = ({ }; return ( - + {quickReactionsEnabled && isReactionAllowed && quickReactions.slice(0, 3).map(({ emoji, image }) => { From bcc59b35b0b9d1b9b3b5f91e40a267b28b01ca73 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 15 Feb 2024 12:34:52 -0300 Subject: [PATCH 07/14] feat: add focus on threadMessage --- .../client/components/message/variants/ThreadMessage.tsx | 2 ++ .../contextualBar/Threads/components/ThreadMessageList.tsx | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/meteor/client/components/message/variants/ThreadMessage.tsx b/apps/meteor/client/components/message/variants/ThreadMessage.tsx index 343b56dc54a83..6019c7d040233 100644 --- a/apps/meteor/client/components/message/variants/ThreadMessage.tsx +++ b/apps/meteor/client/components/message/variants/ThreadMessage.tsx @@ -39,6 +39,8 @@ const ThreadMessage = ({ message, sequential, unread, showUserAvatar }: ThreadMe return ( @@ -76,7 +78,7 @@ const ThreadMessageList = ({ mainMessage }: ThreadMessageListProps): ReactElemen onScroll={handleScroll} style={{ scrollBehavior: 'smooth', overflowX: 'hidden' }} > -
            +
              {loading ? (
            • From 6ed3ecefd49d37117d8c4a68ad067a5d9180e779 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 15 Feb 2024 19:44:35 -0300 Subject: [PATCH 08/14] chore: missing translation --- apps/meteor/client/views/room/Room.tsx | 8 +++++++- apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/meteor/client/views/room/Room.tsx b/apps/meteor/client/views/room/Room.tsx index 7ec6eab586994..4d6d7d56f9d5b 100644 --- a/apps/meteor/client/views/room/Room.tsx +++ b/apps/meteor/client/views/room/Room.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { createElement, lazy, memo, Suspense } from 'react'; import { FocusScope } from 'react-aria'; @@ -17,6 +18,7 @@ import { SelectedMessagesProvider } from './providers/SelectedMessagesProvider'; const UiKitContextualBar = lazy(() => import('./contextualBar/uikit/UiKitContextualBar')); const Room = (): ReactElement => { + const t = useTranslation(); const room = useRoom(); const toolbox = useRoomToolbox(); const contextualBarView = useAppsContextualBar(); @@ -27,7 +29,11 @@ const Room = (): ReactElement => { } body={} aside={ diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index d9faf22baf4cf..859b11f7c8c50 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -967,6 +967,7 @@ "Channel_Name_Placeholder": "Please enter channel name...", "Channel_to_listen_on": "Channel to listen on", "Channel_Unarchived": "Channel with name `#%s` has been Unarchived successfully", + "Channel__roomName__": "Channel {{roomName}}.", "Channels": "Channels", "Channels_added": "Channels added sucessfully", "Channels_are_where_your_team_communicate": "Channels are where your team communicate", @@ -1167,6 +1168,7 @@ "Conversation_finished_message": "Conversation Finished Message", "Conversation_finished_text": "Conversation Finished Text", "conversation_with_s": "the conversation with %s", + "Conversation_with__roomName__": "Conversation with {{roomName}}.", "Conversations": "Conversations", "Conversations_per_day": "Conversations per Day", "Convert": "Convert", From 293e2ae0547fddc03c66c03d15c007292953373f Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 15 Feb 2024 19:44:44 -0300 Subject: [PATCH 09/14] chore: TDD --- apps/meteor/tests/e2e/messaging.spec.ts | 39 +++++++++++++++++++ .../tests/e2e/page-objects/home-channel.ts | 4 ++ 2 files changed, 43 insertions(+) diff --git a/apps/meteor/tests/e2e/messaging.spec.ts b/apps/meteor/tests/e2e/messaging.spec.ts index c5099c52b9f1f..30440dd55d82e 100644 --- a/apps/meteor/tests/e2e/messaging.spec.ts +++ b/apps/meteor/tests/e2e/messaging.spec.ts @@ -20,6 +20,45 @@ test.describe.serial('Messaging', () => { await page.goto('/home'); }); + test('should navigate on messages using keyboard', async ({ page }) => { + await poHomeChannel.sidenav.openChat(targetChannel); + await poHomeChannel.content.sendMessage('msg1'); + await poHomeChannel.content.sendMessage('msg2'); + + // move focus to the second message + await page.keyboard.press('Shift+Tab'); + await expect(page.locator('[data-qa-type="message"]').last()).toBeFocused(); + + // move focus to the first typed message + await page.keyboard.press('ArrowUp'); + await expect(page.locator('[data-qa-type="message"]:has-text("msg1")')).toBeFocused(); + + // move focus to the favorite icon + await page.keyboard.press('Shift+Tab'); + await expect(poHomeChannel.roomHeaderFavoriteBtn).toBeFocused(); + + // refocus on the first typed message + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page.locator('[data-qa-type="message"]:has-text("msg1")')).toBeFocused(); + + // TODO: Check why this test doesn't work + // move focus to the message toolbar + // await page.keyboard.press('Tab'); + // await page.keyboard.press('Tab'); + // await page.keyboard.press('ArrowRight'); + // await expect(page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Quote' })).toBeFocused(); + + // move focus to the first system message + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await expect(page.locator('[data-qa="system-message"]').first()).toBeFocused(); + + // move focus to the composer + await page.keyboard.press('Tab'); + await expect(poHomeChannel.composer).toBeFocused(); + }); + test('expect show "hello word" in both contexts (targetChannel)', async ({ browser }) => { await poHomeChannel.sidenav.openChat(targetChannel); const { page } = await createAuxContext(browser, Users.user2); diff --git a/apps/meteor/tests/e2e/page-objects/home-channel.ts b/apps/meteor/tests/e2e/page-objects/home-channel.ts index 278256b7b0b1c..01dcc302d3e0b 100644 --- a/apps/meteor/tests/e2e/page-objects/home-channel.ts +++ b/apps/meteor/tests/e2e/page-objects/home-channel.ts @@ -41,6 +41,10 @@ export class HomeChannel { await this.page.mouse.move(0, 0); } + get composer(): Locator { + return this.page.locator('textarea[name="msg"]'); + } + get composerToolbar(): Locator { return this.page.locator('[role=toolbar][aria-label="Composer Primary Actions"]'); } From cc0bec9506ff047c8dfba2e0bf3aa4ccfc0ee41f Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 15 Feb 2024 22:58:54 -0300 Subject: [PATCH 10/14] ;) --- .../client/views/room/body/RoomBody.tsx | 6 +- .../Threads/components/ThreadMessageList.tsx | 5 +- .../room/hooks/useMessageListNavigation.ts | 125 +++++++++++------- 3 files changed, 81 insertions(+), 55 deletions(-) diff --git a/apps/meteor/client/views/room/body/RoomBody.tsx b/apps/meteor/client/views/room/body/RoomBody.tsx index d0b96a30867b9..2089e288bace9 100644 --- a/apps/meteor/client/views/room/body/RoomBody.tsx +++ b/apps/meteor/client/views/room/body/RoomBody.tsx @@ -532,8 +532,8 @@ const RoomBody = (): ReactElement => { ); useReadMessageWindowEvents(); - const roomListRef = useRef(null); - const { messageListProps } = useMessageListNavigation(roomListRef); + + const { messageListProps, ref } = useMessageListNavigation(); return ( <> @@ -603,7 +603,7 @@ const RoomBody = (): ReactElement => {
                (listScrollRef, listJumpRef); const hideUsernames = useUserPreference('hideUsernames'); const showUserAvatar = !!useUserPreference('displayAvatars'); @@ -69,7 +68,9 @@ const ThreadMessageList = ({ mainMessage }: ThreadMessageListProps): ReactElemen const scrollMessageList = useScrollMessageList(listWrapperScrollRef); const firstUnreadMessageId = useFirstUnreadMessageId(); - const { messageListProps } = useMessageListNavigation(listWrapperScrollRef); + const { messageListProps, ref: navigationListRef } = useMessageListNavigation(); + + const listRef = useMergedRefs(listScrollRef, listJumpRef, navigationListRef); return (
                diff --git a/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts index 1f070e9ee7e4c..5920448e72815 100644 --- a/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts +++ b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts @@ -1,6 +1,5 @@ import { createFocusManager } from '@react-aria/focus'; -import type { RefObject, FocusEvent } from 'react'; -import { type KeyboardEvent, useRef } from 'react'; +import { useCallback } from 'react'; import { useFocusManager } from 'react-aria'; const isListItem = (node: EventTarget) => @@ -13,65 +12,91 @@ const isThreadMessage = (node: EventTarget) => (node as HTMLElement).classList.c * Custom hook to provide the room navigation by keyboard. * @param ref - A ref to the message list DOM element. */ -export const useMessageListNavigation = (ref: RefObject) => { - const lastMessageFocused = useRef(null); - const massageListFocusManager = createFocusManager(ref); +export const useMessageListNavigation = () => { const roomFocusManager = useFocusManager(); - const handleKeyDown = (e: KeyboardEvent) => { - if (!isListItem(e.target)) { - return; - } + const ref = useCallback( + (node: HTMLElement | null) => { + let lastMessageFocused: HTMLElement | null = null; - if (e.key === 'Tab') { - if (e.shiftKey) { - e.preventDefault(); - e.stopPropagation(); + if (!node) { + return; + } + const massageListFocusManager = createFocusManager({ + current: node, + }); - roomFocusManager.focusFirst({ - from: document.getElementsByClassName('rcx-room-header')[0], - }); - } else if (isThreadMessage(e.target) || isSystemMessage(e.target) || isMessageToolbarAction(e.target)) { - e.preventDefault(); - e.stopPropagation(); + node.addEventListener('keydown', (e) => { + if (!e.target) { + return; + } - roomFocusManager.focusNext({ - accept: (node) => node.tagName === 'TEXTAREA', - }); - } - } + if (!isListItem(e.target)) { + return; + } - if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { - if (e.key === 'ArrowUp') { - massageListFocusManager.focusPrevious({ wrap: true, accept: (node) => isListItem(node) }); - } + if (e.key === 'Tab') { + if (e.shiftKey) { + e.preventDefault(); + e.stopPropagation(); - if (e.key === 'ArrowDown') { - massageListFocusManager.focusNext({ wrap: true, accept: (node) => isListItem(node) }); - } + roomFocusManager.focusFirst({ + from: document.getElementsByClassName('rcx-room-header')[0], + }); + } else if (isThreadMessage(e.target) || isSystemMessage(e.target) || isMessageToolbarAction(e.target)) { + e.preventDefault(); + e.stopPropagation(); - lastMessageFocused.current = document.activeElement as HTMLElement; - } - }; + roomFocusManager.focusNext({ + accept: (node) => node.tagName === 'TEXTAREA', + }); + } + } - const handleOnBlur = (e: FocusEvent) => { - if (!e.currentTarget.contains(e.relatedTarget) && !lastMessageFocused.current) { - lastMessageFocused.current = e.target; - } - }; + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + if (e.key === 'ArrowUp') { + massageListFocusManager.focusPrevious({ wrap: true, accept: (node) => isListItem(node) }); + } - const handleFocus = (e: FocusEvent) => { - if (lastMessageFocused.current && !e.currentTarget.contains(e.relatedTarget) && ref.current?.contains(e.target)) { - lastMessageFocused.current?.focus(); - lastMessageFocused.current = null; - } - }; + if (e.key === 'ArrowDown') { + massageListFocusManager.focusNext({ wrap: true, accept: (node) => isListItem(node) }); + } - return { - messageListProps: { - onBlurCapture: handleOnBlur, - onFocusCapture: handleFocus, - onKeyDownCapture: handleKeyDown, + lastMessageFocused = document.activeElement as HTMLElement; + } + }); + node.addEventListener( + 'blur', + (e) => { + if (!(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)) { + return; + } + + if (!e.currentTarget.contains(e.relatedTarget) && !lastMessageFocused) { + lastMessageFocused = e.target as HTMLElement; + } + }, + { capture: true }, + ); + node.addEventListener( + 'focus', + (e) => { + if (!(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)) { + return; + } + if (lastMessageFocused && !e.currentTarget.contains(e.relatedTarget) && node.contains(e.target as HTMLElement)) { + lastMessageFocused?.focus(); + lastMessageFocused = null; + } + }, + { capture: true }, + ); }, + [roomFocusManager], + ); + + return { + ref, + messageListProps: {}, }; }; From 06434bb541ee2e627fdec1a875bebb35bb87ec7e Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 16 Feb 2024 12:40:45 -0300 Subject: [PATCH 11/14] chore: tweaks --- .../meteor/client/views/room/body/RoomBody.tsx | 5 ++--- .../Threads/components/ThreadMessageList.tsx | 4 ++-- .../room/hooks/useMessageListNavigation.ts | 18 ++++++++++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/apps/meteor/client/views/room/body/RoomBody.tsx b/apps/meteor/client/views/room/body/RoomBody.tsx index 2089e288bace9..4ec51aa67fdaa 100644 --- a/apps/meteor/client/views/room/body/RoomBody.tsx +++ b/apps/meteor/client/views/room/body/RoomBody.tsx @@ -533,7 +533,7 @@ const RoomBody = (): ReactElement => { useReadMessageWindowEvents(); - const { messageListProps, ref } = useMessageListNavigation(); + const { messageListRef, messageListProps } = useMessageListNavigation(); return ( <> @@ -603,9 +603,8 @@ const RoomBody = (): ReactElement => {
                  (listScrollRef, listJumpRef, navigationListRef); + const listRef = useMergedRefs(listScrollRef, listJumpRef, messageListRef); return (
                  diff --git a/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts index 5920448e72815..f446e867531d6 100644 --- a/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts +++ b/apps/meteor/client/views/room/hooks/useMessageListNavigation.ts @@ -1,7 +1,12 @@ import { createFocusManager } from '@react-aria/focus'; +import type { RefCallback } from 'react'; import { useCallback } from 'react'; import { useFocusManager } from 'react-aria'; +type MessageListProps = { + 'aria-orientation': 'vertical' | 'horizontal'; +}; + const isListItem = (node: EventTarget) => (node as HTMLElement).getAttribute('role') === 'listitem' || (node as HTMLElement).getAttribute('role') === 'link'; const isMessageToolbarAction = (node: EventTarget) => (node as HTMLElement).parentElement?.getAttribute('role') === 'toolbar'; @@ -12,16 +17,17 @@ const isThreadMessage = (node: EventTarget) => (node as HTMLElement).classList.c * Custom hook to provide the room navigation by keyboard. * @param ref - A ref to the message list DOM element. */ -export const useMessageListNavigation = () => { +export const useMessageListNavigation = (): { messageListRef: RefCallback; messageListProps: MessageListProps } => { const roomFocusManager = useFocusManager(); - const ref = useCallback( + const messageListRef = useCallback( (node: HTMLElement | null) => { let lastMessageFocused: HTMLElement | null = null; if (!node) { return; } + const massageListFocusManager = createFocusManager({ current: node, }); @@ -65,6 +71,7 @@ export const useMessageListNavigation = () => { lastMessageFocused = document.activeElement as HTMLElement; } }); + node.addEventListener( 'blur', (e) => { @@ -78,6 +85,7 @@ export const useMessageListNavigation = () => { }, { capture: true }, ); + node.addEventListener( 'focus', (e) => { @@ -96,7 +104,9 @@ export const useMessageListNavigation = () => { ); return { - ref, - messageListProps: {}, + messageListRef, + messageListProps: { + 'aria-orientation': 'vertical', + }, }; }; From 15fc3dc7962ee7a7dcc42ff734162a85d3ce45d5 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 16 Feb 2024 12:41:05 -0300 Subject: [PATCH 12/14] chore: e2e test --- .../components/message/toolbar/MessageToolbar.tsx | 2 +- .../packages/rocketchat-i18n/i18n/en.i18n.json | 1 + apps/meteor/tests/e2e/messaging.spec.ts | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx index 04ef43678f783..dd26dde17ecf7 100644 --- a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx +++ b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx @@ -111,7 +111,7 @@ const MessageToolbar = ({ }; return ( - + {quickReactionsEnabled && isReactionAllowed && quickReactions.slice(0, 3).map(({ emoji, image }) => { diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 859b11f7c8c50..60ffa84825f0a 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -6278,6 +6278,7 @@ "Remove_RocketChat_Watermark": "Remove Rocket.Chat watermark", "High_scalabaility": "High scalabaility", "Premium_and_unlimited_apps": "Premium and unlimited apps", + "Message_actions": "Message actions", "Message_audit": "Message auditing", "Premium_omnichannel_capabilities": "Premium omnichannel capabilities", "Video_call_manager": "Video call manager", diff --git a/apps/meteor/tests/e2e/messaging.spec.ts b/apps/meteor/tests/e2e/messaging.spec.ts index 30440dd55d82e..f71c1dd04b8c4 100644 --- a/apps/meteor/tests/e2e/messaging.spec.ts +++ b/apps/meteor/tests/e2e/messaging.spec.ts @@ -42,15 +42,15 @@ test.describe.serial('Messaging', () => { await page.keyboard.press('Tab'); await expect(page.locator('[data-qa-type="message"]:has-text("msg1")')).toBeFocused(); - // TODO: Check why this test doesn't work // move focus to the message toolbar - // await page.keyboard.press('Tab'); - // await page.keyboard.press('Tab'); - // await page.keyboard.press('ArrowRight'); - // await expect(page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Quote' })).toBeFocused(); + await page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Add reaction' }).waitFor(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Add reaction' })).toBeFocused(); // move focus to the first system message - await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Tab'); await page.keyboard.press('ArrowDown'); await expect(page.locator('[data-qa="system-message"]').first()).toBeFocused(); From 820526fbbff169e4e59d40a67c1fc1b9a2836c0b Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 16 Feb 2024 12:42:52 -0300 Subject: [PATCH 13/14] chore: changeset --- .changeset/spicy-wombats-shout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spicy-wombats-shout.md diff --git a/.changeset/spicy-wombats-shout.md b/.changeset/spicy-wombats-shout.md new file mode 100644 index 0000000000000..d84a815241dce --- /dev/null +++ b/.changeset/spicy-wombats-shout.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +Introduces message navigability, allowing users to navigate on messages through keyboard From 1b59c1e6d265e2d82dd1865c73ac40e6bb045320 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Mon, 19 Feb 2024 14:33:49 -0300 Subject: [PATCH 14/14] chore: bump fuselage --- apps/meteor/package.json | 2 +- ee/packages/ui-theming/package.json | 2 +- packages/fuselage-ui-kit/package.json | 2 +- packages/gazzodown/package.json | 2 +- packages/ui-avatar/package.json | 2 +- packages/ui-client/package.json | 2 +- packages/ui-composer/package.json | 2 +- packages/ui-video-conf/package.json | 2 +- packages/uikit-playground/package.json | 2 +- yarn.lock | 50 +++++++------------------- 10 files changed, 22 insertions(+), 46 deletions(-) diff --git a/apps/meteor/package.json b/apps/meteor/package.json index 35430565ce101..6e1b6a0b3836f 100644 --- a/apps/meteor/package.json +++ b/apps/meteor/package.json @@ -240,7 +240,7 @@ "@rocket.chat/favicon": "workspace:^", "@rocket.chat/forked-matrix-appservice-bridge": "^4.0.2", "@rocket.chat/forked-matrix-bot-sdk": "^0.6.0-beta.3", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/fuselage-polyfills": "~0.31.25", "@rocket.chat/fuselage-toastbar": "~0.31.25", diff --git a/ee/packages/ui-theming/package.json b/ee/packages/ui-theming/package.json index abd9bdd62a781..87cab03460dfc 100644 --- a/ee/packages/ui-theming/package.json +++ b/ee/packages/ui-theming/package.json @@ -4,7 +4,7 @@ "private": true, "devDependencies": { "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/icons": "^0.33.0", "@rocket.chat/ui-contexts": "workspace:~", diff --git a/packages/fuselage-ui-kit/package.json b/packages/fuselage-ui-kit/package.json index 72f61f197aabb..599e8476175b5 100644 --- a/packages/fuselage-ui-kit/package.json +++ b/packages/fuselage-ui-kit/package.json @@ -63,7 +63,7 @@ "@babel/preset-typescript": "~7.22.15", "@rocket.chat/apps-engine": "1.41.0", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/fuselage-polyfills": "~0.31.25", "@rocket.chat/icons": "^0.33.0", diff --git a/packages/gazzodown/package.json b/packages/gazzodown/package.json index 8ba6c12023955..eafeb069d0d34 100644 --- a/packages/gazzodown/package.json +++ b/packages/gazzodown/package.json @@ -6,7 +6,7 @@ "@babel/core": "~7.22.20", "@rocket.chat/core-typings": "workspace:^", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-tokens": "~0.32.0", "@rocket.chat/message-parser": "~0.31.28", "@rocket.chat/styled": "~0.31.25", diff --git a/packages/ui-avatar/package.json b/packages/ui-avatar/package.json index 2eaa0106ce3c9..853178aae3a96 100644 --- a/packages/ui-avatar/package.json +++ b/packages/ui-avatar/package.json @@ -4,7 +4,7 @@ "private": true, "devDependencies": { "@babel/core": "~7.22.20", - "@rocket.chat/fuselage": "^0.41.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/ui-contexts": "workspace:^", "@types/babel__core": "~7.20.3", "@types/react": "~17.0.69", diff --git a/packages/ui-client/package.json b/packages/ui-client/package.json index c931427a07230..b7cbe0932812c 100644 --- a/packages/ui-client/package.json +++ b/packages/ui-client/package.json @@ -6,7 +6,7 @@ "@babel/core": "~7.22.20", "@react-aria/toolbar": "^3.0.0-beta.1", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/icons": "^0.33.0", "@rocket.chat/mock-providers": "workspace:^", diff --git a/packages/ui-composer/package.json b/packages/ui-composer/package.json index 10da988ad59fa..a1fbe39a61423 100644 --- a/packages/ui-composer/package.json +++ b/packages/ui-composer/package.json @@ -6,7 +6,7 @@ "@babel/core": "~7.22.20", "@react-aria/toolbar": "^3.0.0-beta.1", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/icons": "^0.33.0", "@storybook/addon-actions": "~6.5.16", "@storybook/addon-docs": "~6.5.16", diff --git a/packages/ui-video-conf/package.json b/packages/ui-video-conf/package.json index 838b667641523..cd0327d6a0518 100644 --- a/packages/ui-video-conf/package.json +++ b/packages/ui-video-conf/package.json @@ -6,7 +6,7 @@ "@babel/core": "~7.22.20", "@rocket.chat/css-in-js": "~0.31.25", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/icons": "^0.33.0", "@rocket.chat/styled": "~0.31.25", diff --git a/packages/uikit-playground/package.json b/packages/uikit-playground/package.json index a7ba568e7367a..9b34b125df9ba 100644 --- a/packages/uikit-playground/package.json +++ b/packages/uikit-playground/package.json @@ -15,7 +15,7 @@ "@codemirror/tooltip": "^0.19.16", "@lezer/highlight": "^1.1.6", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.45.0", + "@rocket.chat/fuselage": "^0.47.0", "@rocket.chat/fuselage-hooks": "^0.33.0", "@rocket.chat/fuselage-polyfills": "~0.31.25", "@rocket.chat/fuselage-toastbar": "^0.31.25", diff --git a/yarn.lock b/yarn.lock index 7c88ca377d17e..c1d3600c0f656 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9304,7 +9304,7 @@ __metadata: "@babel/preset-typescript": ~7.22.15 "@rocket.chat/apps-engine": 1.41.0 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/gazzodown": "workspace:^" @@ -9359,9 +9359,9 @@ __metadata: languageName: unknown linkType: soft -"@rocket.chat/fuselage@npm:^0.41.0": - version: 0.41.0 - resolution: "@rocket.chat/fuselage@npm:0.41.0" +"@rocket.chat/fuselage@npm:^0.47.0": + version: 0.47.0 + resolution: "@rocket.chat/fuselage@npm:0.47.0" dependencies: "@rocket.chat/css-in-js": ^0.31.25 "@rocket.chat/css-supports": ^0.31.25 @@ -9379,31 +9379,7 @@ __metadata: react: ^17.0.2 react-dom: ^17.0.2 react-virtuoso: 1.2.4 - checksum: 8ee33c5626ff7fb8970714696332efc723ca0793470d0b4da9a169aa6b2528ec75068d775e8f149dd3a1ea401ff0240be892022b64bd80e5bd4fc04349e0c0aa - languageName: node - linkType: hard - -"@rocket.chat/fuselage@npm:^0.45.0": - version: 0.45.0 - resolution: "@rocket.chat/fuselage@npm:0.45.0" - dependencies: - "@rocket.chat/css-in-js": ^0.31.25 - "@rocket.chat/css-supports": ^0.31.25 - "@rocket.chat/fuselage-tokens": ^0.32.0 - "@rocket.chat/memo": ^0.31.25 - "@rocket.chat/styled": ^0.31.25 - invariant: ^2.2.4 - react-aria: ~3.23.1 - react-keyed-flatten-children: ^1.3.0 - react-stately: ~3.17.0 - peerDependencies: - "@rocket.chat/fuselage-hooks": "*" - "@rocket.chat/fuselage-polyfills": "*" - "@rocket.chat/icons": "*" - react: ^17.0.2 - react-dom: ^17.0.2 - react-virtuoso: 1.2.4 - checksum: 84611983e263c0016687100c342c4256d6aff2a221c9d7ce86ecd7d49fd1c5fb5cb4d7d79aedd53fd4a1b29ad89efb4bb50357a8e24997822fb249fa78a5ac70 + checksum: 4ca06bd467db88b5c4c3eed70bbd8879923cfbe7f5a92bd934ed0f800b37825592d84753e124a3f2c70d4e9d82bf5dac6bc2735ea93ccfa26fddc6ab49ea8094 languageName: node linkType: hard @@ -9414,7 +9390,7 @@ __metadata: "@babel/core": ~7.22.20 "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-tokens": ~0.32.0 "@rocket.chat/message-parser": ~0.31.28 "@rocket.chat/styled": ~0.31.25 @@ -9747,7 +9723,7 @@ __metadata: "@rocket.chat/favicon": "workspace:^" "@rocket.chat/forked-matrix-appservice-bridge": ^4.0.2 "@rocket.chat/forked-matrix-bot-sdk": ^0.6.0-beta.3 - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/fuselage-toastbar": ~0.31.25 @@ -10605,7 +10581,7 @@ __metadata: resolution: "@rocket.chat/ui-avatar@workspace:packages/ui-avatar" dependencies: "@babel/core": ~7.22.20 - "@rocket.chat/fuselage": ^0.41.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/ui-contexts": "workspace:^" "@types/babel__core": ~7.20.3 "@types/react": ~17.0.69 @@ -10631,7 +10607,7 @@ __metadata: "@babel/core": ~7.22.20 "@react-aria/toolbar": ^3.0.0-beta.1 "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/icons": ^0.33.0 "@rocket.chat/mock-providers": "workspace:^" @@ -10684,7 +10660,7 @@ __metadata: "@babel/core": ~7.22.20 "@react-aria/toolbar": ^3.0.0-beta.1 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/icons": ^0.33.0 "@storybook/addon-actions": ~6.5.16 "@storybook/addon-docs": ~6.5.16 @@ -10776,7 +10752,7 @@ __metadata: resolution: "@rocket.chat/ui-theming@workspace:ee/packages/ui-theming" dependencies: "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/icons": ^0.33.0 "@rocket.chat/ui-contexts": "workspace:~" @@ -10819,7 +10795,7 @@ __metadata: "@rocket.chat/css-in-js": ~0.31.25 "@rocket.chat/emitter": ~0.31.25 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/icons": ^0.33.0 "@rocket.chat/styled": ~0.31.25 @@ -10864,7 +10840,7 @@ __metadata: "@codemirror/tooltip": ^0.19.16 "@lezer/highlight": ^1.1.6 "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.45.0 + "@rocket.chat/fuselage": ^0.47.0 "@rocket.chat/fuselage-hooks": ^0.33.0 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/fuselage-toastbar": ^0.31.25