Update component to support testing
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,15 @@ const removeVS16s = (rawEmoji) => (rawEmoji.indexOf(zeroWidthJoiner) < 0 ? rawEm
|
||||
|
||||
const defaultFontSize = 14;
|
||||
|
||||
// helper functions
|
||||
const isString = (value) => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
const isObject = (value) => {
|
||||
return typeof value === 'object';
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an HEX codepoint, returns UTF16 surrogate pairs.
|
||||
*
|
||||
@@ -92,11 +101,17 @@ const TwemojiImage = ({ style, rawText, iconId }) => {
|
||||
const fontSize = style?.textStyle?.fontSize ?? defaultFontSize;
|
||||
|
||||
if (errorInFetching) {
|
||||
return <Text style={{ fontSize }}>{rawText}</Text>;
|
||||
return (
|
||||
<Text accessibilityLabel={rawText} style={{ fontSize }}>
|
||||
{rawText}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FastImage
|
||||
accessible={true}
|
||||
accessibilityLabel={rawText}
|
||||
style={{
|
||||
width: fontSize,
|
||||
height: fontSize,
|
||||
@@ -157,22 +172,21 @@ const parseString = (text, style) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
const isString = (value) => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
const flatten = (array) => {
|
||||
let newArray = [];
|
||||
let parsedChildren = [],
|
||||
hasObjectType = false;
|
||||
|
||||
array.forEach((item) => {
|
||||
if (Array.isArray(item)) {
|
||||
newArray = newArray.concat(item);
|
||||
parsedChildren = parsedChildren.concat(item);
|
||||
} else {
|
||||
newArray.push(item);
|
||||
parsedChildren.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return newArray;
|
||||
hasObjectType = parsedChildren.some((x) => isObject(x));
|
||||
|
||||
return { parsedChildren, hasObjectType };
|
||||
};
|
||||
|
||||
const parseChildren = (source, style) => {
|
||||
@@ -193,9 +207,9 @@ const parseChildren = (source, style) => {
|
||||
*/
|
||||
export const Twemoji = ({ children, imageProps, ...props }) => {
|
||||
const textStyle = StyleSheet.flatten(props.style);
|
||||
const parsedChildren = parseChildren(children, { imageProps, textStyle });
|
||||
const { parsedChildren } = parseChildren(children, { imageProps, textStyle });
|
||||
|
||||
if (parsedChildren.length && typeof parsedChildren[0] === 'object') {
|
||||
if (parsedChildren.length && isObject(parsedChildren[0])) {
|
||||
return parsedChildren[0];
|
||||
}
|
||||
|
||||
@@ -208,11 +222,22 @@ export const Twemoji = ({ children, imageProps, ...props }) => {
|
||||
*/
|
||||
export const TwemojiText = ({ children, imageProps, ...props }) => {
|
||||
const textStyle = StyleSheet.flatten(props.style);
|
||||
const parsedChildren = parseChildren(children, { imageProps, textStyle });
|
||||
const { parsedChildren, hasObjectType } = parseChildren(children, { imageProps, textStyle });
|
||||
|
||||
// If there in no Twemoji in the text, render it as it is.
|
||||
if (!hasObjectType) {
|
||||
return <Text {...props}>{parsedChildren.join('')}</Text>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Text {...props}>
|
||||
{/* Hack to retain the line height and to render emoji (images) within the line height*/}
|
||||
<Text style={{ color: 'transparent', fontSize: 0.1 }} selectable={false}>
|
||||
<Text
|
||||
key={'twemoji-line-height-retainer'}
|
||||
accessible={false}
|
||||
selectable={false}
|
||||
style={{ color: 'transparent', fontSize: 0.1 }}
|
||||
>
|
||||
{' '}
|
||||
</Text>
|
||||
{parsedChildren}
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
(h/test "default render"
|
||||
(h/render [account-avatar/view])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji)))
|
||||
(h/is-truthy (h/query-by-label-text account-avatar/default-emoji)))
|
||||
|
||||
(h/test "with emoji"
|
||||
(let [emoji "💸"]
|
||||
(h/render [account-avatar/view {:emoji emoji :size 80}])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/is-truthy (h/query-by-text emoji))))
|
||||
(h/is-truthy (h/query-by-label-text emoji))))
|
||||
|
||||
(h/test "size 80 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
@@ -29,10 +28,7 @@
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
(h/is-truthy (h/query-by-label-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 48 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "💵"
|
||||
@@ -48,10 +44,7 @@
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 1
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
(h/is-truthy (h/query-by-label-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 28 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
@@ -65,10 +58,7 @@
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
(h/is-truthy (h/query-by-label-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 16 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "🎉"
|
||||
@@ -84,7 +74,4 @@
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 0.8
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts))))))
|
||||
(h/is-truthy (h/query-by-label-text (:emoji opts))))))
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def default-emoji "🍑")
|
||||
|
||||
(defn- view-internal
|
||||
"Opts:
|
||||
|
||||
@@ -19,7 +21,7 @@
|
||||
:theme - keyword -> :light/:dark"
|
||||
[{:keys [size emoji]
|
||||
:or {size style/default-size
|
||||
emoji "🍑"}
|
||||
emoji default-emoji}
|
||||
:as opts}]
|
||||
(let [emoji-size (style/get-emoji-size size)]
|
||||
[rn/view
|
||||
@@ -27,8 +29,7 @@
|
||||
:accessibility-label :account-avatar
|
||||
:style (style/root-container opts)}
|
||||
[twemoji/twemoji
|
||||
{:accessibility-label :account-emoji
|
||||
:style {:font-size emoji-size}}
|
||||
{:style {:font-size emoji-size}}
|
||||
(string/trim emoji)]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
(if (string/blank? emoji)
|
||||
[initials full-name size customization-color]
|
||||
[twemoji/twemoji
|
||||
{:accessibility-label :emoji
|
||||
:style {:font-size (if (= size :size/l) 15 12)}}
|
||||
{:style {:font-size (if (= size :size/l) 15 12)}}
|
||||
(string/trim emoji)])
|
||||
[lock locked? size]])
|
||||
|
||||
Reference in New Issue
Block a user