Skip to content

Commit 7c7b8c2

Browse files
committed
WebLink [nfc]: Make into formatting wrapper, using style inheritance
1 parent a73285b commit 7c7b8c2

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

src/account-info/CustomProfileFields.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ function CustomProfileFieldRow(props: {|
7070
valueElement = (
7171
<View style={styles.valueView}>
7272
{value.url ? (
73-
<WebLink url={value.url} label={{ text: '{_}', values: { _: value.text } }} />
73+
<WebLink url={value.url}>
74+
<ZulipText text={value.text} />
75+
</WebLink>
7476
) : (
7577
<ZulipText text={value.text} />
7678
)}

src/common/WebLink.js

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/* @flow strict-local */
22

3-
import React from 'react';
4-
import type { Node } from 'react';
3+
import * as React from 'react';
54

6-
import type { LocalizableText } from '../types';
5+
import ZulipText from './ZulipText';
76
import ZulipTextIntl from './ZulipTextIntl';
87
import { openLinkEmbedded } from '../utils/openLink';
98
import { BRAND_COLOR, createStyleSheet } from '../styles';
109

1110
type Props = $ReadOnly<{|
12-
label: LocalizableText,
11+
...$Exact<React$ElementConfig<typeof ZulipText>>,
1312
url: URL,
1413
|}>;
1514

@@ -21,15 +20,52 @@ const componentStyles = createStyleSheet({
2120

2221
/**
2322
* A button styled like a web link.
23+
*
24+
* Accepts `ZulipText`s, `ZulipTextIntl`s, and strings as children.
25+
*
26+
* Note: This sort of messes in those non-string children's business by
27+
* unsetting some of their default style attributes. It does this so that
28+
* its own special formatting can be passed down through the limited style
29+
* inheritance that RN supports:
30+
* https://reactnative.dev/docs/text#limited-style-inheritance
31+
* See `aggressiveDefaultStyle` in ZulipText.
32+
*
33+
* TODO: Possibly there's a better way handle this.
2434
*/
25-
export default function WebLink(props: Props): Node {
35+
export default function WebLink(props: Props): React.Node {
36+
const { children } = props;
37+
2638
return (
27-
<ZulipTextIntl
39+
<ZulipText
2840
style={componentStyles.link}
29-
text={props.label}
3041
onPress={() => {
3142
openLinkEmbedded(props.url.toString());
3243
}}
33-
/>
44+
>
45+
{React.Children.map(children, child => {
46+
if (!React.isValidElement(child)) {
47+
// Some React node that isn't a React element (a `React.Element`);
48+
// e.g., a plain string. The enclosing ZulipText will apply its
49+
// styles directly.
50+
return child;
51+
}
52+
// `child` should be a React.Element at this point. Docs are very
53+
// vague, but this sounds like it should be true, and it seems true
54+
// empirically. Would at least be good to have better type checking.
55+
56+
if (child.type !== ZulipText && child.type !== ZulipTextIntl) {
57+
return child;
58+
}
59+
// These element types will have a style prop that we want to add to.
60+
61+
return React.cloneElement(child, {
62+
style: {
63+
// Defeat ZulipText's aggressiveDefaultStyle.color so that our
64+
// color gets applied.
65+
color: undefined,
66+
},
67+
});
68+
})}
69+
</ZulipText>
3470
);
3571
}

src/start/PasswordAuthScreen.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import ViewPlaceholder from '../common/ViewPlaceholder';
1919
import ZulipText from '../common/ZulipText';
2020
import { isValidEmailFormat } from '../utils/misc';
2121
import { loginSuccess } from '../actions';
22+
import ZulipTextIntl from '../common/ZulipTextIntl';
2223

2324
const styles = createStyleSheet({
2425
linksTouchable: {
@@ -142,7 +143,9 @@ class PasswordAuthScreenInner extends PureComponent<Props, State> {
142143
<ErrorMsg error={error} />
143144
<View style={styles.linksTouchable}>
144145
<ZulipText style={styles.forgotPasswordText}>
145-
<WebLink label="Forgot password?" url={new URL('/accounts/password/reset/', realm)} />
146+
<WebLink url={new URL('/accounts/password/reset/', realm)}>
147+
<ZulipTextIntl text="Forgot password?" />
148+
</WebLink>
146149
</ZulipText>
147150
</View>
148151
</Screen>

0 commit comments

Comments
 (0)