diff --git a/package/src/components/MessageInput/MessageComposer.tsx b/package/src/components/MessageInput/MessageComposer.tsx
index 4e74adab7f..fb96e4895a 100644
--- a/package/src/components/MessageInput/MessageComposer.tsx
+++ b/package/src/components/MessageInput/MessageComposer.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo } from 'react';
-import { Modal, StyleSheet, View } from 'react-native';
+import { StyleSheet, View } from 'react-native';
-import { GestureHandlerRootView } from 'react-native-gesture-handler';
import Animated, {
Extrapolation,
interpolate,
@@ -52,9 +51,9 @@ import { MessageInputHeightState } from '../../state-store/message-input-height-
import { primitives } from '../../theme';
import { transitions } from '../../utils/animations/transitions';
import { type TextInputOverrideComponent } from '../AutoCompleteInput/AutoCompleteInput';
+import { PollModal } from '../Poll/components/PollModal';
import { CreatePoll } from '../Poll/CreatePollContent';
import { PortalWhileClosingView } from '../UIComponents/PortalWhileClosingView';
-import { SafeAreaViewWrapper } from '../UIComponents/SafeAreaViewWrapper';
const useStyles = () => {
const {
@@ -67,16 +66,6 @@ const useStyles = () => {
flexShrink: 1,
minWidth: 0,
},
- pollModalWrapper: {
- alignItems: 'center',
- flex: 1,
- justifyContent: 'center',
- backgroundColor: semantics.backgroundCoreElevation1,
- },
- pollSafeArea: {
- flex: 1,
- backgroundColor: semantics.backgroundCoreElevation1,
- },
container: {
alignItems: 'center',
flexDirection: 'row',
@@ -457,23 +446,13 @@ const MessageComposerWithContext = (props: MessageComposerPropsWithContext) => {
{showPollCreationDialog ? (
-
-
-
-
-
-
-
-
-
+
+
+
) : null}
);
diff --git a/package/src/components/Poll/components/CreatePollHeader.tsx b/package/src/components/Poll/components/CreatePollHeader.tsx
index 33c91a4e5e..fe5d31086b 100644
--- a/package/src/components/Poll/components/CreatePollHeader.tsx
+++ b/package/src/components/Poll/components/CreatePollHeader.tsx
@@ -4,7 +4,7 @@ import { StyleSheet, Text, View } from 'react-native';
import { useTheme } from '../../../contexts/themeContext/ThemeContext';
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
import { Check, IconProps } from '../../../icons';
-import { ArrowLeft } from '../../../icons/arrow-left';
+import { Cross } from '../../../icons/xmark-1';
import { primitives } from '../../../theme';
import { Button } from '../../ui';
import { useCanCreatePoll } from '../hooks/useCanCreatePoll';
@@ -43,9 +43,16 @@ export const CreatePollHeader = ({
const renderSendPollIcon = useCallback(
(props: IconProps) => {
- return ;
+ return (
+
+ );
},
- [semantics.textOnAccent],
+ [canCreatePoll, semantics.textOnAccent, semantics.textDisabled],
);
return (
@@ -54,9 +61,9 @@ export const CreatePollHeader = ({
accessibilityLabelKey='a11y/Close poll creation'
variant='secondary'
onPress={onBackPressHandler}
- type='ghost'
+ type='outline'
size='md'
- LeadingIcon={ArrowLeft}
+ LeadingIcon={Cross}
iconOnly
/>
diff --git a/package/src/components/Poll/components/PollButtons.tsx b/package/src/components/Poll/components/PollButtons.tsx
index 2fbb4298f1..cde38d1ffc 100644
--- a/package/src/components/Poll/components/PollButtons.tsx
+++ b/package/src/components/Poll/components/PollButtons.tsx
@@ -1,10 +1,10 @@
import React, { useCallback, useMemo } from 'react';
-import { Modal, StyleSheet, View } from 'react-native';
-import { GestureHandlerRootView } from 'react-native-gesture-handler';
+import { StyleSheet, View } from 'react-native';
import { GenericPollButton, PollButtonProps } from './Button';
import { PollAnswersList } from './PollAnswersList';
import { PollInputDialog } from './PollInputDialog';
+import { PollModal } from './PollModal';
import { PollModalHeader } from './PollModalHeader';
import { PollAllOptions } from './PollOption';
import { PollResults } from './PollResults';
@@ -12,7 +12,6 @@ import { PollResults } from './PollResults';
import { useChatContext, usePollContext, useTheme, useTranslationContext } from '../../../contexts';
import { primitives } from '../../../theme';
import { defaultPollOptionCount } from '../../../utils/constants';
-import { SafeAreaViewWrapper } from '../../UIComponents/SafeAreaViewWrapper';
import {
useAddCommentOpen,
useAllCommentsOpen,
@@ -51,14 +50,10 @@ export const ViewResultsButton = (props: PollButtonProps) => {
type='outline'
/>
{showResults ? (
-
-
-
-
-
-
-
-
+
+
+
+
) : null}
>
);
@@ -81,8 +76,6 @@ export const ShowAllOptionsButton = (props: PollButtonProps) => {
openAllOptions();
}, [message, onPress, openAllOptions, poll]);
- const styles = useStyles();
-
return (
<>
{options && options.length > defaultPollOptionCount ? (
@@ -92,14 +85,10 @@ export const ShowAllOptionsButton = (props: PollButtonProps) => {
/>
) : null}
{showAllOptions ? (
-
-
-
-
-
-
-
-
+
+
+
+
) : null}
>
);
@@ -122,8 +111,6 @@ export const ShowAllCommentsButton = (props: PollButtonProps) => {
openAllComments();
}, [message, onPress, openAllComments, poll]);
- const styles = useStyles();
-
return (
<>
{answersCount && answersCount > 0 ? (
@@ -133,14 +120,10 @@ export const ShowAllCommentsButton = (props: PollButtonProps) => {
/>
) : null}
{showAnswers ? (
-
-
-
-
-
-
-
-
+
+
+
+
) : null}
>
);
@@ -254,9 +237,6 @@ const useStyles = () => {
return useMemo(() => {
return StyleSheet.create({
buttonsContainer: { gap: primitives.spacingXs },
- modalRoot: {
- flex: 1,
- },
endVoteButton: {
borderColor: isPollCreatedByClient
? semantics.chatBorderOnChatOutgoing
@@ -267,10 +247,6 @@ const useStyles = () => {
? semantics.chatBorderOnChatOutgoing
: semantics.chatBorderOnChatIncoming,
},
- safeArea: {
- backgroundColor: semantics.backgroundCoreElevation1,
- flex: 1,
- },
});
}, [semantics, isPollCreatedByClient]);
};
diff --git a/package/src/components/Poll/components/PollInputDialog.tsx b/package/src/components/Poll/components/PollInputDialog.tsx
index 2099aed082..dd74ebe8ce 100644
--- a/package/src/components/Poll/components/PollInputDialog.tsx
+++ b/package/src/components/Poll/components/PollInputDialog.tsx
@@ -72,19 +72,11 @@ export const PollInputDialog = ({
/>
-
@@ -112,8 +112,8 @@ const useStyles = () => {
return useMemo(
() =>
StyleSheet.create({
- button: { flex: 1, width: undefined, ...button },
- buttonContainer: { flexDirection: 'row', gap: primitives.spacingXs },
+ button: { width: undefined, ...button },
+ buttonContainer: { gap: primitives.spacingXs },
container: {
backgroundColor: semantics.backgroundCoreElevation1,
borderRadius: primitives.radiusXl,
@@ -132,7 +132,7 @@ const useStyles = () => {
input: {
alignItems: 'center',
borderColor: semantics.borderUtilityActive,
- borderRadius: primitives.radiusMd,
+ borderRadius: primitives.radiusLg,
borderWidth: 1,
fontSize: primitives.typographyFontSizeMd,
padding: primitives.spacingSm,
diff --git a/package/src/components/Poll/components/PollModal.tsx b/package/src/components/Poll/components/PollModal.tsx
new file mode 100644
index 0000000000..4d995fce0f
--- /dev/null
+++ b/package/src/components/Poll/components/PollModal.tsx
@@ -0,0 +1,55 @@
+import React, { PropsWithChildren, useMemo } from 'react';
+import { Modal, ModalProps, StyleSheet } from 'react-native';
+import { GestureHandlerRootView } from 'react-native-gesture-handler';
+
+import { useTheme } from '../../../contexts';
+import { SafeAreaViewWrapper } from '../../UIComponents/SafeAreaViewWrapper';
+
+export type PollModalProps = PropsWithChildren<{
+ animationType?: ModalProps['animationType'];
+ onRequestClose?: () => void;
+ visible?: boolean;
+}>;
+
+export const PollModal = ({
+ animationType = 'slide',
+ children,
+ onRequestClose,
+ visible,
+}: PollModalProps) => {
+ const styles = useStyles();
+
+ return (
+
+
+ {children}
+
+
+ );
+};
+
+const useStyles = () => {
+ const {
+ theme: { semantics },
+ } = useTheme();
+ return useMemo(
+ () =>
+ StyleSheet.create({
+ root: {
+ flex: 1,
+ },
+ safeArea: {
+ flex: 1,
+ backgroundColor: semantics.backgroundCoreElevation1,
+ },
+ }),
+ [semantics],
+ );
+};
diff --git a/package/src/components/Poll/components/PollModalHeader.tsx b/package/src/components/Poll/components/PollModalHeader.tsx
index ed4d57e54a..312be77ebf 100644
--- a/package/src/components/Poll/components/PollModalHeader.tsx
+++ b/package/src/components/Poll/components/PollModalHeader.tsx
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { useTheme } from '../../../contexts';
-import { ArrowLeft } from '../../../icons/arrow-left';
+import { Cross } from '../../../icons/xmark-1';
import { primitives } from '../../../theme';
import { Button } from '../../ui';
@@ -27,10 +27,10 @@ export const PollModalHeader = ({ onPress, title }: PollModalHeaderProps) => {
diff --git a/package/src/components/Poll/components/PollResults/PollResultItem.tsx b/package/src/components/Poll/components/PollResults/PollResultItem.tsx
index 5c8e02570f..ddddfd2dbb 100644
--- a/package/src/components/Poll/components/PollResults/PollResultItem.tsx
+++ b/package/src/components/Poll/components/PollResults/PollResultItem.tsx
@@ -1,6 +1,5 @@
import React, { useCallback, useMemo, useState } from 'react';
-import { Modal, StyleSheet, Text, View } from 'react-native';
-import { GestureHandlerRootView } from 'react-native-gesture-handler';
+import { StyleSheet, Text, View } from 'react-native';
import { LocalMessage, Poll, PollOption, PollVote as PollVoteClass } from 'stream-chat';
@@ -15,9 +14,9 @@ import {
} from '../../../../contexts';
import { primitives } from '../../../../theme';
-import { SafeAreaViewWrapper } from '../../../UIComponents/SafeAreaViewWrapper';
import { usePollState } from '../../hooks/usePollState';
import { GenericPollButton } from '../Button';
+import { PollModal } from '../PollModal';
import { PollModalHeader } from '../PollModalHeader';
export type ShowAllVotesButtonProps = {
@@ -62,18 +61,14 @@ export const ShowAllVotesButton = (props: ShowAllVotesButtonProps) => {
) : null}
{showAllVotes ? (
- setShowAllVotes(false)}
visible={showAllVotes}
>
-
-
- setShowAllVotes(false)} title={t('Votes')} />
-
-
-
-
+ setShowAllVotes(false)} title={t('Votes')} />
+
+
) : null}
>
);
@@ -156,9 +151,6 @@ const useStyles = () => {
alignItems: 'center',
paddingBottom: primitives.spacingXs,
},
- modalRoot: {
- flex: 1,
- },
title: {
flex: 1,
fontSize: primitives.typographyFontSizeLg,
@@ -183,10 +175,6 @@ const useStyles = () => {
marginStart: primitives.spacingMd,
textAlign: 'left',
},
- safeArea: {
- backgroundColor: semantics.backgroundCoreElevation1,
- flex: 1,
- },
inlineButton: {
borderColor: semantics.borderCoreDefault,
borderTopWidth: 1,
diff --git a/package/src/components/Poll/components/__tests__/CreatePollHeader.test.tsx b/package/src/components/Poll/components/__tests__/CreatePollHeader.test.tsx
index ebb8459fa6..44f78eb8ec 100644
--- a/package/src/components/Poll/components/__tests__/CreatePollHeader.test.tsx
+++ b/package/src/components/Poll/components/__tests__/CreatePollHeader.test.tsx
@@ -43,39 +43,8 @@ const collectPathData = (node: unknown): string[] => {
return [...(typeof props?.d === 'string' ? [props.d] : []), ...collectPathData(children)];
};
-const collectTransforms = (node: unknown): string[] => {
- if (!node || typeof node !== 'object') {
- return [];
- }
-
- if (Array.isArray(node)) {
- return node.reduce((acc, child) => [...acc, ...collectTransforms(child)], []);
- }
-
- const { children, props } = node as {
- children?: unknown;
- props?: { style?: StyleProp };
- };
- const style = StyleSheet.flatten(props?.style);
- const styleTransforms = Array.isArray(style?.transform)
- ? style.transform.flatMap((transform) => {
- if (
- transform &&
- typeof transform === 'object' &&
- 'rotate' in transform &&
- typeof transform.rotate === 'string'
- ) {
- return [transform.rotate];
- }
- return [];
- })
- : [];
-
- return [...styleTransforms, ...collectTransforms(children)];
-};
-
describe('CreatePollHeader', () => {
- it('renders a secondary ghost arrow-left close button', () => {
+ it('renders a secondary outline cross close button', () => {
render(
@@ -84,11 +53,10 @@ describe('CreatePollHeader', () => {
const style = getCloseButtonWrapperStyle();
expect(style.backgroundColor).toBeUndefined();
- expect(style.borderWidth).toBeUndefined();
- expect(style.borderColor).toBeUndefined();
+ expect(style.borderWidth).toBe(1);
+ expect(style.borderColor).toBeDefined();
expect(collectPathData(screen.toJSON())).toContain(
- 'M10 16.875V3.125M10 3.125L4.375 8.75M10 3.125L15.625 8.75',
+ 'M15.625 4.375L4.375 15.625M15.625 15.625L4.375 4.375',
);
- expect(collectTransforms(screen.toJSON())).toContain('-90deg');
});
});
diff --git a/package/src/components/Poll/components/__tests__/PollModalHeader.test.tsx b/package/src/components/Poll/components/__tests__/PollModalHeader.test.tsx
index 3f0a6d3178..8f29d12377 100644
--- a/package/src/components/Poll/components/__tests__/PollModalHeader.test.tsx
+++ b/package/src/components/Poll/components/__tests__/PollModalHeader.test.tsx
@@ -47,41 +47,6 @@ const collectPathData = (node: unknown): string[] => {
return [...(typeof props?.d === 'string' ? [props.d] : []), ...collectPathData(children)];
};
-const collectTransforms = (node: unknown): string[] => {
- if (!node || typeof node !== 'object') {
- return [];
- }
-
- if (Array.isArray(node)) {
- return node.reduce((acc, child) => [...acc, ...collectTransforms(child)], []);
- }
-
- const { children, props } = node as {
- children?: unknown;
- props?: { style?: StyleProp; transform?: unknown };
- };
- const style = StyleSheet.flatten(props?.style);
- const styleTransforms = Array.isArray(style?.transform)
- ? style.transform.flatMap((transform) => {
- if (
- transform &&
- typeof transform === 'object' &&
- 'rotate' in transform &&
- typeof transform.rotate === 'string'
- ) {
- return [transform.rotate];
- }
- return [];
- })
- : [];
-
- return [
- ...(typeof props?.transform === 'string' ? [props.transform] : []),
- ...styleTransforms,
- ...collectTransforms(children),
- ];
-};
-
const renderPollModalHeader = () =>
render(
@@ -94,33 +59,31 @@ describe('PollModalHeader', () => {
setPlatform(originalPlatform);
});
- it('renders a secondary ghost arrow-left button outside Android', () => {
+ it('renders a secondary outline cross button outside Android', () => {
setPlatform('ios');
renderPollModalHeader();
const style = getCloseButtonWrapperStyle();
expect(style.backgroundColor).toBeUndefined();
- expect(style.borderWidth).toBeUndefined();
- expect(style.borderColor).toBeUndefined();
+ expect(style.borderWidth).toBe(1);
+ expect(style.borderColor).toBeDefined();
expect(collectPathData(screen.toJSON())).toContain(
- 'M10 16.875V3.125M10 3.125L4.375 8.75M10 3.125L15.625 8.75',
+ 'M15.625 4.375L4.375 15.625M15.625 15.625L4.375 4.375',
);
- expect(collectTransforms(screen.toJSON())).toContain('-90deg');
});
- it('renders a secondary ghost arrow-left button on Android', () => {
+ it('renders a secondary outline cross button on Android', () => {
setPlatform('android');
renderPollModalHeader();
const style = getCloseButtonWrapperStyle();
expect(style.backgroundColor).toBeUndefined();
- expect(style.borderWidth).toBeUndefined();
- expect(style.borderColor).toBeUndefined();
+ expect(style.borderWidth).toBe(1);
+ expect(style.borderColor).toBeDefined();
expect(collectPathData(screen.toJSON())).toContain(
- 'M10 16.875V3.125M10 3.125L4.375 8.75M10 3.125L15.625 8.75',
+ 'M15.625 4.375L4.375 15.625M15.625 15.625L4.375 4.375',
);
- expect(collectTransforms(screen.toJSON())).toContain('-90deg');
});
});
diff --git a/package/src/components/Poll/components/index.ts b/package/src/components/Poll/components/index.ts
index 5cfc99b017..b64e450952 100644
--- a/package/src/components/Poll/components/index.ts
+++ b/package/src/components/Poll/components/index.ts
@@ -6,4 +6,5 @@ export * from './PollInputDialog';
export * from './MultipleVotesSettings';
export * from './PollOption';
export * from './PollResults';
+export * from './PollModal';
export * from './PollModalHeader';