Skip to content

Commit 0838c6e

Browse files
authored
Button - add hyperlink (#1671)
* Button - add hyperlink * link to isLink
1 parent a67c341 commit 0838c6e

File tree

8 files changed

+120
-19
lines changed

8 files changed

+120
-19
lines changed

demo/src/screens/componentScreens/ButtonsScreen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,12 @@ export default class ButtonsScreen extends Component {
383383
style={{marginBottom: ButtonSpace}}
384384
/>
385385

386+
<Button
387+
label="hyperlink button"
388+
hyperlink
389+
style={{marginBottom: ButtonSpace}}
390+
/>
391+
386392
<Button label="Icon on right" iconSource={plusIcon} iconOnRight />
387393
</View>
388394

generatedTypes/src/components/button/ButtonTypes.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ export declare type ButtonProps = TouchableOpacityProps & TypographyModifiers &
8080
*/
8181
link?: boolean;
8282
/**
83-
* label color for when it's displayed as link
83+
* Button will look like a hyperlink
84+
*/
85+
hyperlink?: boolean;
86+
/**
87+
* label color for when it's displayed as link or hyperlink
8488
*/
8589
linkColor?: string;
8690
/**

generatedTypes/src/components/button/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ declare class Button extends PureComponent<Props, ButtonState> {
156156
componentDidUpdate(prevProps: Props): void;
157157
onLayout: (event: LayoutChangeEvent) => void;
158158
get isOutline(): boolean;
159+
get isLink(): boolean | undefined;
159160
get isFilled(): boolean;
160161
get isIconButton(): boolean | 0 | undefined;
161162
getBackgroundColor(): any;

src/components/button/ButtonTypes.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ export type ButtonProps = TouchableOpacityProps &
9595
*/
9696
link?: boolean;
9797
/**
98-
* label color for when it's displayed as link
98+
* Button will look like a hyperlink
99+
*/
100+
hyperlink?: boolean;
101+
/**
102+
* label color for when it's displayed as link or hyperlink
99103
*/
100104
linkColor?: string;
101105
/**

src/components/button/__tests__/__snapshots__/index.spec.js.snap

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,78 @@ exports[`Button container size should return style for xSmall button 2`] = `
16971697
</View>
16981698
`;
16991699

1700+
exports[`Button hyperlink should render button as a hyperlink 1`] = `
1701+
<View
1702+
accessibilityRole="button"
1703+
accessible={true}
1704+
collapsable={false}
1705+
focusable={true}
1706+
nativeID="animatedComponent"
1707+
onClick={[Function]}
1708+
onLayout={[Function]}
1709+
onResponderGrant={[Function]}
1710+
onResponderMove={[Function]}
1711+
onResponderRelease={[Function]}
1712+
onResponderTerminate={[Function]}
1713+
onResponderTerminationRequest={[Function]}
1714+
onStartShouldSetResponder={[Function]}
1715+
style={
1716+
Object {
1717+
"alignItems": "center",
1718+
"backgroundColor": "transparent",
1719+
"borderRadius": 0,
1720+
"flexDirection": "row",
1721+
"justifyContent": "center",
1722+
"minWidth": undefined,
1723+
"opacity": 1,
1724+
"paddingHorizontal": undefined,
1725+
"paddingVertical": undefined,
1726+
}
1727+
}
1728+
>
1729+
<Text
1730+
numberOfLines={1}
1731+
style={
1732+
Array [
1733+
Object {
1734+
"backgroundColor": "transparent",
1735+
"textAlign": "left",
1736+
},
1737+
undefined,
1738+
undefined,
1739+
undefined,
1740+
undefined,
1741+
Object {},
1742+
undefined,
1743+
undefined,
1744+
Object {
1745+
"textDecorationLine": "underline",
1746+
},
1747+
Array [
1748+
Object {
1749+
"backgroundColor": "transparent",
1750+
"flex": 0,
1751+
"flexDirection": "row",
1752+
"fontFamily": "System",
1753+
"fontSize": 16,
1754+
"fontWeight": "400",
1755+
"lineHeight": 24,
1756+
},
1757+
Object {
1758+
"color": "#5A48F5",
1759+
},
1760+
Object {},
1761+
Object {},
1762+
undefined,
1763+
],
1764+
]
1765+
}
1766+
>
1767+
Button
1768+
</Text>
1769+
</View>
1770+
`;
1771+
17001772
exports[`Button icon should apply color on icon 1`] = `
17011773
<View
17021774
accessibilityRole="button"

src/components/button/__tests__/index.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ describe('Button', () => {
5656
});
5757
});
5858

59+
describe('hyperlink', () => {
60+
it('should render button as a hyperlink', () => {
61+
const tree = renderer.create(<Button label="Button" hyperlink/>).toJSON();
62+
expect(tree).toMatchSnapshot();
63+
});
64+
});
65+
5966
describe('backgroundColor', () => {
6067
it('should return defined theme backgroundColor', () => {
6168
ThemeManager.setComponentTheme('Button', {

src/components/button/button.api.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
{"name": "outlineColor", "type": "string", "description": "The outline color"},
3939
{"name": "outlineWidth", "type": "number", "description": "The outline width"},
4040
{"name": "link", "type": "boolean", "description": "Button will look like a link"},
41-
{"name": "linkColor", "type": "string", "description": "label color for when it's displayed as link"},
41+
{"name": "hyperlink", "type": "boolean", "description": "Button will look like a hyperlink"},
42+
{"name": "linkColor", "type": "string", "description": "label color for when it's displayed as link or hyperlink"},
4243
{"name": "labelStyle", "type": "TextStyle", "description": "Additional styles for label text"},
4344
{"name": "labelProps", "type": "TextProps", "description": "Props that will be passed to the button's Text label."},
4445
{

src/components/button/index.tsx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,13 @@ class Button extends PureComponent<Props, ButtonState> {
6363
return Boolean(outline || outlineColor);
6464
}
6565

66+
get isLink() {
67+
const {link, hyperlink} = this.props;
68+
return link || hyperlink;
69+
}
70+
6671
get isFilled() {
67-
const {link} = this.props;
68-
return !this.isOutline && !link;
72+
return !this.isOutline && !this.isLink;
6973
}
7074

7175
get isIconButton() {
@@ -75,10 +79,10 @@ class Button extends PureComponent<Props, ButtonState> {
7579

7680
getBackgroundColor() {
7781
const {backgroundColor: themeBackgroundColor, modifiers} = this.props;
78-
const {disabled, outline, link, disabledBackgroundColor, backgroundColor: propsBackgroundColor} = this.props;
82+
const {disabled, outline, disabledBackgroundColor, backgroundColor: propsBackgroundColor} = this.props;
7983
const {backgroundColor: stateBackgroundColor} = modifiers;
8084

81-
if (!outline && !link) {
85+
if (!outline && !this.isLink) {
8286
if (disabled) {
8387
return disabledBackgroundColor || DISABLED_COLOR;
8488
}
@@ -97,18 +101,19 @@ class Button extends PureComponent<Props, ButtonState> {
97101
}
98102

99103
getLabelColor() {
100-
const {link, linkColor, outline, outlineColor, disabled, color: propsColor} = this.props;
104+
const {linkColor, outline, outlineColor, disabled, color: propsColor} = this.props;
105+
const isLink = this.isLink;
101106

102107
let color: string | undefined = Colors.white;
103-
if (link) {
108+
if (isLink) {
104109
color = linkColor || Colors.primary;
105110
} else if (outline) {
106111
color = outlineColor || Colors.primary;
107112
} else if (this.isIconButton) {
108113
color = undefined; // Colors.grey10;
109114
}
110115

111-
if (disabled && (link || outline)) {
116+
if (disabled && (isLink || outline)) {
112117
return DISABLED_COLOR;
113118
}
114119

@@ -130,7 +135,7 @@ class Button extends PureComponent<Props, ButtonState> {
130135
}
131136

132137
getContainerSizeStyle() {
133-
const {outline, link, avoidMinWidth, avoidInnerPadding, round} = this.props;
138+
const {outline, avoidMinWidth, avoidInnerPadding, round} = this.props;
134139
const size = this.props.size || DEFAULT_SIZE;
135140
const outlineWidth = this.props.outlineWidth || 1;
136141

@@ -177,7 +182,7 @@ class Button extends PureComponent<Props, ButtonState> {
177182

178183
const containerSizeStyle = CONTAINER_STYLE_BY_SIZE[size];
179184

180-
if (link || (this.isIconButton && !round)) {
185+
if (this.isLink || (this.isIconButton && !round)) {
181186
containerSizeStyle.paddingVertical = undefined;
182187
containerSizeStyle.paddingHorizontal = undefined;
183188
containerSizeStyle.minWidth = undefined;
@@ -196,10 +201,10 @@ class Button extends PureComponent<Props, ButtonState> {
196201
}
197202

198203
getOutlineStyle() {
199-
const {outline, outlineColor, outlineWidth, link, disabled} = this.props;
204+
const {outline, outlineColor, outlineWidth, disabled} = this.props;
200205

201206
let outlineStyle;
202-
if ((outline || outlineColor) && !link) {
207+
if ((outline || outlineColor) && !this.isLink) {
203208
outlineStyle = {
204209
borderWidth: outlineWidth || 1,
205210
borderColor: outlineColor || Colors.primary
@@ -213,9 +218,9 @@ class Button extends PureComponent<Props, ButtonState> {
213218
}
214219

215220
getBorderRadiusStyle() {
216-
const {link, fullWidth, borderRadius: borderRadiusFromProps, modifiers} = this.props;
221+
const {fullWidth, borderRadius: borderRadiusFromProps, modifiers} = this.props;
217222

218-
if (link || fullWidth || borderRadiusFromProps === 0) {
223+
if (this.isLink || fullWidth || borderRadiusFromProps === 0) {
219224
return {borderRadius: 0};
220225
}
221226

@@ -290,7 +295,7 @@ class Button extends PureComponent<Props, ButtonState> {
290295
}
291296

292297
renderLabel() {
293-
const {label, labelStyle, labelProps} = this.props;
298+
const {label, labelStyle, labelProps, hyperlink} = this.props;
294299
const typography = extractTypographyValue(this.props);
295300
const color = this.getLabelColor();
296301
const labelSizeStyle = this.getLabelSizeStyle();
@@ -299,6 +304,7 @@ class Button extends PureComponent<Props, ButtonState> {
299304
return (
300305
<Text
301306
style={[this.styles.text, !!color && {color}, labelSizeStyle, {...typography}, labelStyle]}
307+
underline={hyperlink}
302308
numberOfLines={1}
303309
{...labelProps}
304310
>
@@ -310,7 +316,7 @@ class Button extends PureComponent<Props, ButtonState> {
310316
}
311317

312318
render() {
313-
const {onPress, disabled, link, style, testID, animateLayout, modifiers, forwardedRef, ...others} = this.props;
319+
const {onPress, disabled, style, testID, animateLayout, modifiers, forwardedRef, ...others} = this.props;
314320
const shadowStyle = this.getShadowStyle();
315321
const {margins} = modifiers;
316322
const backgroundColor = this.getBackgroundColor();
@@ -326,7 +332,7 @@ class Button extends PureComponent<Props, ButtonState> {
326332
this.styles.container,
327333
animateLayout && this.getAnimationDirectionStyle(),
328334
containerSizeStyle,
329-
link && this.styles.innerContainerLink,
335+
this.isLink && this.styles.innerContainerLink,
330336
shadowStyle,
331337
margins,
332338
backgroundColor && {backgroundColor},

0 commit comments

Comments
 (0)