@telus-uds/components-web 2.25.1 → 2.27.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 +33 -3
- package/lib/Card/Card.js +46 -29
- package/lib/DatePicker/DatePicker.js +129 -69
- package/lib/OptimizeImage/OptimizeImage.js +1 -1
- package/lib/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/lib/baseExports.js +6 -0
- package/lib-module/Card/Card.js +49 -31
- package/lib-module/DatePicker/DatePicker.js +132 -72
- package/lib-module/OptimizeImage/OptimizeImage.js +1 -1
- package/lib-module/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/lib-module/baseExports.js +1 -1
- package/package.json +3 -3
- package/src/Card/Card.jsx +47 -29
- package/src/DatePicker/DatePicker.jsx +125 -63
- package/src/OptimizeImage/OptimizeImage.jsx +1 -1
- package/src/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/src/baseExports.js +1 -0
- package/types/MultiSelectFilter.d.ts +2 -1
- package/types/WebVideo.d.ts +4 -3
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React, { forwardRef, useEffect, useState } from 'react';
|
|
1
|
+
import React, { forwardRef, useEffect, useState, useRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import momentPropTypes from 'react-moment-proptypes';
|
|
5
5
|
import 'react-dates/initialize';
|
|
6
6
|
import SingleDatePicker from 'react-dates/lib/components/SingleDatePicker';
|
|
7
7
|
import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerSingleDateController';
|
|
8
|
-
import { IconButton, TextInput, selectSystemProps, useCopy, useViewport, useThemeTokens, applyTextStyles, getTokensPropType } from '@telus-uds/components-base';
|
|
8
|
+
import { IconButton, TextInput, selectSystemProps, useCopy, useViewport, useThemeTokens, applyTextStyles, getTokensPropType, Portal, useSafeLayoutEffect } from '@telus-uds/components-base';
|
|
9
9
|
import moment from 'moment';
|
|
10
|
-
import { isUndefined } from 'lodash';
|
|
10
|
+
import { isUndefined, throttle } from 'lodash';
|
|
11
11
|
import CalendarContainer from './CalendarContainer';
|
|
12
12
|
import dictionary from './dictionary';
|
|
13
13
|
import { htmlAttrs } from '../utils';
|
|
@@ -47,6 +47,24 @@ const DateInputWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
|
47
47
|
display: 'flex',
|
|
48
48
|
flexDirection: 'column'
|
|
49
49
|
});
|
|
50
|
+
const PortalPositionedContainer = /*#__PURE__*/styled.div.withConfig({
|
|
51
|
+
displayName: "DatePicker__PortalPositionedContainer",
|
|
52
|
+
componentId: "components-web__sc-mz8fi3-2"
|
|
53
|
+
})({
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
left: _ref => {
|
|
56
|
+
let {
|
|
57
|
+
left
|
|
58
|
+
} = _ref;
|
|
59
|
+
return `${left}px`;
|
|
60
|
+
},
|
|
61
|
+
top: _ref2 => {
|
|
62
|
+
let {
|
|
63
|
+
top
|
|
64
|
+
} = _ref2;
|
|
65
|
+
return `${top}px`;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
50
68
|
|
|
51
69
|
/**
|
|
52
70
|
* Use DatePicker to select a date on a calendar.
|
|
@@ -69,7 +87,7 @@ const DateInputWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
|
69
87
|
* - Optimized for keyboard interaction and tablet touch
|
|
70
88
|
* - Recommended for viewports greater than or equal to 576px
|
|
71
89
|
*/
|
|
72
|
-
const DatePicker = /*#__PURE__*/forwardRef((
|
|
90
|
+
const DatePicker = /*#__PURE__*/forwardRef((_ref3, ref) => {
|
|
73
91
|
var _dictionary$copy;
|
|
74
92
|
let {
|
|
75
93
|
copy = 'en',
|
|
@@ -90,9 +108,33 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
90
108
|
prevTestID,
|
|
91
109
|
nextTestID,
|
|
92
110
|
...rest
|
|
93
|
-
} =
|
|
111
|
+
} = _ref3;
|
|
94
112
|
const [inputDate, setInputDate] = useState(date instanceof moment ? date : undefined);
|
|
95
113
|
const [inputText, setInputText] = useState(date instanceof moment ? date.format(dateFormat) : '');
|
|
114
|
+
const textInputRef = useRef();
|
|
115
|
+
const [datePickerPosition, setDatePickerPosition] = useState({
|
|
116
|
+
left: 0,
|
|
117
|
+
top: 0
|
|
118
|
+
});
|
|
119
|
+
useSafeLayoutEffect(() => {
|
|
120
|
+
const updateDimensions = () => {
|
|
121
|
+
if (inline) return;
|
|
122
|
+
const {
|
|
123
|
+
left,
|
|
124
|
+
top
|
|
125
|
+
} = textInputRef.current.getBoundingClientRect();
|
|
126
|
+
setDatePickerPosition({
|
|
127
|
+
left,
|
|
128
|
+
top: top + textInputRef.current.offsetHeight
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const throttledUpdateDimensions = throttle(updateDimensions, 100, {
|
|
132
|
+
leading: false
|
|
133
|
+
});
|
|
134
|
+
updateDimensions();
|
|
135
|
+
window.addEventListener('resize', throttledUpdateDimensions);
|
|
136
|
+
return () => window.removeEventListener('resize', throttledUpdateDimensions);
|
|
137
|
+
}, []);
|
|
96
138
|
const [isFocused, setIsFocused] = useState(false);
|
|
97
139
|
const [isClickedInside, setIsClickedInside] = useState(false);
|
|
98
140
|
const getCopy = useCopy({
|
|
@@ -109,10 +151,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
109
151
|
setInputText(date instanceof moment ? date.format(dateFormat) : '');
|
|
110
152
|
}
|
|
111
153
|
}, [date, inputDate]);
|
|
112
|
-
const onFocusChange =
|
|
154
|
+
const onFocusChange = _ref4 => {
|
|
113
155
|
let {
|
|
114
156
|
focused
|
|
115
|
-
} =
|
|
157
|
+
} = _ref4;
|
|
116
158
|
if (!isClickedInside) {
|
|
117
159
|
setIsFocused(focused);
|
|
118
160
|
}
|
|
@@ -157,7 +199,7 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
157
199
|
const circleSize = getResponsiveCircleSize(inline, viewport);
|
|
158
200
|
const HiddenInputFieldContainer = /*#__PURE__*/styled.div.withConfig({
|
|
159
201
|
displayName: "DatePicker__HiddenInputFieldContainer",
|
|
160
|
-
componentId: "components-web__sc-mz8fi3-
|
|
202
|
+
componentId: "components-web__sc-mz8fi3-3"
|
|
161
203
|
})(["height:", ";width:", ";overflow:hidden;"], props => props.height, props => props.width);
|
|
162
204
|
const {
|
|
163
205
|
hiddenInputFieldContainerHeight,
|
|
@@ -183,10 +225,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
183
225
|
fontName: remainingTokens.dayPickerWeekHeaderFontName,
|
|
184
226
|
fontWeight: remainingTokens.dayPickerWeekHeaderFontWeight
|
|
185
227
|
});
|
|
186
|
-
const renderPrevButton =
|
|
228
|
+
const renderPrevButton = _ref5 => {
|
|
187
229
|
let {
|
|
188
230
|
onClick
|
|
189
|
-
} =
|
|
231
|
+
} = _ref5;
|
|
190
232
|
return /*#__PURE__*/_jsx(IconButton, {
|
|
191
233
|
onPress: () => {
|
|
192
234
|
onClick();
|
|
@@ -198,10 +240,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
198
240
|
testID: prevTestID
|
|
199
241
|
});
|
|
200
242
|
};
|
|
201
|
-
const renderNextButton =
|
|
243
|
+
const renderNextButton = _ref6 => {
|
|
202
244
|
let {
|
|
203
245
|
onClick
|
|
204
|
-
} =
|
|
246
|
+
} = _ref6;
|
|
205
247
|
return /*#__PURE__*/_jsx(IconButton, {
|
|
206
248
|
onPress: () => {
|
|
207
249
|
onClick();
|
|
@@ -213,18 +255,7 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
213
255
|
testID: nextTestID
|
|
214
256
|
});
|
|
215
257
|
};
|
|
216
|
-
return /*#__PURE__*/_jsx(
|
|
217
|
-
...selectProps(rest),
|
|
218
|
-
daySize: daySize,
|
|
219
|
-
validation: validation,
|
|
220
|
-
remainingTokens: {
|
|
221
|
-
...remainingTokens
|
|
222
|
-
},
|
|
223
|
-
calendarDayDefaultHeight: circleSize,
|
|
224
|
-
calendarDayDefaultWidth: circleSize,
|
|
225
|
-
calendarMonthFontTokens: calendarMonthFontTokens,
|
|
226
|
-
calendarWeekFontTokens: calendarWeekFontTokens,
|
|
227
|
-
defaultFontTokens: defaultFontTokens,
|
|
258
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
|
228
259
|
children: inline ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
229
260
|
children: [/*#__PURE__*/_jsx(HiddenInputFieldContainer, {
|
|
230
261
|
height: hiddenInputFieldContainerHeight,
|
|
@@ -236,68 +267,33 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
236
267
|
value: inputText,
|
|
237
268
|
readOnly: true
|
|
238
269
|
})
|
|
239
|
-
}), /*#__PURE__*/_jsx(
|
|
240
|
-
|
|
241
|
-
onDateChange: onChange,
|
|
242
|
-
focused: isFocused,
|
|
243
|
-
onFocusChange: onFocusChange,
|
|
244
|
-
numberOfMonths: 1,
|
|
245
|
-
hideKeyboardShortcutsPanel: true,
|
|
246
|
-
keepOpenOnDateSelect: false,
|
|
270
|
+
}), /*#__PURE__*/_jsx(CalendarContainer, {
|
|
271
|
+
...selectProps(rest),
|
|
247
272
|
daySize: daySize,
|
|
248
|
-
renderNavPrevButton: renderPrevButton,
|
|
249
|
-
renderNavNextButton: renderNextButton,
|
|
250
|
-
isOutsideRange: isDayDisabled,
|
|
251
|
-
phrases: getCopy(),
|
|
252
|
-
renderMonthElement: _ref5 => {
|
|
253
|
-
let {
|
|
254
|
-
month
|
|
255
|
-
} = _ref5;
|
|
256
|
-
return /*#__PURE__*/_jsx(MonthCenterContainer, {
|
|
257
|
-
children: /*#__PURE__*/_jsxs("div", {
|
|
258
|
-
children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
|
|
259
|
-
})
|
|
260
|
-
});
|
|
261
|
-
},
|
|
262
|
-
renderWeekHeaderElement: day => /*#__PURE__*/_jsx("div", {
|
|
263
|
-
children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
|
|
264
|
-
})
|
|
265
|
-
})]
|
|
266
|
-
}) : /*#__PURE__*/_jsx(DateInputWrapper, {
|
|
267
|
-
onMouseDown: handleMouseDown,
|
|
268
|
-
onFocus: handleFocus,
|
|
269
|
-
children: /*#__PURE__*/_jsx(TextInput, {
|
|
270
|
-
copy: copy,
|
|
271
|
-
feedback: feedback,
|
|
272
|
-
hint: hint,
|
|
273
|
-
placeholder: "DD / MM / YYYY",
|
|
274
|
-
onChange: onChangeInput,
|
|
275
|
-
tooltip: tooltip,
|
|
276
|
-
hintPosition: hintPosition,
|
|
277
|
-
label: ((_dictionary$copy = dictionary[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
|
|
278
|
-
value: inputText,
|
|
279
273
|
validation: validation,
|
|
280
|
-
|
|
281
|
-
|
|
274
|
+
remainingTokens: remainingTokens,
|
|
275
|
+
calendarDayDefaultHeight: circleSize,
|
|
276
|
+
calendarDayDefaultWidth: circleSize,
|
|
277
|
+
calendarMonthFontTokens: calendarMonthFontTokens,
|
|
278
|
+
calendarWeekFontTokens: calendarWeekFontTokens,
|
|
279
|
+
defaultFontTokens: defaultFontTokens,
|
|
280
|
+
children: /*#__PURE__*/_jsx(DayPickerSingleDateController, {
|
|
282
281
|
date: inputDate,
|
|
283
|
-
disabled: disabled,
|
|
284
282
|
onDateChange: onChange,
|
|
285
283
|
focused: isFocused,
|
|
286
284
|
onFocusChange: onFocusChange,
|
|
287
285
|
numberOfMonths: 1,
|
|
288
286
|
hideKeyboardShortcutsPanel: true,
|
|
289
|
-
keepOpenOnDateSelect:
|
|
287
|
+
keepOpenOnDateSelect: false,
|
|
290
288
|
daySize: daySize,
|
|
291
|
-
ref: ref,
|
|
292
289
|
renderNavPrevButton: renderPrevButton,
|
|
290
|
+
renderNavNextButton: renderNextButton,
|
|
293
291
|
isOutsideRange: isDayDisabled,
|
|
294
292
|
phrases: getCopy(),
|
|
295
|
-
|
|
296
|
-
renderNavNextButton: renderNextButton,
|
|
297
|
-
renderMonthElement: _ref6 => {
|
|
293
|
+
renderMonthElement: _ref7 => {
|
|
298
294
|
let {
|
|
299
295
|
month
|
|
300
|
-
} =
|
|
296
|
+
} = _ref7;
|
|
301
297
|
return /*#__PURE__*/_jsx(MonthCenterContainer, {
|
|
302
298
|
children: /*#__PURE__*/_jsxs("div", {
|
|
303
299
|
children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
|
|
@@ -308,6 +304,70 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
308
304
|
children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
|
|
309
305
|
})
|
|
310
306
|
})
|
|
307
|
+
})]
|
|
308
|
+
}) : /*#__PURE__*/_jsx(DateInputWrapper, {
|
|
309
|
+
onMouseDown: handleMouseDown,
|
|
310
|
+
onFocus: handleFocus,
|
|
311
|
+
children: /*#__PURE__*/_jsx(TextInput, {
|
|
312
|
+
copy: copy,
|
|
313
|
+
feedback: feedback,
|
|
314
|
+
hint: hint,
|
|
315
|
+
placeholder: "DD / MM / YYYY",
|
|
316
|
+
onChange: onChangeInput,
|
|
317
|
+
tooltip: tooltip,
|
|
318
|
+
hintPosition: hintPosition,
|
|
319
|
+
label: ((_dictionary$copy = dictionary[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
|
|
320
|
+
value: inputText,
|
|
321
|
+
validation: validation,
|
|
322
|
+
inactive: disabled,
|
|
323
|
+
ref: textInputRef,
|
|
324
|
+
children: /*#__PURE__*/_jsx(Portal, {
|
|
325
|
+
children: /*#__PURE__*/_jsx(PortalPositionedContainer, {
|
|
326
|
+
top: datePickerPosition.top,
|
|
327
|
+
left: datePickerPosition.left,
|
|
328
|
+
children: /*#__PURE__*/_jsx(CalendarContainer, {
|
|
329
|
+
...selectProps(rest),
|
|
330
|
+
daySize: daySize,
|
|
331
|
+
validation: validation,
|
|
332
|
+
remainingTokens: remainingTokens,
|
|
333
|
+
calendarDayDefaultHeight: circleSize,
|
|
334
|
+
calendarDayDefaultWidth: circleSize,
|
|
335
|
+
calendarMonthFontTokens: calendarMonthFontTokens,
|
|
336
|
+
calendarWeekFontTokens: calendarWeekFontTokens,
|
|
337
|
+
defaultFontTokens: defaultFontTokens,
|
|
338
|
+
children: /*#__PURE__*/_jsx(SingleDatePicker, {
|
|
339
|
+
date: inputDate,
|
|
340
|
+
disabled: disabled,
|
|
341
|
+
onDateChange: onChange,
|
|
342
|
+
focused: isFocused,
|
|
343
|
+
onFocusChange: onFocusChange,
|
|
344
|
+
numberOfMonths: 1,
|
|
345
|
+
hideKeyboardShortcutsPanel: true,
|
|
346
|
+
keepOpenOnDateSelect: true,
|
|
347
|
+
daySize: daySize,
|
|
348
|
+
ref: ref,
|
|
349
|
+
renderNavPrevButton: renderPrevButton,
|
|
350
|
+
isOutsideRange: isDayDisabled,
|
|
351
|
+
phrases: getCopy(),
|
|
352
|
+
id: id,
|
|
353
|
+
renderNavNextButton: renderNextButton,
|
|
354
|
+
renderMonthElement: _ref8 => {
|
|
355
|
+
let {
|
|
356
|
+
month
|
|
357
|
+
} = _ref8;
|
|
358
|
+
return /*#__PURE__*/_jsx(MonthCenterContainer, {
|
|
359
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
360
|
+
children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
|
|
361
|
+
})
|
|
362
|
+
});
|
|
363
|
+
},
|
|
364
|
+
renderWeekHeaderElement: day => /*#__PURE__*/_jsx("div", {
|
|
365
|
+
children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
|
|
366
|
+
})
|
|
367
|
+
})
|
|
368
|
+
})
|
|
369
|
+
})
|
|
370
|
+
})
|
|
311
371
|
})
|
|
312
372
|
})
|
|
313
373
|
});
|
|
@@ -33,7 +33,7 @@ const OptimizeImage = _ref => {
|
|
|
33
33
|
mdSrc: getOptimizedUrl(contentfulAssetUrl, dimension, md, quality, disableRetina, supportsWebp),
|
|
34
34
|
lgSrc: getOptimizedUrl(contentfulAssetUrl, dimension, lg, quality, disableRetina, supportsWebp),
|
|
35
35
|
xlSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xl, quality, disableRetina, supportsWebp),
|
|
36
|
-
fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
|
|
36
|
+
fallbackSrc: getFallbackUrl(contentfulAssetUrl, dimension, xl, quality)
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
}, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import isSvgUrl from './isSvgUrl';
|
|
2
|
-
export default function getFallbackUrl(url,
|
|
2
|
+
export default function getFallbackUrl(url, dimension, size, quality) {
|
|
3
3
|
if (!isSvgUrl(url)) {
|
|
4
|
-
return `${url}
|
|
4
|
+
return `${url}?${dimension}=${size}&q=${quality}`;
|
|
5
5
|
}
|
|
6
6
|
return url;
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ export {
|
|
|
5
5
|
/**
|
|
6
6
|
* Most base components should be re-exported as-is.
|
|
7
7
|
*/
|
|
8
|
-
A11yText, ActivityIndicator, Autocomplete, Box, Button, BaseProvider, A11yInfoProvider, ViewportProvider, ThemeProvider, ButtonDropdown, ButtonGroup, ButtonLink, Carousel, CarouselTabs, Checkbox, CheckboxGroup, ChevronLink, Divider, ExpandCollapse, Feedback, FlexGrid, Icon, InputLabel, InputSupports, Link, Listbox, Modal, MultiSelectFilter, Notification, Pagination, QuickLinks, QuickLinksFeature, Radio, RadioGroup, RadioCard, RadioCardGroup, Responsive, Search, Select, SideNav, Skeleton, SkipLink, Spacer, StackView, StackWrap, StepTracker, Tabs, Tags, TextButton, TextArea, TextInput, Timeline, ToggleSwitch, ToggleSwitchGroup, TooltipButton, Tooltip, Typography, Validator,
|
|
8
|
+
A11yText, ActivityIndicator, Autocomplete, Box, Button, BaseProvider, A11yInfoProvider, ViewportProvider, ThemeProvider, ButtonDropdown, ButtonGroup, ButtonLink, Carousel, CarouselTabs, Checkbox, CheckboxGroup, ChevronLink, ColourToggle, Divider, ExpandCollapse, Feedback, FlexGrid, Icon, InputLabel, InputSupports, Link, Listbox, Modal, MultiSelectFilter, Notification, Pagination, QuickLinks, QuickLinksFeature, Radio, RadioGroup, RadioCard, RadioCardGroup, Responsive, Search, Select, SideNav, Skeleton, SkipLink, Spacer, StackView, StackWrap, StepTracker, Tabs, Tags, TextButton, TextArea, TextInput, Timeline, ToggleSwitch, ToggleSwitchGroup, TooltipButton, Tooltip, Typography, Validator,
|
|
9
9
|
/*
|
|
10
10
|
* Most utilities exported from @telus-uds/components-base are for building systems, not apps.
|
|
11
11
|
* Re-export only those utilities with a stable API and known use cases within apps / pages.
|
package/package.json
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
],
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@gorhom/portal": "^1.0.14",
|
|
8
|
-
"@telus-uds/components-base": "1.
|
|
8
|
+
"@telus-uds/components-base": "1.72.0",
|
|
9
9
|
"@telus-uds/system-constants": "^1.3.0",
|
|
10
10
|
"fscreen": "^1.2.0",
|
|
11
11
|
"lodash.omit": "^4.5.0",
|
|
12
12
|
"react-dates": "^21.8.0",
|
|
13
13
|
"react-helmet-async": "^1.3.0",
|
|
14
14
|
"react-moment-proptypes": "^1.8.1",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^2.48.0",
|
|
16
16
|
"prop-types": "^15.7.2",
|
|
17
17
|
"lodash.throttle": "^4.1.1",
|
|
18
18
|
"react-youtube": "^10.1.0",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"skip": true
|
|
63
63
|
},
|
|
64
64
|
"types": "types/index.d.ts",
|
|
65
|
-
"version": "2.
|
|
65
|
+
"version": "2.27.0"
|
|
66
66
|
}
|
package/src/Card/Card.jsx
CHANGED
|
@@ -9,9 +9,11 @@ import {
|
|
|
9
9
|
selectSystemProps,
|
|
10
10
|
StackView,
|
|
11
11
|
useThemeTokens,
|
|
12
|
+
useThemeTokensCallback,
|
|
12
13
|
variantProp,
|
|
13
14
|
a11yProps,
|
|
14
|
-
viewProps
|
|
15
|
+
viewProps,
|
|
16
|
+
PressableCardBase
|
|
15
17
|
} from '@telus-uds/components-base'
|
|
16
18
|
import CardContent from './CardContent'
|
|
17
19
|
import CardFooter from './CardFooter'
|
|
@@ -20,26 +22,6 @@ import FullBleedContent, {
|
|
|
20
22
|
useFullBleedContentProps
|
|
21
23
|
} from '../shared/FullBleedContent'
|
|
22
24
|
|
|
23
|
-
const selectCardBaseTokens = ({
|
|
24
|
-
backgroundColor,
|
|
25
|
-
borderColor,
|
|
26
|
-
gradient,
|
|
27
|
-
borderWidth,
|
|
28
|
-
borderRadius,
|
|
29
|
-
shadow,
|
|
30
|
-
minWidth
|
|
31
|
-
}) => {
|
|
32
|
-
return {
|
|
33
|
-
backgroundColor,
|
|
34
|
-
borderColor,
|
|
35
|
-
gradient,
|
|
36
|
-
borderWidth,
|
|
37
|
-
borderRadius,
|
|
38
|
-
shadow,
|
|
39
|
-
minWidth
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
25
|
// Passes React Native-oriented system props through UDS Card
|
|
44
26
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
45
27
|
|
|
@@ -79,8 +61,11 @@ const Card = forwardRef(
|
|
|
79
61
|
footerPadding,
|
|
80
62
|
fullBleedImage,
|
|
81
63
|
fullBleedContent = fullBleedImage,
|
|
82
|
-
tokens,
|
|
64
|
+
tokens = {},
|
|
83
65
|
variant,
|
|
66
|
+
interactiveCard,
|
|
67
|
+
onPress,
|
|
68
|
+
dataSet,
|
|
84
69
|
...rest
|
|
85
70
|
} = {
|
|
86
71
|
fullBleedContent: { position: null }
|
|
@@ -96,10 +81,14 @@ const Card = forwardRef(
|
|
|
96
81
|
|
|
97
82
|
// If the card has rounded corners and a full bleed image, we need to apply
|
|
98
83
|
// those corners on the image as well, but partially
|
|
99
|
-
const
|
|
84
|
+
const { borderRadius } = useThemeTokens('Card', tokens, variant)
|
|
85
|
+
const getThemeTokens = useThemeTokensCallback('Card', interactiveCard?.tokens, {
|
|
86
|
+
interactive: true,
|
|
87
|
+
...(interactiveCard?.variant || {})
|
|
88
|
+
})
|
|
100
89
|
const hasFooter = Boolean(footer)
|
|
101
90
|
const fullBleedBorderRadius = getFullBleedBorderRadius(
|
|
102
|
-
|
|
91
|
+
borderRadius,
|
|
103
92
|
fullBleedContentPosition,
|
|
104
93
|
hasFooter
|
|
105
94
|
)
|
|
@@ -110,23 +99,39 @@ const Card = forwardRef(
|
|
|
110
99
|
flexShrink: 1,
|
|
111
100
|
justifyContent: 'space-between'
|
|
112
101
|
}
|
|
102
|
+
// When interactive area is present, spacing tokens should only be applied
|
|
103
|
+
// to individual Card sections, not Card as a whole
|
|
104
|
+
const { paddingTop, paddingBottom, paddingLeft, paddingRight, ...restOfTokens } = tokens
|
|
113
105
|
|
|
114
106
|
return (
|
|
115
107
|
<CardBase
|
|
116
108
|
ref={ref}
|
|
117
109
|
variant={{ ...variant, padding: 'custom' }}
|
|
118
|
-
tokens={
|
|
110
|
+
tokens={restOfTokens}
|
|
119
111
|
{...selectProps(rest)}
|
|
120
112
|
>
|
|
121
113
|
<StackView space={0} tokens={columnFlex}>
|
|
114
|
+
{interactiveCard?.body ? (
|
|
115
|
+
<PressableCardBase
|
|
116
|
+
ref={ref}
|
|
117
|
+
tokens={getThemeTokens}
|
|
118
|
+
dataSet={dataSet}
|
|
119
|
+
onPress={onPress}
|
|
120
|
+
{...selectProps(rest)}
|
|
121
|
+
>
|
|
122
|
+
{interactiveCard?.body}
|
|
123
|
+
</PressableCardBase>
|
|
124
|
+
) : null}
|
|
122
125
|
<StackView
|
|
123
126
|
direction={contentStackDirection}
|
|
124
127
|
tokens={{ ...columnFlex, alignItems: contentStackAlign }}
|
|
125
128
|
space={0}
|
|
126
129
|
>
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
|
|
130
|
+
{children ? (
|
|
131
|
+
<CardContent tokens={tokens} variant={variant} withFooter={hasFooter}>
|
|
132
|
+
{children}
|
|
133
|
+
</CardContent>
|
|
134
|
+
) : null}
|
|
130
135
|
{fullBleedContentPosition !== 'none' && (
|
|
131
136
|
<FullBleedContent borderRadius={fullBleedBorderRadius} {...fullBleedContentProps} />
|
|
132
137
|
)}
|
|
@@ -184,7 +189,20 @@ Card.propTypes = {
|
|
|
184
189
|
/**
|
|
185
190
|
* Card variant.
|
|
186
191
|
*/
|
|
187
|
-
variant: variantProp.propType
|
|
192
|
+
variant: variantProp.propType,
|
|
193
|
+
/**
|
|
194
|
+
* Function to call on pressing the card.
|
|
195
|
+
* Note: This is only available when `interactive` variant is used.
|
|
196
|
+
*/
|
|
197
|
+
onPress: PropTypes.func,
|
|
198
|
+
/**
|
|
199
|
+
* Object to set interactive card's properties
|
|
200
|
+
*/
|
|
201
|
+
interactiveCard: PropTypes.shape({
|
|
202
|
+
body: PropTypes.node,
|
|
203
|
+
tokens: getTokensPropType('Card'),
|
|
204
|
+
variant: variantProp.propType
|
|
205
|
+
})
|
|
188
206
|
}
|
|
189
207
|
|
|
190
208
|
export default Card
|