@telus-uds/components-community.content-card 1.0.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.
- package/CHANGELOG.md +16 -0
- package/lib/ContentCard.js +209 -0
- package/lib/index.js +19 -0
- package/lib/index.native.js +19 -0
- package/lib-module/ContentCard.js +184 -0
- package/lib-module/index.js +3 -0
- package/lib-module/index.native.js +3 -0
- package/package.json +48 -0
- package/src/ContentCard.jsx +177 -0
- package/src/index.js +5 -0
- package/src/index.native.js +5 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Change Log - @telus-uds/components-community.content-card
|
|
2
|
+
|
|
3
|
+
This log was last generated on Thu, 26 Oct 2023 19:24:58 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
<!-- Start content -->
|
|
6
|
+
|
|
7
|
+
## 1.0.0
|
|
8
|
+
|
|
9
|
+
Thu, 26 Oct 2023 19:24:58 GMT
|
|
10
|
+
|
|
11
|
+
### Major changes
|
|
12
|
+
|
|
13
|
+
- content card component (srikanthkhari@gmail.com)
|
|
14
|
+
- Bump @telus-uds/components-base to v1.65.0
|
|
15
|
+
- Bump @telus-uds/browserslist-config to v1.0.5
|
|
16
|
+
- Bump @telus-uds/system-theme-tokens to v2.42.0
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.styles = exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _componentsBase = require("@telus-uds/components-base");
|
|
13
|
+
|
|
14
|
+
var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
|
|
15
|
+
|
|
16
|
+
var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
|
|
17
|
+
|
|
18
|
+
var _ImageBackground = _interopRequireDefault(require("react-native-web/dist/cjs/exports/ImageBackground"));
|
|
19
|
+
|
|
20
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
|
+
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
24
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
25
|
+
|
|
26
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
27
|
+
|
|
28
|
+
/* eslint-disable react/require-default-props */
|
|
29
|
+
const styles = _StyleSheet.default.create({
|
|
30
|
+
rowReverse: {
|
|
31
|
+
flexDirection: 'row-reverse'
|
|
32
|
+
},
|
|
33
|
+
innerContainer: {
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
justifyContent: 'space-between',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
width: 'auto'
|
|
39
|
+
},
|
|
40
|
+
informationContainer: {
|
|
41
|
+
width: '65%'
|
|
42
|
+
}
|
|
43
|
+
}); // Passes React Native-oriented system props through UDS PressableCardBase
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
exports.styles = styles;
|
|
47
|
+
const [selectProps, selectedSystemPropTypes] = (0, _componentsBase.selectSystemProps)([_componentsBase.a11yProps, _componentsBase.focusHandlerProps, _componentsBase.viewProps]);
|
|
48
|
+
const ContentCard = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
49
|
+
let {
|
|
50
|
+
title,
|
|
51
|
+
content,
|
|
52
|
+
linkText,
|
|
53
|
+
onPress,
|
|
54
|
+
href,
|
|
55
|
+
customImage,
|
|
56
|
+
imageSrc,
|
|
57
|
+
imageHeight,
|
|
58
|
+
imageWidth,
|
|
59
|
+
isContentOnRight,
|
|
60
|
+
tokens,
|
|
61
|
+
...rest
|
|
62
|
+
} = _ref;
|
|
63
|
+
const viewport = (0, _componentsBase.useViewport)();
|
|
64
|
+
const innerContainerStyle = isContentOnRight ? [styles.innerContainer, styles.rowReverse] : styles.innerContainer;
|
|
65
|
+
const generalTokens = (0, _componentsBase.useThemeTokens)('ContentCard', tokens);
|
|
66
|
+
const getTokens = (0, _componentsBase.useThemeTokensCallback)('ContentCard', tokens);
|
|
67
|
+
const cardTokens = (0, _componentsBase.useThemeTokens)('Card', tokens, {}, {
|
|
68
|
+
viewport
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const {
|
|
72
|
+
hrefAttrs,
|
|
73
|
+
rest: unusedRest
|
|
74
|
+
} = _componentsBase.hrefAttrsProp.bundle(rest);
|
|
75
|
+
|
|
76
|
+
const getPressableCardTokens = cardState => {
|
|
77
|
+
return { ...cardTokens,
|
|
78
|
+
...getTokens(cardState)
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.PressableCardBase, {
|
|
83
|
+
ref: ref,
|
|
84
|
+
onPress: onPress,
|
|
85
|
+
href: href,
|
|
86
|
+
hrefAttrs: hrefAttrs,
|
|
87
|
+
tokens: getPressableCardTokens,
|
|
88
|
+
...selectProps(unusedRest),
|
|
89
|
+
children: cardState => {
|
|
90
|
+
const {
|
|
91
|
+
borderWidth
|
|
92
|
+
} = getPressableCardTokens(cardState); // Stop content jumping around as border size changes
|
|
93
|
+
|
|
94
|
+
const borderOffset = borderWidth - generalTokens.borderWidth;
|
|
95
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Box, {
|
|
96
|
+
horizontal: {
|
|
97
|
+
xs: 4,
|
|
98
|
+
lg: 5,
|
|
99
|
+
options: {
|
|
100
|
+
subtract: borderOffset
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
vertical: {
|
|
104
|
+
xs: 5,
|
|
105
|
+
lg: 7,
|
|
106
|
+
options: {
|
|
107
|
+
subtract: borderOffset
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
|
|
111
|
+
style: innerContainerStyle,
|
|
112
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
|
|
113
|
+
style: styles.informationContainer,
|
|
114
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
|
|
115
|
+
heading: "h3",
|
|
116
|
+
variant: {
|
|
117
|
+
bold: true,
|
|
118
|
+
colour: 'brand'
|
|
119
|
+
},
|
|
120
|
+
children: title
|
|
121
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Spacer, {
|
|
122
|
+
space: 1
|
|
123
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
|
|
124
|
+
variant: {
|
|
125
|
+
size: 'small'
|
|
126
|
+
},
|
|
127
|
+
children: content
|
|
128
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Spacer, {
|
|
129
|
+
space: 3
|
|
130
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.ChevronLink, {
|
|
131
|
+
disabled: true,
|
|
132
|
+
children: linkText
|
|
133
|
+
})]
|
|
134
|
+
}), customImage || /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImageBackground.default, {
|
|
135
|
+
source: imageSrc // eslint-disable-next-line react-native/no-inline-styles
|
|
136
|
+
,
|
|
137
|
+
style: {
|
|
138
|
+
flex: 1,
|
|
139
|
+
aspectRatio: imageWidth / imageHeight,
|
|
140
|
+
maxHeight: imageHeight,
|
|
141
|
+
maxWidth: imageWidth
|
|
142
|
+
},
|
|
143
|
+
resizeMode: "cover"
|
|
144
|
+
})]
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
ContentCard.displayName = 'ContentCard';
|
|
151
|
+
ContentCard.propTypes = { ...selectedSystemPropTypes,
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The URL to be navigated to.
|
|
155
|
+
*/
|
|
156
|
+
href: _propTypes.default.string,
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Text stating the title or headline.
|
|
160
|
+
*/
|
|
161
|
+
title: _propTypes.default.string.isRequired,
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Text giving a short content of the card. One paragraph of plain text.
|
|
165
|
+
*/
|
|
166
|
+
content: _propTypes.default.string.isRequired,
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Text for the ChevronLink.
|
|
170
|
+
*/
|
|
171
|
+
linkText: _propTypes.default.string.isRequired,
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Optional function to be called on press e.g. for within-page navigation.
|
|
175
|
+
*/
|
|
176
|
+
onPress: _propTypes.default.func,
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Src of the Image.
|
|
180
|
+
*/
|
|
181
|
+
imageSrc: _propTypes.default.string,
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Height of the Image.
|
|
185
|
+
*/
|
|
186
|
+
imageHeight: _propTypes.default.number,
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Width of the Image.
|
|
190
|
+
*/
|
|
191
|
+
imageWidth: _propTypes.default.number,
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Custom Image to be used instead of the default image.
|
|
195
|
+
*/
|
|
196
|
+
customImage: _propTypes.default.node,
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Controls if the content is on the right side of the image.
|
|
200
|
+
*/
|
|
201
|
+
isContentOnRight: _propTypes.default.bool
|
|
202
|
+
};
|
|
203
|
+
ContentCard.defaultProps = {
|
|
204
|
+
isContentOnRight: false
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
var _default = (0, _componentsBase.withLinkRouter)(ContentCard);
|
|
208
|
+
|
|
209
|
+
exports.default = _default;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "ContentCard", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _ContentCard.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.default = void 0;
|
|
13
|
+
|
|
14
|
+
var _ContentCard = _interopRequireDefault(require("./ContentCard"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
var _default = _ContentCard.default;
|
|
19
|
+
exports.default = _default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "ContentCard", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _ContentCard.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.default = void 0;
|
|
13
|
+
|
|
14
|
+
var _ContentCard = _interopRequireDefault(require("./ContentCard"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
var _default = _ContentCard.default;
|
|
19
|
+
exports.default = _default;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { Typography, Spacer, ChevronLink, PressableCardBase, selectSystemProps, hrefAttrsProp, withLinkRouter, a11yProps, focusHandlerProps, useThemeTokensCallback, useViewport, useThemeTokens, Box, viewProps } from '@telus-uds/components-base';
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
|
+
import View from "react-native-web/dist/exports/View";
|
|
7
|
+
import ImageBackground from "react-native-web/dist/exports/ImageBackground";
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
export const styles = StyleSheet.create({
|
|
11
|
+
rowReverse: {
|
|
12
|
+
flexDirection: 'row-reverse'
|
|
13
|
+
},
|
|
14
|
+
innerContainer: {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
flexDirection: 'row',
|
|
17
|
+
justifyContent: 'space-between',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
width: 'auto'
|
|
20
|
+
},
|
|
21
|
+
informationContainer: {
|
|
22
|
+
width: '65%'
|
|
23
|
+
}
|
|
24
|
+
}); // Passes React Native-oriented system props through UDS PressableCardBase
|
|
25
|
+
|
|
26
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
27
|
+
const ContentCard = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
28
|
+
let {
|
|
29
|
+
title,
|
|
30
|
+
content,
|
|
31
|
+
linkText,
|
|
32
|
+
onPress,
|
|
33
|
+
href,
|
|
34
|
+
customImage,
|
|
35
|
+
imageSrc,
|
|
36
|
+
imageHeight,
|
|
37
|
+
imageWidth,
|
|
38
|
+
isContentOnRight,
|
|
39
|
+
tokens,
|
|
40
|
+
...rest
|
|
41
|
+
} = _ref;
|
|
42
|
+
const viewport = useViewport();
|
|
43
|
+
const innerContainerStyle = isContentOnRight ? [styles.innerContainer, styles.rowReverse] : styles.innerContainer;
|
|
44
|
+
const generalTokens = useThemeTokens('ContentCard', tokens);
|
|
45
|
+
const getTokens = useThemeTokensCallback('ContentCard', tokens);
|
|
46
|
+
const cardTokens = useThemeTokens('Card', tokens, {}, {
|
|
47
|
+
viewport
|
|
48
|
+
});
|
|
49
|
+
const {
|
|
50
|
+
hrefAttrs,
|
|
51
|
+
rest: unusedRest
|
|
52
|
+
} = hrefAttrsProp.bundle(rest);
|
|
53
|
+
|
|
54
|
+
const getPressableCardTokens = cardState => {
|
|
55
|
+
return { ...cardTokens,
|
|
56
|
+
...getTokens(cardState)
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return /*#__PURE__*/_jsx(PressableCardBase, {
|
|
61
|
+
ref: ref,
|
|
62
|
+
onPress: onPress,
|
|
63
|
+
href: href,
|
|
64
|
+
hrefAttrs: hrefAttrs,
|
|
65
|
+
tokens: getPressableCardTokens,
|
|
66
|
+
...selectProps(unusedRest),
|
|
67
|
+
children: cardState => {
|
|
68
|
+
const {
|
|
69
|
+
borderWidth
|
|
70
|
+
} = getPressableCardTokens(cardState); // Stop content jumping around as border size changes
|
|
71
|
+
|
|
72
|
+
const borderOffset = borderWidth - generalTokens.borderWidth;
|
|
73
|
+
return /*#__PURE__*/_jsx(Box, {
|
|
74
|
+
horizontal: {
|
|
75
|
+
xs: 4,
|
|
76
|
+
lg: 5,
|
|
77
|
+
options: {
|
|
78
|
+
subtract: borderOffset
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
vertical: {
|
|
82
|
+
xs: 5,
|
|
83
|
+
lg: 7,
|
|
84
|
+
options: {
|
|
85
|
+
subtract: borderOffset
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
89
|
+
style: innerContainerStyle,
|
|
90
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
91
|
+
style: styles.informationContainer,
|
|
92
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
93
|
+
heading: "h3",
|
|
94
|
+
variant: {
|
|
95
|
+
bold: true,
|
|
96
|
+
colour: 'brand'
|
|
97
|
+
},
|
|
98
|
+
children: title
|
|
99
|
+
}), /*#__PURE__*/_jsx(Spacer, {
|
|
100
|
+
space: 1
|
|
101
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
102
|
+
variant: {
|
|
103
|
+
size: 'small'
|
|
104
|
+
},
|
|
105
|
+
children: content
|
|
106
|
+
}), /*#__PURE__*/_jsx(Spacer, {
|
|
107
|
+
space: 3
|
|
108
|
+
}), /*#__PURE__*/_jsx(ChevronLink, {
|
|
109
|
+
disabled: true,
|
|
110
|
+
children: linkText
|
|
111
|
+
})]
|
|
112
|
+
}), customImage || /*#__PURE__*/_jsx(ImageBackground, {
|
|
113
|
+
source: imageSrc // eslint-disable-next-line react-native/no-inline-styles
|
|
114
|
+
,
|
|
115
|
+
style: {
|
|
116
|
+
flex: 1,
|
|
117
|
+
aspectRatio: imageWidth / imageHeight,
|
|
118
|
+
maxHeight: imageHeight,
|
|
119
|
+
maxWidth: imageWidth
|
|
120
|
+
},
|
|
121
|
+
resizeMode: "cover"
|
|
122
|
+
})]
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
ContentCard.displayName = 'ContentCard';
|
|
129
|
+
ContentCard.propTypes = { ...selectedSystemPropTypes,
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The URL to be navigated to.
|
|
133
|
+
*/
|
|
134
|
+
href: PropTypes.string,
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Text stating the title or headline.
|
|
138
|
+
*/
|
|
139
|
+
title: PropTypes.string.isRequired,
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Text giving a short content of the card. One paragraph of plain text.
|
|
143
|
+
*/
|
|
144
|
+
content: PropTypes.string.isRequired,
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Text for the ChevronLink.
|
|
148
|
+
*/
|
|
149
|
+
linkText: PropTypes.string.isRequired,
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Optional function to be called on press e.g. for within-page navigation.
|
|
153
|
+
*/
|
|
154
|
+
onPress: PropTypes.func,
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Src of the Image.
|
|
158
|
+
*/
|
|
159
|
+
imageSrc: PropTypes.string,
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Height of the Image.
|
|
163
|
+
*/
|
|
164
|
+
imageHeight: PropTypes.number,
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Width of the Image.
|
|
168
|
+
*/
|
|
169
|
+
imageWidth: PropTypes.number,
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Custom Image to be used instead of the default image.
|
|
173
|
+
*/
|
|
174
|
+
customImage: PropTypes.node,
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Controls if the content is on the right side of the image.
|
|
178
|
+
*/
|
|
179
|
+
isContentOnRight: PropTypes.bool
|
|
180
|
+
};
|
|
181
|
+
ContentCard.defaultProps = {
|
|
182
|
+
isContentOnRight: false
|
|
183
|
+
};
|
|
184
|
+
export default withLinkRouter(ContentCard);
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "TELUS Digital",
|
|
3
|
+
"browserslist": [
|
|
4
|
+
"extends @telus-uds/browserslist-config"
|
|
5
|
+
],
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"prop-types": "^15.7.2",
|
|
8
|
+
"@telus-uds/components-base": "^1.65.0"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@telus-uds/browserslist-config": "^1.0.4",
|
|
12
|
+
"babel-plugin-styled-components": "^2.0.6",
|
|
13
|
+
"jest-styled-components": "^7.0.8",
|
|
14
|
+
"babel-plugin-react-native-web": "^0.17.0",
|
|
15
|
+
"@testing-library/react-native": "11.0.0",
|
|
16
|
+
"@telus-uds/system-theme-tokens": "^2.42.0"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/telus/universal-design-system#readme",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"name": "@telus-uds/components-community.content-card",
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"react-native-web": "~0.17.7 || ~0.18.7",
|
|
23
|
+
"react-native": "*",
|
|
24
|
+
"react": "^17.0.2 || ^18.0.0",
|
|
25
|
+
"react-dom": "^17.0.2 || ^18.0.0"
|
|
26
|
+
},
|
|
27
|
+
"main": "lib/index.js",
|
|
28
|
+
"module": "lib-module/index.js",
|
|
29
|
+
"react-native": "src/index.js",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/telus/universal-design-system.git"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"format": "prettier --write .",
|
|
36
|
+
"lint": "telus-standard",
|
|
37
|
+
"lint:fix": "telus-standard --fix",
|
|
38
|
+
"test": "jest",
|
|
39
|
+
"build:main": "babel src -d lib",
|
|
40
|
+
"build:module": "babel src -d lib-module --env-name module",
|
|
41
|
+
"build": "npm run build:main && npm run build:module"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"standard-engine": {
|
|
45
|
+
"skip": true
|
|
46
|
+
},
|
|
47
|
+
"version": "1.0.0"
|
|
48
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
2
|
+
import React, { forwardRef } from 'react'
|
|
3
|
+
import PropTypes from 'prop-types'
|
|
4
|
+
import {
|
|
5
|
+
Typography,
|
|
6
|
+
Spacer,
|
|
7
|
+
ChevronLink,
|
|
8
|
+
PressableCardBase,
|
|
9
|
+
selectSystemProps,
|
|
10
|
+
hrefAttrsProp,
|
|
11
|
+
withLinkRouter,
|
|
12
|
+
a11yProps,
|
|
13
|
+
focusHandlerProps,
|
|
14
|
+
useThemeTokensCallback,
|
|
15
|
+
useViewport,
|
|
16
|
+
useThemeTokens,
|
|
17
|
+
Box,
|
|
18
|
+
viewProps
|
|
19
|
+
} from '@telus-uds/components-base'
|
|
20
|
+
import { StyleSheet, View, ImageBackground } from 'react-native'
|
|
21
|
+
|
|
22
|
+
export const styles = StyleSheet.create({
|
|
23
|
+
rowReverse: {
|
|
24
|
+
flexDirection: 'row-reverse'
|
|
25
|
+
},
|
|
26
|
+
innerContainer: {
|
|
27
|
+
display: 'flex',
|
|
28
|
+
flexDirection: 'row',
|
|
29
|
+
justifyContent: 'space-between',
|
|
30
|
+
alignItems: 'center',
|
|
31
|
+
width: 'auto'
|
|
32
|
+
},
|
|
33
|
+
informationContainer: {
|
|
34
|
+
width: '65%'
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// Passes React Native-oriented system props through UDS PressableCardBase
|
|
39
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
40
|
+
a11yProps,
|
|
41
|
+
focusHandlerProps,
|
|
42
|
+
viewProps
|
|
43
|
+
])
|
|
44
|
+
|
|
45
|
+
const ContentCard = forwardRef(
|
|
46
|
+
(
|
|
47
|
+
{
|
|
48
|
+
title,
|
|
49
|
+
content,
|
|
50
|
+
linkText,
|
|
51
|
+
onPress,
|
|
52
|
+
href,
|
|
53
|
+
customImage,
|
|
54
|
+
imageSrc,
|
|
55
|
+
imageHeight,
|
|
56
|
+
imageWidth,
|
|
57
|
+
isContentOnRight,
|
|
58
|
+
tokens,
|
|
59
|
+
...rest
|
|
60
|
+
},
|
|
61
|
+
ref
|
|
62
|
+
) => {
|
|
63
|
+
const viewport = useViewport()
|
|
64
|
+
const innerContainerStyle = isContentOnRight
|
|
65
|
+
? [styles.innerContainer, styles.rowReverse]
|
|
66
|
+
: styles.innerContainer
|
|
67
|
+
const generalTokens = useThemeTokens('ContentCard', tokens)
|
|
68
|
+
const getTokens = useThemeTokensCallback('ContentCard', tokens)
|
|
69
|
+
const cardTokens = useThemeTokens('Card', tokens, {}, { viewport })
|
|
70
|
+
const { hrefAttrs, rest: unusedRest } = hrefAttrsProp.bundle(rest)
|
|
71
|
+
const getPressableCardTokens = (cardState) => {
|
|
72
|
+
return { ...cardTokens, ...getTokens(cardState) }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<PressableCardBase
|
|
77
|
+
ref={ref}
|
|
78
|
+
onPress={onPress}
|
|
79
|
+
href={href}
|
|
80
|
+
hrefAttrs={hrefAttrs}
|
|
81
|
+
tokens={getPressableCardTokens}
|
|
82
|
+
{...selectProps(unusedRest)}
|
|
83
|
+
>
|
|
84
|
+
{(cardState) => {
|
|
85
|
+
const { borderWidth } = getPressableCardTokens(cardState)
|
|
86
|
+
|
|
87
|
+
// Stop content jumping around as border size changes
|
|
88
|
+
const borderOffset = borderWidth - generalTokens.borderWidth
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<Box
|
|
92
|
+
horizontal={{ xs: 4, lg: 5, options: { subtract: borderOffset } }}
|
|
93
|
+
vertical={{ xs: 5, lg: 7, options: { subtract: borderOffset } }}
|
|
94
|
+
>
|
|
95
|
+
<View style={innerContainerStyle}>
|
|
96
|
+
<View style={styles.informationContainer}>
|
|
97
|
+
<Typography heading="h3" variant={{ bold: true, colour: 'brand' }}>
|
|
98
|
+
{title}
|
|
99
|
+
</Typography>
|
|
100
|
+
<Spacer space={1} />
|
|
101
|
+
<Typography variant={{ size: 'small' }}>{content}</Typography>
|
|
102
|
+
<Spacer space={3} />
|
|
103
|
+
<ChevronLink disabled>{linkText}</ChevronLink>
|
|
104
|
+
</View>
|
|
105
|
+
{customImage || (
|
|
106
|
+
<ImageBackground
|
|
107
|
+
source={imageSrc}
|
|
108
|
+
// eslint-disable-next-line react-native/no-inline-styles
|
|
109
|
+
style={{
|
|
110
|
+
flex: 1,
|
|
111
|
+
aspectRatio: imageWidth / imageHeight,
|
|
112
|
+
maxHeight: imageHeight,
|
|
113
|
+
maxWidth: imageWidth
|
|
114
|
+
}}
|
|
115
|
+
resizeMode="cover"
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
118
|
+
</View>
|
|
119
|
+
</Box>
|
|
120
|
+
)
|
|
121
|
+
}}
|
|
122
|
+
</PressableCardBase>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
ContentCard.displayName = 'ContentCard'
|
|
128
|
+
|
|
129
|
+
ContentCard.propTypes = {
|
|
130
|
+
...selectedSystemPropTypes,
|
|
131
|
+
/**
|
|
132
|
+
* The URL to be navigated to.
|
|
133
|
+
*/
|
|
134
|
+
href: PropTypes.string,
|
|
135
|
+
/**
|
|
136
|
+
* Text stating the title or headline.
|
|
137
|
+
*/
|
|
138
|
+
title: PropTypes.string.isRequired,
|
|
139
|
+
/**
|
|
140
|
+
* Text giving a short content of the card. One paragraph of plain text.
|
|
141
|
+
*/
|
|
142
|
+
content: PropTypes.string.isRequired,
|
|
143
|
+
/**
|
|
144
|
+
* Text for the ChevronLink.
|
|
145
|
+
*/
|
|
146
|
+
linkText: PropTypes.string.isRequired,
|
|
147
|
+
/**
|
|
148
|
+
* Optional function to be called on press e.g. for within-page navigation.
|
|
149
|
+
*/
|
|
150
|
+
onPress: PropTypes.func,
|
|
151
|
+
/**
|
|
152
|
+
* Src of the Image.
|
|
153
|
+
*/
|
|
154
|
+
imageSrc: PropTypes.string,
|
|
155
|
+
/**
|
|
156
|
+
* Height of the Image.
|
|
157
|
+
*/
|
|
158
|
+
imageHeight: PropTypes.number,
|
|
159
|
+
/**
|
|
160
|
+
* Width of the Image.
|
|
161
|
+
*/
|
|
162
|
+
imageWidth: PropTypes.number,
|
|
163
|
+
/**
|
|
164
|
+
* Custom Image to be used instead of the default image.
|
|
165
|
+
*/
|
|
166
|
+
customImage: PropTypes.node,
|
|
167
|
+
/**
|
|
168
|
+
* Controls if the content is on the right side of the image.
|
|
169
|
+
*/
|
|
170
|
+
isContentOnRight: PropTypes.bool
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
ContentCard.defaultProps = {
|
|
174
|
+
isContentOnRight: false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export default withLinkRouter(ContentCard)
|
package/src/index.js
ADDED