From f3411f7abf30111fd95bdbdc6cefa6ec3ad0685b Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Wed, 4 Feb 2026 12:38:16 +0530 Subject: [PATCH 1/8] feat: add button component implementation --- .../AudioRecorder/AudioRecorder.tsx | 36 ++-- .../AudioRecorder/AudioRecordingButton.tsx | 11 +- .../components/InputButtons/AttachButton.tsx | 21 +- .../OutputButtons/CooldownTimer.tsx | 35 +-- .../components/OutputButtons/EditButton.tsx | 20 +- .../components/OutputButtons/SendButton.tsx | 20 +- .../MessageList/ScrollToBottomButton.tsx | 62 ++---- package/src/components/ui/Avatar/index.ts | 1 + package/src/components/ui/Button/Button.tsx | 201 ++++++++++++++++++ package/src/components/ui/Button/constants.ts | 22 ++ .../ui/Button/hooks/useButtonStyles.ts | 121 +++++++++++ package/src/components/ui/Button/index.ts | 1 + package/src/components/ui/IconButton.tsx | 119 ----------- package/src/components/ui/index.ts | 2 +- 14 files changed, 419 insertions(+), 253 deletions(-) create mode 100644 package/src/components/ui/Button/Button.tsx create mode 100644 package/src/components/ui/Button/constants.ts create mode 100644 package/src/components/ui/Button/hooks/useButtonStyles.ts create mode 100644 package/src/components/ui/Button/index.ts delete mode 100644 package/src/components/ui/IconButton.tsx diff --git a/package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx b/package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx index 1ddcefd811..3b0ebf2dec 100644 --- a/package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx +++ b/package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx @@ -5,7 +5,7 @@ import Animated from 'react-native-reanimated'; import dayjs from 'dayjs'; -import { IconButton } from '../../../../components/ui'; +import { Button } from '../../../../components/ui'; import { MessageInputContextValue, useMessageInputContext, @@ -46,20 +46,20 @@ const StopRecording = ({ const { theme: { semantics }, } = useTheme(); - const onStopVoiceRecording = () => { NativeHandlers.triggerHaptic('impactMedium'); stopVoiceRecordingHandler(); }; return ( - ); }; @@ -77,11 +77,12 @@ const UploadRecording = ({ }; return ( - ); @@ -97,12 +98,13 @@ const DeleteRecording = ({ deleteVoiceRecordingHandler(); }; return ( - ); }; diff --git a/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx b/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx index 430dd868a3..a6414f2239 100644 --- a/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +++ b/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx @@ -14,7 +14,6 @@ import Animated, { withSpring, } from 'react-native-reanimated'; -import { IconButton } from '../../../../components/ui/IconButton'; import { useActiveAudioPlayer } from '../../../../contexts/audioPlayerContext/AudioPlayerContext'; import { MessageInputContextValue, @@ -26,6 +25,7 @@ import { useStateStore } from '../../../../hooks/useStateStore'; import { NewMic } from '../../../../icons/NewMic'; import { NativeHandlers } from '../../../../native'; import { AudioRecorderManagerState } from '../../../../state-store/audio-recorder-manager'; +import { Button } from '../../../ui'; export type AudioRecordingButtonPropsWithContext = Pick< MessageInputContextValue, @@ -209,15 +209,16 @@ export const AudioRecordingButtonWithContext = (props: AudioRecordingButtonProps return ( - diff --git a/package/src/components/MessageInput/components/InputButtons/AttachButton.tsx b/package/src/components/MessageInput/components/InputButtons/AttachButton.tsx index 9f8640be40..a5441327ec 100644 --- a/package/src/components/MessageInput/components/InputButtons/AttachButton.tsx +++ b/package/src/components/MessageInput/components/InputButtons/AttachButton.tsx @@ -9,9 +9,8 @@ import { MessageInputContextValue, useMessageInputContext, } from '../../../../contexts/messageInputContext/MessageInputContext'; -import { useTheme } from '../../../../contexts/themeContext/ThemeContext'; import { NewPlus } from '../../../../icons/NewPlus'; -import { IconButton } from '../../../ui/IconButton'; +import { Button } from '../../../ui/'; import { NativeAttachmentPicker } from '../NativeAttachmentPicker'; type AttachButtonPropsWithContext = Pick< @@ -35,11 +34,6 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => { selectedPicker, toggleAttachmentPicker, } = props; - const { - theme: { - messageInput: { attachButton }, - }, - } = useTheme(); const onAttachButtonLayout = (event: LayoutChangeEvent) => { const layout = event.nativeEvent.layout; @@ -82,15 +76,16 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => { return ( <> - {showAttachButtonPicker ? ( { const { seconds } = props; - const { - theme: { - messageInput: { - cooldownTimer: { text }, - }, - }, - } = useTheme(); - - const icon = useCallback(() => { - return ( - - {seconds} - - ); - }, [seconds, text]); return ( - ); }; - -const styles = StyleSheet.create({ - text: { color: '#B8BEC4', fontSize: 16, fontWeight: '600' }, -}); diff --git a/package/src/components/MessageInput/components/OutputButtons/EditButton.tsx b/package/src/components/MessageInput/components/OutputButtons/EditButton.tsx index 48adc924f5..56673eb5e9 100644 --- a/package/src/components/MessageInput/components/OutputButtons/EditButton.tsx +++ b/package/src/components/MessageInput/components/OutputButtons/EditButton.tsx @@ -4,9 +4,8 @@ import { MessageInputContextValue, useMessageInputContext, } from '../../../../contexts/messageInputContext/MessageInputContext'; -import { useTheme } from '../../../../contexts/themeContext/ThemeContext'; import { NewTick } from '../../../../icons/NewTick'; -import { IconButton } from '../../../ui/IconButton'; +import { Button } from '../../../ui'; export type EditButtonProps = Partial> & { /** Disables the button */ @@ -18,12 +17,6 @@ export const EditButton = (props: EditButtonProps) => { const { sendMessage: sendMessageFromContext } = useMessageInputContext(); const sendMessage = propsSendMessage || sendMessageFromContext; - const { - theme: { - messageInput: { editButton }, - }, - } = useTheme(); - const onPressHandler = useCallback(() => { if (disabled) { return; @@ -32,13 +25,14 @@ export const EditButton = (props: EditButtonProps) => { }, [disabled, sendMessage]); return ( - ); diff --git a/package/src/components/MessageInput/components/OutputButtons/SendButton.tsx b/package/src/components/MessageInput/components/OutputButtons/SendButton.tsx index b0ccabad26..c48222d51c 100644 --- a/package/src/components/MessageInput/components/OutputButtons/SendButton.tsx +++ b/package/src/components/MessageInput/components/OutputButtons/SendButton.tsx @@ -4,9 +4,8 @@ import { MessageInputContextValue, useMessageInputContext, } from '../../../../contexts/messageInputContext/MessageInputContext'; -import { useTheme } from '../../../../contexts/themeContext/ThemeContext'; import { SendRight } from '../../../../icons/SendRight'; -import { IconButton } from '../../../ui/IconButton'; +import { Button } from '../../../ui'; export type SendButtonProps = Partial> & { /** Disables the button */ @@ -18,12 +17,6 @@ export const SendButton = (props: SendButtonProps) => { const { sendMessage: sendMessageFromContext } = useMessageInputContext(); const sendMessage = propsSendMessage || sendMessageFromContext; - const { - theme: { - messageInput: { sendButton }, - }, - } = useTheme(); - const onPressHandler = useCallback(() => { if (disabled) { return; @@ -32,14 +25,15 @@ export const SendButton = (props: SendButtonProps) => { }, [disabled, sendMessage]); return ( - ); }; diff --git a/package/src/components/MessageList/ScrollToBottomButton.tsx b/package/src/components/MessageList/ScrollToBottomButton.tsx index c8614c1656..55f81acfd0 100644 --- a/package/src/components/MessageList/ScrollToBottomButton.tsx +++ b/package/src/components/MessageList/ScrollToBottomButton.tsx @@ -1,23 +1,9 @@ import React from 'react'; -import { StyleSheet, View } from 'react-native'; import Animated, { ZoomIn, ZoomOut } from 'react-native-reanimated'; -import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { NewDown } from '../../icons/NewDown'; -import { BadgeNotification } from '../ui/BadgeNotification'; -import { IconButton } from '../ui/IconButton'; - -const styles = StyleSheet.create({ - unreadCountNotificationContainer: { - position: 'absolute', - right: 0, - top: 0, - }, - container: { - padding: 4, - }, -}); +import { Button } from '../ui/Button'; export type ScrollToBottomButtonProps = { /** onPress handler */ @@ -30,40 +16,28 @@ export type ScrollToBottomButtonProps = { export const ScrollToBottomButton = (props: ScrollToBottomButtonProps) => { const { onPress, showNotification = true, unreadCount } = props; - const { - theme: { - messageList: { - scrollToBottomButton: { container }, - }, - }, - } = useTheme(); - if (!showNotification) { return null; } return ( - - - - - - {unreadCount ? ( - - ) : null} - - + +