@quintype/native-components 2.20.0-fix-rtl-issues.1 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/package.json +7 -8
  3. package/src/Icons/ClockIcon/index.js +9 -5
  4. package/src/components/ActionText/ActionText.js +7 -9
  5. package/src/components/ActionText/ActionText.test.js +5 -12
  6. package/src/components/AlsoRead/index.js +1 -1
  7. package/src/components/AlsoRead/styles.js +2 -0
  8. package/src/components/AuthorRow/AuthorRow.test.js +4 -9
  9. package/src/components/AuthorRow/index.js +16 -12
  10. package/src/components/BackNavigator/styles.js +2 -0
  11. package/src/components/Button/index.js +13 -9
  12. package/src/components/CollectionCard/index.js +6 -1
  13. package/src/components/CollectionCardNew/index.js +5 -1
  14. package/src/components/CollectionTitleNew/styles.js +0 -1
  15. package/src/components/CustomSwitch/index.js +16 -10
  16. package/src/components/Header/index.js +13 -9
  17. package/src/components/JSEmbedElement/index.js +3 -1
  18. package/src/components/PDFReader/styles.js +1 -0
  19. package/src/components/PrimaryStoryCard/index.js +60 -24
  20. package/src/components/PrimaryStoryCard/styles.js +29 -5
  21. package/src/components/PrimaryStoryCardNew/index.js +67 -18
  22. package/src/components/PrimaryStoryCardNew/styles.js +29 -5
  23. package/src/components/RadioButton/index.js +24 -9
  24. package/src/components/SecondaryStoryCard/index.js +60 -22
  25. package/src/components/SecondaryStoryCard/styles.js +29 -4
  26. package/src/components/SecondaryStoryCardNew/index.js +68 -16
  27. package/src/components/SecondaryStoryCardNew/styles.js +28 -4
  28. package/src/components/ShareButton/index.js +8 -3
  29. package/src/components/SlideshowStoryCard/styles.js +3 -2
  30. package/src/components/Story/index.js +14 -10
  31. package/src/components/StoryHeader/index.js +9 -7
  32. package/src/components/StoryHeader/styles.js +4 -2
  33. package/src/components/StoryImage/index.js +1 -1
  34. package/src/components/StoryImage/styles.js +2 -2
  35. package/src/components/StoryText/index.js +3 -1
  36. package/src/components/StoryText/styles.js +2 -0
  37. package/src/components/Table/index.js +1 -1
  38. package/src/components/Table/styles.js +5 -2
  39. package/src/components/TextBigFact/index.js +1 -2
  40. package/src/components/TextBigFact/styles.js +3 -0
  41. package/src/components/TextBlockQuote/index.js +5 -4
  42. package/src/components/TextBlockQuote/styles.js +8 -0
  43. package/src/components/TextBlurb/styles.js +2 -0
  44. package/src/components/TextQandA/styles.js +3 -3
  45. package/src/components/TextQuote/styles.js +5 -2
  46. package/src/components/TextSummary/styles.js +2 -0
  47. package/src/components/YouTubePlayer/index.js +1 -0
  48. package/src/constants/component-constants/content-constants/constants.js +7 -5
  49. package/src/constants/component-constants/general-constants/constants.js +25 -14
  50. package/src/constants/renderHTML.js +10 -0
  51. package/src/utils/story.js +7 -3
  52. package/src/utils/timeUtils.js +13 -4
@@ -1,4 +1,4 @@
1
- import { throttle } from 'lodash';
1
+ import { get, throttle } from 'lodash';
2
2
  import PropTypes from 'prop-types';
3
3
  import React, { useContext, memo } from 'react';
