@telus-uds/components-web 2.7.0 → 2.8.1
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 +26 -3
- package/component-docs.json +5 -1
- package/lib/DatePicker/CalendarContainer.js +10 -25
- package/lib/DatePicker/DatePicker.js +106 -60
- package/lib/DatePicker/reactDatesCss.js +1 -1
- package/lib/StoryCard/StoryCard.js +3 -6
- package/lib/WebVideo/WebVideo.js +1 -1
- package/lib-module/DatePicker/CalendarContainer.js +10 -25
- package/lib-module/DatePicker/DatePicker.js +105 -61
- package/lib-module/DatePicker/reactDatesCss.js +1 -1
- package/lib-module/StoryCard/StoryCard.js +3 -6
- package/lib-module/WebVideo/WebVideo.js +1 -1
- package/package.json +5 -4
- package/src/DatePicker/CalendarContainer.jsx +10 -25
- package/src/DatePicker/DatePicker.jsx +99 -69
- package/src/DatePicker/reactDatesCss.js +4 -67
- package/src/StoryCard/StoryCard.jsx +3 -7
- package/src/WebVideo/WebVideo.jsx +1 -1
- package/types/WebVideo.d.ts +2 -2
|
@@ -7,19 +7,21 @@ import SingleDatePicker from 'react-dates/lib/components/SingleDatePicker'
|
|
|
7
7
|
import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerSingleDateController'
|
|
8
8
|
import {
|
|
9
9
|
IconButton,
|
|
10
|
-
|
|
10
|
+
TextInput,
|
|
11
11
|
selectSystemProps,
|
|
12
12
|
useCopy,
|
|
13
13
|
useViewport,
|
|
14
14
|
useThemeTokens,
|
|
15
15
|
applyTextStyles
|
|
16
16
|
} from '@telus-uds/components-base'
|
|
17
|
+
import moment from 'moment'
|
|
17
18
|
import CalendarContainer from './CalendarContainer'
|
|
18
19
|
import dictionary from './dictionary'
|
|
19
20
|
import { htmlAttrs } from '../utils'
|
|
20
21
|
|
|
21
22
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
22
|
-
|
|
23
|
+
const dateFormat = 'DD / MM / YYYY'
|
|
24
|
+
const dateFormatWithoutSpaces = 'DD/MM/YYYY'
|
|
23
25
|
const getResponsiveDaySize = (inline = false, viewport = 'md') => {
|
|
24
26
|
let responsiveDaySize
|
|
25
27
|
if (viewport === 'xs') {
|
|
@@ -46,6 +48,11 @@ const MonthCenterContainer = styled.div({
|
|
|
46
48
|
justifyContent: 'center'
|
|
47
49
|
})
|
|
48
50
|
|
|
51
|
+
const DateInputWrapper = styled.div({
|
|
52
|
+
display: 'flex',
|
|
53
|
+
flexDirection: 'column'
|
|
54
|
+
})
|
|
55
|
+
|
|
49
56
|
/**
|
|
50
57
|
* Use DatePicker to select a date on a calendar.
|
|
51
58
|
*
|
|
@@ -88,22 +95,49 @@ const DatePicker = forwardRef(
|
|
|
88
95
|
},
|
|
89
96
|
ref
|
|
90
97
|
) => {
|
|
91
|
-
const [inputDate, setInputDate] = useState(date)
|
|
92
|
-
const [
|
|
98
|
+
const [inputDate, setInputDate] = useState(date instanceof moment ? date : undefined)
|
|
99
|
+
const [inputText, setInputText] = useState(
|
|
100
|
+
date instanceof moment ? date.format(dateFormat) : ''
|
|
101
|
+
)
|
|
93
102
|
|
|
103
|
+
const [isFocused, setIsFocused] = useState(false)
|
|
104
|
+
const [isClickedInside, setIsClickedInside] = useState(false)
|
|
94
105
|
const getCopy = useCopy({ dictionary, copy })
|
|
95
106
|
const onFocusChange = ({ focused }) => {
|
|
96
|
-
|
|
107
|
+
if (!isClickedInside) {
|
|
108
|
+
setIsFocused(focused)
|
|
109
|
+
}
|
|
110
|
+
setIsClickedInside(false)
|
|
111
|
+
}
|
|
112
|
+
const handleFocus = () => {
|
|
113
|
+
setIsFocused(true)
|
|
114
|
+
}
|
|
115
|
+
const handleMouseDown = (event) => {
|
|
116
|
+
if (event.target.tagName === 'INPUT') {
|
|
117
|
+
setIsClickedInside(true)
|
|
118
|
+
setIsFocused(true)
|
|
119
|
+
} else {
|
|
120
|
+
event.stopPropagation()
|
|
121
|
+
}
|
|
97
122
|
}
|
|
98
123
|
const onChange = (value) => {
|
|
99
124
|
setInputDate(value)
|
|
125
|
+
setInputText(value.format(dateFormat))
|
|
100
126
|
if (onDateChange) onDateChange(value)
|
|
101
127
|
}
|
|
128
|
+
const onChangeInput = (value) => {
|
|
129
|
+
if (moment(value.replace(/\s/g, ''), dateFormatWithoutSpaces, true).isValid()) {
|
|
130
|
+
setInputDate(moment(value, dateFormat))
|
|
131
|
+
if (onDateChange) onDateChange(moment(value, dateFormat))
|
|
132
|
+
setInputText(moment(value, dateFormatWithoutSpaces).format(dateFormat))
|
|
133
|
+
} else {
|
|
134
|
+
setInputText(value)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
102
137
|
const viewport = useViewport()
|
|
103
138
|
const daySize = getResponsiveDaySize(inline, viewport)
|
|
104
139
|
const circleSize = getResponsiveCircleSize(inline, viewport)
|
|
105
140
|
|
|
106
|
-
const value = date ?? inputDate
|
|
107
141
|
const HiddenInputFieldContainer = styled.div`
|
|
108
142
|
height: ${(props) => props.height};
|
|
109
143
|
width: ${(props) => props.width};
|
|
@@ -164,76 +198,27 @@ const DatePicker = forwardRef(
|
|
|
164
198
|
calendarWeekFontTokens={calendarWeekFontTokens}
|
|
165
199
|
defaultFontTokens={defaultFontTokens}
|
|
166
200
|
>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
{inline ? (
|
|
178
|
-
<>
|
|
179
|
-
<HiddenInputFieldContainer
|
|
180
|
-
height={hiddenInputFieldContainerHeight}
|
|
181
|
-
width={hiddenInputFieldContainerWidth}
|
|
182
|
-
>
|
|
183
|
-
<input
|
|
184
|
-
ref={ref}
|
|
185
|
-
id={id}
|
|
186
|
-
type="text"
|
|
187
|
-
value={value?.format('YYYY-MM-DD') ?? ''}
|
|
188
|
-
readOnly
|
|
189
|
-
/>
|
|
190
|
-
</HiddenInputFieldContainer>
|
|
191
|
-
<DayPickerSingleDateController
|
|
192
|
-
date={value}
|
|
193
|
-
onDateChange={onChange}
|
|
194
|
-
focused={isFocused}
|
|
195
|
-
onFocusChange={onFocusChange}
|
|
196
|
-
numberOfMonths={1}
|
|
197
|
-
hideKeyboardShortcutsPanel={true}
|
|
198
|
-
keepOpenOnDateSelect={false}
|
|
199
|
-
daySize={daySize}
|
|
200
|
-
renderNavPrevButton={renderPrevButton}
|
|
201
|
-
renderNavNextButton={renderNextButton}
|
|
202
|
-
isOutsideRange={isDayDisabled}
|
|
203
|
-
phrases={getCopy()}
|
|
204
|
-
renderMonthElement={({ month }) => (
|
|
205
|
-
<MonthCenterContainer>
|
|
206
|
-
<div>
|
|
207
|
-
{dictionary[copy]
|
|
208
|
-
? dictionary[copy].months[month.month()]
|
|
209
|
-
: month.format('MMMM')}{' '}
|
|
210
|
-
{month.year()}
|
|
211
|
-
</div>
|
|
212
|
-
</MonthCenterContainer>
|
|
213
|
-
)}
|
|
214
|
-
renderWeekHeaderElement={(day) => (
|
|
215
|
-
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
216
|
-
)}
|
|
217
|
-
/>
|
|
218
|
-
</>
|
|
219
|
-
) : (
|
|
220
|
-
<SingleDatePicker
|
|
221
|
-
date={value}
|
|
201
|
+
{inline ? (
|
|
202
|
+
<>
|
|
203
|
+
<HiddenInputFieldContainer
|
|
204
|
+
height={hiddenInputFieldContainerHeight}
|
|
205
|
+
width={hiddenInputFieldContainerWidth}
|
|
206
|
+
>
|
|
207
|
+
<input ref={ref} id={id} type="text" value={inputText} readOnly />
|
|
208
|
+
</HiddenInputFieldContainer>
|
|
209
|
+
<DayPickerSingleDateController
|
|
210
|
+
date={inputDate}
|
|
222
211
|
onDateChange={onChange}
|
|
223
212
|
focused={isFocused}
|
|
224
213
|
onFocusChange={onFocusChange}
|
|
225
214
|
numberOfMonths={1}
|
|
226
215
|
hideKeyboardShortcutsPanel={true}
|
|
227
|
-
keepOpenOnDateSelect={
|
|
216
|
+
keepOpenOnDateSelect={false}
|
|
228
217
|
daySize={daySize}
|
|
229
|
-
ref={ref}
|
|
230
218
|
renderNavPrevButton={renderPrevButton}
|
|
219
|
+
renderNavNextButton={renderNextButton}
|
|
231
220
|
isOutsideRange={isDayDisabled}
|
|
232
221
|
phrases={getCopy()}
|
|
233
|
-
id={id}
|
|
234
|
-
displayFormat="DD / MM / YYYY"
|
|
235
|
-
placeholder="DD / MM / YYYY"
|
|
236
|
-
renderNavNextButton={renderNextButton}
|
|
237
222
|
renderMonthElement={({ month }) => (
|
|
238
223
|
<MonthCenterContainer>
|
|
239
224
|
<div>
|
|
@@ -248,8 +233,53 @@ const DatePicker = forwardRef(
|
|
|
248
233
|
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
249
234
|
)}
|
|
250
235
|
/>
|
|
251
|
-
|
|
252
|
-
|
|
236
|
+
</>
|
|
237
|
+
) : (
|
|
238
|
+
<DateInputWrapper onMouseDown={handleMouseDown} onFocus={handleFocus}>
|
|
239
|
+
<TextInput
|
|
240
|
+
copy={copy}
|
|
241
|
+
feedback={feedback}
|
|
242
|
+
hint={hint}
|
|
243
|
+
placeholder="DD / MM / YYYY"
|
|
244
|
+
onChange={onChangeInput}
|
|
245
|
+
tooltip={tooltip}
|
|
246
|
+
hintPosition={hintPosition}
|
|
247
|
+
label={dictionary[copy]?.roleDescription ?? label}
|
|
248
|
+
value={inputText}
|
|
249
|
+
validation={validation}
|
|
250
|
+
>
|
|
251
|
+
<SingleDatePicker
|
|
252
|
+
date={inputDate}
|
|
253
|
+
onDateChange={onChange}
|
|
254
|
+
focused={isFocused}
|
|
255
|
+
onFocusChange={onFocusChange}
|
|
256
|
+
numberOfMonths={1}
|
|
257
|
+
hideKeyboardShortcutsPanel={true}
|
|
258
|
+
keepOpenOnDateSelect={true}
|
|
259
|
+
daySize={daySize}
|
|
260
|
+
ref={ref}
|
|
261
|
+
renderNavPrevButton={renderPrevButton}
|
|
262
|
+
isOutsideRange={isDayDisabled}
|
|
263
|
+
phrases={getCopy()}
|
|
264
|
+
id={id}
|
|
265
|
+
renderNavNextButton={renderNextButton}
|
|
266
|
+
renderMonthElement={({ month }) => (
|
|
267
|
+
<MonthCenterContainer>
|
|
268
|
+
<div>
|
|
269
|
+
{dictionary[copy]
|
|
270
|
+
? dictionary[copy].months[month.month()]
|
|
271
|
+
: month.format('MMMM')}{' '}
|
|
272
|
+
{month.year()}
|
|
273
|
+
</div>
|
|
274
|
+
</MonthCenterContainer>
|
|
275
|
+
)}
|
|
276
|
+
renderWeekHeaderElement={(day) => (
|
|
277
|
+
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
278
|
+
)}
|
|
279
|
+
/>
|
|
280
|
+
</TextInput>
|
|
281
|
+
</DateInputWrapper>
|
|
282
|
+
)}
|
|
253
283
|
</CalendarContainer>
|
|
254
284
|
)
|
|
255
285
|
}
|
|
@@ -31,13 +31,8 @@ const defaultReactDatesCss = css`
|
|
|
31
31
|
.SingleDatePickerInput {
|
|
32
32
|
display: inline-block;
|
|
33
33
|
background-color: #fff;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
border-radius: 2px;
|
|
37
|
-
border: 1px solid #dbdbdb;
|
|
38
|
-
}
|
|
39
|
-
.SingleDatePickerInput__rtl {
|
|
40
|
-
direction: rtl;
|
|
34
|
+
position: absolute;
|
|
35
|
+
top: -55px;
|
|
41
36
|
}
|
|
42
37
|
.SingleDatePickerInput__disabled {
|
|
43
38
|
background-color: #f2f2f2;
|
|
@@ -658,67 +653,8 @@ const defaultReactDatesCss = css`
|
|
|
658
653
|
left: 0;
|
|
659
654
|
overflow-y: scroll;
|
|
660
655
|
}
|
|
661
|
-
.DateInput {
|
|
662
|
-
margin: 0;
|
|
663
|
-
padding: 0;
|
|
664
|
-
background: #fff;
|
|
665
|
-
position: relative;
|
|
666
|
-
display: inline-block;
|
|
667
|
-
width: 130px;
|
|
668
|
-
vertical-align: middle;
|
|
669
|
-
}
|
|
670
|
-
.DateInput__small {
|
|
671
|
-
width: 97px;
|
|
672
|
-
}
|
|
673
|
-
.DateInput__block {
|
|
674
|
-
width: 100%;
|
|
675
|
-
}
|
|
676
|
-
.DateInput__disabled {
|
|
677
|
-
background: #f2f2f2;
|
|
678
|
-
color: #dbdbdb;
|
|
679
|
-
}
|
|
680
656
|
.DateInput_input {
|
|
681
|
-
|
|
682
|
-
font-size: 19px;
|
|
683
|
-
line-height: 24px;
|
|
684
|
-
color: #484848;
|
|
685
|
-
background-color: #fff;
|
|
686
|
-
width: 100%;
|
|
687
|
-
padding: 11px 11px 9px;
|
|
688
|
-
border: 0;
|
|
689
|
-
border-top: 0;
|
|
690
|
-
border-right: 0;
|
|
691
|
-
border-bottom: 2px solid transparent;
|
|
692
|
-
border-left: 0;
|
|
693
|
-
border-radius: 0;
|
|
694
|
-
}
|
|
695
|
-
.DateInput_input__small {
|
|
696
|
-
font-size: 15px;
|
|
697
|
-
line-height: 18px;
|
|
698
|
-
letter-spacing: 0.2px;
|
|
699
|
-
padding: 7px 7px 5px;
|
|
700
|
-
}
|
|
701
|
-
.DateInput_input__regular {
|
|
702
|
-
font-weight: auto;
|
|
703
|
-
}
|
|
704
|
-
.DateInput_input__readOnly {
|
|
705
|
-
-webkit-user-select: none;
|
|
706
|
-
-moz-user-select: none;
|
|
707
|
-
-ms-user-select: none;
|
|
708
|
-
user-select: none;
|
|
709
|
-
}
|
|
710
|
-
.DateInput_input__focused {
|
|
711
|
-
outline: 0;
|
|
712
|
-
background: #fff;
|
|
713
|
-
border: 0;
|
|
714
|
-
border-top: 0;
|
|
715
|
-
border-right: 0;
|
|
716
|
-
border-bottom: 2px solid #008489;
|
|
717
|
-
border-left: 0;
|
|
718
|
-
}
|
|
719
|
-
.DateInput_input__disabled {
|
|
720
|
-
background: #f2f2f2;
|
|
721
|
-
font-style: italic;
|
|
657
|
+
display: none;
|
|
722
658
|
}
|
|
723
659
|
.DateInput_screenReaderMessage {
|
|
724
660
|
border: 0;
|
|
@@ -732,6 +668,7 @@ const defaultReactDatesCss = css`
|
|
|
732
668
|
}
|
|
733
669
|
.DateInput_fang {
|
|
734
670
|
position: absolute;
|
|
671
|
+
top: 55px;
|
|
735
672
|
width: 20px;
|
|
736
673
|
height: 10px;
|
|
737
674
|
left: 22px;
|
|
@@ -115,21 +115,17 @@ const StoryCard = forwardRef(
|
|
|
115
115
|
space={1}
|
|
116
116
|
tokens={{ justifyContent: 'space-between', alignItems: 'baseline' }}
|
|
117
117
|
>
|
|
118
|
-
{Boolean(tag) &&
|
|
119
|
-
<Typography variant={{ size: 'eyebrow', colour: 'secondary' }}>
|
|
120
|
-
{tag}
|
|
121
|
-
</Typography>
|
|
122
|
-
)}
|
|
118
|
+
{Boolean(tag) && <Typography variant={{ size: 'eyebrow' }}>{tag}</Typography>}
|
|
123
119
|
{Boolean(date) && (
|
|
124
120
|
// TODO: get user locale and apply date formatting: "MMM DD, YYYY" for `en` and "YYYY-MM-DD" for `fr`
|
|
125
121
|
// Get locale based on decision of https://github.com/telus/universal-design-system/issues/715
|
|
126
|
-
<Typography variant={{ size: 'small'
|
|
122
|
+
<Typography variant={{ size: 'small' }}>{date}</Typography>
|
|
127
123
|
)}
|
|
128
124
|
</StackWrap>
|
|
129
125
|
<Spacer space={2} />
|
|
130
126
|
<Divider variant={{ decorative: true }} />
|
|
131
127
|
<Spacer space={3} />
|
|
132
|
-
<Typography variant={{ size: 'h3'
|
|
128
|
+
<Typography variant={{ size: 'h3' }}>{title}</Typography>
|
|
133
129
|
<Spacer space={2} />
|
|
134
130
|
<Typography>{description}</Typography>
|
|
135
131
|
</Box>
|
|
@@ -119,7 +119,7 @@ export const VideoProps = {
|
|
|
119
119
|
/**
|
|
120
120
|
* The splash screen UI's language as an ISO language code. It currently supports English and French.
|
|
121
121
|
*/
|
|
122
|
-
copy: PropTypes.oneOf(['en', 'fr'])
|
|
122
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
123
123
|
/**
|
|
124
124
|
* A function to be run when the play button is pressed on the video splash screen and the video is ready to play.
|
|
125
125
|
*/
|
package/types/WebVideo.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export interface WebVideoProps extends HTMLAttrs {
|
|
|
8
8
|
defaultVolume?: number
|
|
9
9
|
beginMuted?: boolean
|
|
10
10
|
videoLength: number
|
|
11
|
-
copy
|
|
12
|
-
onStart
|
|
11
|
+
copy?: 'en' | 'fr'
|
|
12
|
+
onStart?: () => void
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
declare const WebVideo: ComponentType<WebVideoProps>
|