4
4
  import {
@@ -8,6 +8,7 @@ import {
8
8
  TextStyle,
9
9
  TouchableOpacityProps,
10
10
  } from 'react-native';
11
+ import Icon from 'react-native-vector-icons/FontAwesome';
11
12
  import {
12
13
  AppTheme,
13
14
  getImageMetadata,
@@ -17,13 +18,25 @@ import {
17
18
  import { getStoryHeadline } from '../../utils/story';
18
19
  import { ResponsiveImage, Text } from '../index';
19
20
  import { storyStyles } from './styles';
21
+ import {
22
+ COMP_GENERAL_CONSTANTS,
23
+ COMP_CONTENT_CONSTANTS,
24
+ } from '../../constants/component-constants';
20
25
 
21
26
  const SecondaryStoryCardNewBase = (props) => {
22
27
  const { story = {} } = props;
23
28
  const { theme } = useContext(AppTheme);
24
- const { locale } = theme;
29
+ const {
30
+ locale,
31
+ DARK_MODE,
32
+ COLORS,
33
+ reverseTimeAdverbPosition,
34
+ enableReadTimeOnStoryCards,
35
+ } = theme;
36
+
37
+ const translate = get(theme, ['translate'], (word) => word);
25
38
 
26
- const styles = storyStyles(theme);
39
+ const styles = storyStyles(theme, DARK_MODE);
27
40
  const containerStyle = StyleSheet.flatten([
28
41
  styles.container,
29
42
  { paddingHorizontal: props.horizontalPadding },
@@ -38,12 +51,43 @@ const SecondaryStoryCardNewBase = (props) => {
38
51
  ]);
39
52
 
40
53
  const DATE_FORMAT = 'd MMM, yyyy';
41
- const readTime = story['read-time'] ? `${story['read-time']} min read` : '';
54
+ const readTime = enableReadTimeOnStoryCards && story['read-time']
55
+ ? `${story['read-time']} ${translate('min read')} · `
56
+ : '';
42
57
 
43
58
  const throttledOnpress = throttle(props.onPress, 1000);
59
+
60
+ const showIcon = (name) => (
61
+ <View style={styles.storyType}>
62
+ <Icon name={name} size={14} color={COLORS.MONO7} />
63
+ </View>
64
+ );
65
+
66
+ const showLiveBlogIcon = () => (
67
+ <View style={styles.storyType}>
68
+ <View style={styles.liveBlogIcon} />
69
+ <Text style={styles.liveBlogText}>LIVE</Text>
70
+ </View>
71
+ );
72
+
73
+ const showStoryType = () => {
74
+ switch (story['story-template']) {
75
+ case 'text':
76
+ return null;
77
+ case 'photo':
78
+ return showIcon('photo');
79
+ case 'video':
80
+ return showIcon('play');
81
+ case 'live-blog':
82
+ return showLiveBlogIcon();
83
+ default:
84
+ null;
85
+ }
86
+ };
87
+
44
88
  return (
45
89
  <TouchableOpacity
46
- testID={props.collectionTestID}
90
+ testID={COMP_GENERAL_CONSTANTS.secondaryStoryCard}
47
91
  onPress={throttledOnpress}
48
92
  activeOpacity={0.8}
49
93
  style={containerStyle}
@@ -53,25 +97,34 @@ const SecondaryStoryCardNewBase = (props) => {
53
97
  slug={getImageSlug(story) || ''}
54
98
  cdn={props.cdn || ''}
55
99
  imageWidth={props.imageWidth}
56
- />
100
+ >
101
+ <View style={styles.storyTypeContainer}>{showStoryType()}</View>
102
+ </ResponsiveImage>
57
103
  <View style={styles.headlineAndTimestampBlockContainer}>
58
104
  <Text
59
105
  primary
60
106
  numberOfLines={2}
61
107
  ellipsizeMode="tail"
62
108
  style={headlineStyle}
63
- testID="secondaryStoryCardHeadline"
109
+ testID={COMP_GENERAL_CONSTANTS.secondaryStoryHeadline}
64
110
  >
65
111
  {getStoryHeadline(story)?.trim()}
66
112
  </Text>
67
- <View style={styles.timestampContainer}>
68
- {readTime ? (
69
- <Text style={timestampStyle}>{`${readTime} · `}</Text>
70
- ) : null}
71
- <Text style={timestampStyle} testID="secondaryStoryCardDate">
72
- {getTimeForStoryCards(story['published-at'], DATE_FORMAT, locale)}
73
- </Text>
74
- </View>
113
+ <Text
114
+ style={timestampStyle}
115
+ numberOfLines={2}
116
+ // TODO: Add corrected testID here
117
+ testID={COMP_CONTENT_CONSTANTS.publishedDate}
118
+ >
119
+ {readTime
120
+ + getTimeForStoryCards(
121
+ story['published-at'],
122
+ DATE_FORMAT,
123
+ locale,
124
+ translate,
125
+ reverseTimeAdverbPosition,
126
+ )}
127
+ </Text>
75
128
  </View>
76
129
  <View style={styles.icon}>{props.iconComponent}</View>
77
130
  </TouchableOpacity>
@@ -84,7 +137,6 @@ SecondaryStoryCardNewBase.propTypes = TouchableOpacityProps && {
84
137
  headlineStyle: TextStyle,
85
138
  timestampStyle: TextStyle,
86
139
  story: PropTypes.any.isRequired,
87
- collectionTestID: PropTypes.string,
88
140
  iconComponent: PropTypes.element,
89
141
  horizontalPadding: PropTypes.number,
90
142
  };
@@ -18,10 +18,6 @@ export const storyStyles = ({ COLORS, FONT_SIZE }) => StyleSheet.create({
18
18
  fontSize: FONT_SIZE.h5,
19
19
  lineHeight: FONT_SIZE.h5 * 1.2,
20
20
  opacity: 0.6,
21
- },
22
- timestampContainer: {
23
- alignItems: 'center',
24
- flexDirection: 'row',
25
21
  marginTop: 4,
26
22
  },
27
23
  headline: {
@@ -33,4 +29,32 @@ export const storyStyles = ({ COLORS, FONT_SIZE }) => StyleSheet.create({
33
29
  icon: {
34
30
  marginLeft: 8,
35
31
  },
32
+ storyTypeContainer: {
33
+ position: 'absolute',
34
+ backgroundColor: COLORS.MONO1,
35
+ bottom: 0,
36
+ left: 0,
37
+ },
38
+ storyType: {
39
+ padding: 5,
40
+ justifyContent: 'space-between',
41
+ alignItems: 'center',
42
+ flexDirection: 'row',
43
+ },
44
+ storyTypeText: {
45
+ color: COLORS.MONO7,
46
+ fontSize: FONT_SIZE.h5,
47
+ },
48
+ liveBlogText: {
49
+ color: COLORS.MONO7,
50
+ fontSize: FONT_SIZE.h5,
51
+ marginLeft: 4,
52
+ fontWeight: 'bold',
53
+ },
54
+ liveBlogIcon: {
55
+ height: 12,
56
+ width: 12,
57
+ borderRadius: 50,
58
+ backgroundColor: COLORS.BRAND_3,
59
+ },
36
60
  });
@@ -6,10 +6,12 @@ import Share from 'react-native-share';
6
6
  import { AppTheme } from '../../utils';
7
7
  import { shareButtonStyles } from './styles';
8
8
  import { getStoryHeadline } from '../../utils/story';
9
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants';
9
10
 
10
11
  const ShareButtonBase = (props) => {
11
12
  const { theme } = useContext(AppTheme);
12
13
  const styles = shareButtonStyles(theme);
14
+ const { enableShareOnStoryCards } = theme;
13
15
  const { story, type = 'story', slug } = props;
14
16
 
15
17
  const getShareURL = () => {
@@ -42,11 +44,14 @@ const ShareButtonBase = (props) => {
42
44
  return null;
43
45
  }
44
46
 
45
- return (
46
- <TouchableOpacity onPress={share}>
47
+ return enableShareOnStoryCards ? (
48
+ <TouchableOpacity
49
+ onPress={share}
50
+ testID={COMP_GENERAL_CONSTANTS.shareButtonTouch}
51
+ >
47
52
  <Icon style={styles.iconStyle} name="share-social-outline" size={20} />
48
53
  </TouchableOpacity>
49
- );
54
+ ) : null;
50
55
  };
51
56
 
52
57
  ShareButtonBase.propTypes = {
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet, Dimensions } from 'react-native';
2
-
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants'
3
3
  const { width } = Dimensions.get('window');
4
4
 
5
5
  export const slideshowStoryCardStyles = ({ COLORS }) => {
@@ -21,7 +21,8 @@ export const slideshowStoryCardStyles = ({ COLORS }) => {
21
21
  flexDirection: 'column',
22
22
  },
23
23
  attributionText: {
24
- color: COLORS.BRAND_BLACK
24
+ color: COLORS.BRAND_BLACK,
25
+ textAlign : COMP_GENERAL_CONSTANTS.textAlignment
25
26
  }
26
27
  })
27
28
  }
@@ -47,7 +47,7 @@ const getLiveBlogTimeStamp = (card, DATE_FORMAT, share, styles, locale) => {
47
47
 
48
48
  /* Mutate the data during access check to limit the content shown */
49
49
  const mutateDataBeforeAccess = (item, storyHasAccess) => {
50
- if (isStoryFree(item)) {
50
+ if (isStoryFree(item) === 0 || storyHasAccess === 'granted') {
51
51
  return item;
52
52
  }
53
53
  if (storyHasAccess !== 'loading' && storyHasAccess === 'granted') {
@@ -55,7 +55,7 @@ const mutateDataBeforeAccess = (item, storyHasAccess) => {
55
55
  }
56
56
  /* The following steps are necessary to keep argument mutation at bay */
57
57
  const firstCardObject = get(item, ['cards', 0], {});
58
- const firstCardElement = get(firstCardObject, ['story-elements', 0], {});
58
+ const firstCardElement = get(firstCardObject, !STORY_TYPES.VIDEO_STORY && ['story-elements', 0], {});
59
59
 
60
60
  return {
61
61
  ...item,
@@ -119,8 +119,11 @@ const getStoryCards = (
119
119
  )}
120
120
  {/* Skip first card if it's a listicle */}
121
121
 
122
- {source.length > 1 && isMiddleIndexOfArray(index, source) && getAd(true)}
123
- {/* ^ Requesting Ad if there are multiple cards. Sending param true for mid-content ad */}
122
+ {source.length > (storyType === STORY_TYPES.VIDEO_STORY ? 2 : 1)
123
+ && isMiddleIndexOfArray(index, source)
124
+ && getAd(true)}
125
+ {/* ^ Requesting mid-content-ad if there are > 1 card
126
+ (> 2 cards in case of video story since the 1st card gets rendered in header). */}
124
127
 
125
128
  {(card['story-elements'] || []).map((storyElement, index, source) => {
126
129
  /* Skip the first video element for video story */
@@ -129,10 +132,12 @@ const getStoryCards = (
129
132
  return (
130
133
  <>
131
134
  {cards.length === 1
132
- && source.length > 1
133
- && isMiddleIndexOfArray(index, source)
134
- && getAd(true)}
135
- {/* ^ Requesting Ad if there's just one card but multiple elements. Sending param true for mid-content ad */}
135
+ && source.length > (storyType === STORY_TYPES.VIDEO_STORY ? 2 : 1)
136
+ && isMiddleIndexOfArray(index, source)
137
+ && getAd(true)}
138
+ {/* ^ In the case of a story having just 1 card,
139
+ requesting mid-content-Ad if there are > 1 story-elements in that card
140
+ (> 2 story-elements in case of video story since the 1st story-element gets rendered in header). */}
136
141
 
137
142
  <StoryContent
138
143
  testID={contentTestID}
@@ -194,9 +199,8 @@ export const Story = ({
194
199
 
195
200
  const shouldShowComments = () => {
196
201
  if (!enableFbComments) return null;
197
-
198
202
  if (
199
- isStoryFree(story)
203
+ isStoryFree(story) === 0
200
204
  || (storyHasAccess !== 'loading' && storyHasAccess === 'granted')
201
205
  ) {
202
206
  return (
@@ -19,7 +19,7 @@ import { YouTubePlayer } from '../YouTubePlayer';
19
19
  import { storyHeaderStyles } from './styles';
20
20
  import { COMP_CONTENT_CONSTANTS } from '../../constants/component-constants/content-constants/constants';
21
21
 
22
- /* import {DailyMotionPlayer} from "../DailyMotionPlayer"; */
22
+ import { DailyMotionPlayer } from '../DailyMotionPlayer';
23
23
 
24
24
  const DATE_FORMAT = 'd MMMM yyyy h:mm a';
25
25
 
@@ -44,9 +44,9 @@ const getHeroComponent = (props) => {
44
44
  case STORY_TYPES.VIDEO_STORY: {
45
45
  if (!firstVideoElement) return null;
46
46
  switch (firstVideoElement.type) {
47
- /* case "jsembed":{
48
- return <DailyMotionPlayer element={firstVideoElement} />;
49
- } */
47
+ case 'jsembed': {
48
+ return <DailyMotionPlayer element={firstVideoElement} />;
49
+ }
50
50
  case 'youtube-video': {
51
51
  return (
52
52
  <YouTubePlayer
@@ -69,8 +69,10 @@ export const StoryHeader = (props) => {
69
69
  const { story } = props;
70
70
  const sectionData = get(story, ['sections', 0], {});
71
71
  const { theme } = useContext(AppTheme);
72
- const { COLORS, CAN_COPY_TEXT, locale } = theme;
73
- const styles = storyHeaderStyles(COLORS);
72
+ const {
73
+ COLORS, CAN_COPY_TEXT, locale, FONT_FAMILY,
74
+ } = theme;
75
+ const styles = storyHeaderStyles(COLORS, FONT_FAMILY);
74
76
  const imgCaption = story['hero-image-caption'];
75
77
  const attri = story['hero-image-attribution'];
76
78
  const imgAttribution = imgCaption && attri ? ` | ${attri}` : attri;
@@ -91,7 +93,7 @@ export const StoryHeader = (props) => {
91
93
  }}
92
94
  />
93
95
  <HTML
94
- html={imgAttribution}
96
+ html={attri}
95
97
  textSelectable={CAN_COPY_TEXT}
96
98
  key={Math.random()}
97
99
  baseFontStyle={styles.attributionStyle}
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
 
3
- export const storyHeaderStyles = (COLORS) => StyleSheet.create({
3
+ export const storyHeaderStyles = (COLORS, FONT_FAMILY) => StyleSheet.create({
4
4
  tagStyle: {
5
5
  padding: 10,
6
6
  backgroundColor: COLORS.BRAND_7,
@@ -29,15 +29,17 @@ export const storyHeaderStyles = (COLORS) => StyleSheet.create({
29
29
  padding: 10,
30
30
  paddingBottom: 0,
31
31
  color: COLORS.BRAND_BLACK,
32
+ fontFamily: FONT_FAMILY.secondary,
32
33
  opacity: 0.8,
33
34
  },
34
35
  attributionStyle: {
35
36
  color: COLORS.BRAND_BLACK,
37
+ fontFamily: FONT_FAMILY.secondary,
36
38
  opacity: 0.8,
37
39
  },
38
40
  captionContainerStyle: {
39
41
  paddingHorizontal: 5,
40
- flexDirection: 'row',
42
+ flexDirection: 'column',
41
43
  flexWrap: 'wrap',
42
44
  marginTop: 10,
43
45
  },
@@ -28,7 +28,7 @@ export const StoryImage = ({
28
28
  if (!card['image-attribution']) return null;
29
29
  return (
30
30
  <Text style={styles.attributionText}>
31
- {` | ${card['image-attribution']}`}
31
+ {` | ${stripHTML(card['image-attribution'])}`}
32
32
  </Text>
33
33
  );
34
34
  };
@@ -1,8 +1,8 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
  import { getImageHeight } from '../../utils';
3
3
 
4
- export const storyImageStyles = ({ COLORS, FONT_SIZE }, metadata) => {
5
- const { width, height } = metadata;
4
+ export const storyImageStyles = ({ COLORS, FONT_SIZE }, metadata = {}) => {
5
+ const { width, height } = metadata || {};
6
6
  const imageHeight = getImageHeight(width, height);
7
7
 
8
8
  return StyleSheet.create({
@@ -1,7 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useContext } from 'react';
3
3
  import {
4
- View, StyleSheet, Linking, Text,
4
+ View, StyleSheet, Linking, Text, I18nManager,
5
5
  } from 'react-native';
6
6
  import HTML from 'react-native-render-html';
7
7
  import { AppTheme } from '../../utils/context';
@@ -21,8 +21,10 @@ export const StoryText = (props) => {
21
21
  {
22
22
  fontFamily: FONT_FAMILY.secondary,
23
23
  fontWeight: props.question ? '600' : 'normal',
24
+ writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
24
25
  },
25
26
  ]);
27
+
26
28
  const customTagsStyles = customHTMLStyles();
27
29
 
28
30
  return (
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants';
2
3
 
3
4
  export const storyTextStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
4
5
  container: {
@@ -8,5 +9,6 @@ export const storyTextStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
8
9
  fontSize: FONT_SIZE.h2,
9
10
  lineHeight: FONT_SIZE.h2 * 1.5,
10
11
  color: COLORS.BRAND_8,
12
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
11
13
  },
12
14
  });
@@ -27,7 +27,7 @@ export const Table = ({ card }) => {
27
27
  <View style={styles.tableRow}>
28
28
  {headerFields.map((headerField) => (
29
29
  <View style={styles.tableHeaderTitle}>
30
- <Text>{data[headerField]}</Text>
30
+ <Text style={styles.tableContect}>{data[headerField]}</Text>
31
31
  </View>
32
32
  ))}
33
33
  </View>
@@ -1,5 +1,4 @@
1
1
  import { StyleSheet } from 'react-native';
2
-
3
2
  export const tableStyles = ({ COLORS }) => StyleSheet.create({
4
3
  container: {
5
4
  flexDirection: 'row',
@@ -15,6 +14,7 @@ export const tableStyles = ({ COLORS }) => StyleSheet.create({
15
14
  justifyContent: 'center',
16
15
  borderWidth: 0.5,
17
16
  borderColor: COLORS.BRAND_4,
17
+ color: COLORS.BRAND_4,
18
18
  },
19
19
  tableBody: {
20
20
  flexDirection: 'column',
@@ -22,4 +22,7 @@ export const tableStyles = ({ COLORS }) => StyleSheet.create({
22
22
  tableRow: {
23
23
  flexDirection: 'row',
24
24
  },
25
- });
25
+ tableContect: {
26
+ color: COLORS.BRAND_BLACK,
27
+ },
28
+ });
@@ -40,8 +40,7 @@ export const TextBigFact = ({ text, attribution, id }) => {
40
40
  />
41
41
  {!!attribution && (
42
42
  <Text style={styles.authorText}>
43
- -
44
- {attribution}
43
+ {`- ${attribution}`}
45
44
  </Text>
46
45
  )}
47
46
  </View>
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants';
2
3
 
3
4
  export const bigTextStyles = (COLORS, FONT_SIZE, DARK_MODE) => StyleSheet.create({
4
5
  container: {
@@ -11,10 +12,12 @@ export const bigTextStyles = (COLORS, FONT_SIZE, DARK_MODE) => StyleSheet.create
11
12
  color: DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE,
12
13
  lineHeight: FONT_SIZE.h1 * 1.3,
13
14
  marginVertical: 10,
15
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
14
16
  },
15
17
  authorText: {
16
18
  fontSize: FONT_SIZE.h5,
17
19
  color: DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE,
18
20
  lineHeight: FONT_SIZE.h5 * 1.3,
21
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
19
22
  },
20
23
  });
@@ -26,8 +26,10 @@ export const TextBlockQuote = ({ text, attribution }) => {
26
26
 
27
27
  return (
28
28
  <View testID="text-block-quote" style={styles.container}>
29
- <Icon name="quote-left" size={46} color={DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE} />
30
- <HTML
29
+ <View style={styles.topBorderContainer}>
30
+ <Icon name="quote-left" size={46} color={DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE} />
31
+ </View>
32
+ <HTML
31
33
  alterData={alterQuoteData}
32
34
  html={text}
33
35
  textSelectable={CAN_COPY_TEXT}
@@ -44,8 +46,7 @@ export const TextBlockQuote = ({ text, attribution }) => {
44
46
  />
45
47
  {!!attribution && (
46
48
  <Text style={styles.authorText}>
47
- -
48
- {attribution}
49
+ {`- ${attribution}`}
49
50
  </Text>
50
51
  )}
51
52
  </View>
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants';
2
3
 
3
4
  export const blockQuoteTextStyles = (FONT_SIZE, COLORS, DARK_MODE) => StyleSheet.create({
4
5
  container: {
@@ -11,10 +12,17 @@ export const blockQuoteTextStyles = (FONT_SIZE, COLORS, DARK_MODE) => StyleSheet
11
12
  color: DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE,
12
13
  lineHeight: FONT_SIZE.h1 * 1.3,
13
14
  marginVertical: 10,
15
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
14
16
  },
15
17
  authorText: {
16
18
  fontSize: FONT_SIZE.h5,
17
19
  color: DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE,
18
20
  lineHeight: FONT_SIZE.h5 * 1.3,
21
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
22
+ },
23
+ topBorderContainer: {
24
+ alignItems: 'center',
25
+ flexDirection: 'row',
26
+ marginBottom: 8,
19
27
  },
20
28
  });
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants'
2
3
 
3
4
  export const textBlurbStyles = (FONT_SIZE) => StyleSheet.create({
4
5
  container: {
@@ -9,5 +10,6 @@ export const textBlurbStyles = (FONT_SIZE) => StyleSheet.create({
9
10
  blurbText: {
10
11
  fontSize: FONT_SIZE.h3,
11
12
  lineHeight: FONT_SIZE.h3 * 1.3,
13
+ textAlign : COMP_GENERAL_CONSTANTS.textAlignment
12
14
  },
13
15
  });
@@ -8,13 +8,13 @@ export const textQandAStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
8
8
  fontSize: FONT_SIZE.h2,
9
9
  fontWeight: '600',
10
10
  lineHeight: FONT_SIZE.h2 * 1.3,
11
- color: COLORS.BRAND_8,
12
- opacity: 0.8
11
+ color: COLORS.BRAND_BLACK,
12
+ opacity: 0.8,
13
13
  },
14
14
  answerText: {
15
15
  fontSize: FONT_SIZE.h2,
16
16
  lineHeight: FONT_SIZE.h2 * 1.3,
17
17
  color: COLORS.BRAND_BLACK,
18
- opacity: 0.8
18
+ opacity: 0.8,
19
19
  },
20
20
  });
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants';
2
3
 
3
4
  export const textQuoteStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
4
5
  container: {
@@ -19,14 +20,15 @@ export const textQuoteStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
19
20
  fontSize: FONT_SIZE.h1,
20
21
  lineHeight: FONT_SIZE.h1 * 1.3,
21
22
  color: COLORS.BRAND_BLACK,
22
- opacity: 0.9
23
+ opacity: 0.9,
24
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
23
25
  },
24
26
  attributionText: {
25
27
  fontSize: FONT_SIZE.h3,
26
28
  lineHeight: FONT_SIZE.h3 * 1.3,
27
29
  color: COLORS.BRAND_BLACK,
28
30
  alignItems: 'flex-end',
29
- textAlign: 'right',
31
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment,
30
32
  },
31
33
  quoteTopBorder: {
32
34
  backgroundColor: COLORS.BRAND_1,
@@ -43,5 +45,6 @@ export const textQuoteStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
43
45
  marginVertical: 10,
44
46
  alignSelf: 'flex-end',
45
47
  flexDirection: 'row',
48
+ width: '100%',
46
49
  },
47
50
  });
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { COMP_GENERAL_CONSTANTS } from '../../constants/component-constants/general-constants/constants'
2
3
 
3
4
  export const textSummaryStyles = (FONT_SIZE, COLORS) => StyleSheet.create({
4
5
  container: {
@@ -14,6 +15,7 @@ export const textSummaryStyles = (FONT_SIZE, COLORS) => StyleSheet.create({
14
15
  color: COLORS.BRAND_6,
15
16
  fontSize: FONT_SIZE.h2,
16
17
  lineHeight: FONT_SIZE.h2 * 1.3,
18
+ textAlign: COMP_GENERAL_CONSTANTS.textAlignment
17
19
  },
18
20
  summaryText: {
19
21
  color: COLORS.BRAND_1,
@@ -36,6 +36,7 @@ const webviewStyles = (windowWidth) => {
36
36
  },
37
37
  container: {
38
38
  flex: 1,
39
+ marginVertical: 10,
39
40
  },
40
41
  };
41
42
  };
@@ -1,7 +1,9 @@
1
1
  export const COMP_CONTENT_CONSTANTS = {
2
- storyTitle: 'COMP_STORY_TITLE',
3
- storySubTitle: 'COMP_STORY_SUBTITLE',
4
- sectionName: 'COMP_STORY_SECTION_NAME',
5
- publishedDate: 'COMP_STORY_PUBLISHED_DATE',
6
- relatedStoriesLabel: 'COMP_STORY_RELATEDSTORIES_LABEL',
2
+ storyTitle: "COMP_STORY_TITLE",
3
+ storySubTitle: "COMP_STORY_SUBTITLE",
4
+ sectionName: "COMP_STORY_SECTION_NAME",
5
+ publishedDate: "COMP_STORY_PUBLISHED_DATE",
6
+ relatedStoriesLabel: "COMP_STORY_RELATEDSTORIES_LABEL",
7
+ authorName: "COMP_STORY_AUTHOR_NAME",
8
+ authorImage: "COMP_STORY_AUTHOR_IMAGE",
7
9
  };