@telus-uds/components-web 2.26.0 → 2.28.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 +31 -2
- package/lib/DatePicker/DatePicker.js +129 -69
- package/lib/Image/Image.js +20 -44
- package/lib/Image/index.js +11 -1
- package/lib/Image/server.js +12 -0
- package/lib/OptimizeImage/OptimizeImage.js +1 -1
- package/lib/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/lib/Table/Cell.js +14 -5
- package/lib/baseExports.js +6 -0
- package/lib/index.js +12 -2
- package/lib/server.js +13 -0
- package/lib/utils/theming/get-theme-from-server.js +24 -0
- package/lib/utils/theming/with-client-theme.js +32 -0
- package/lib/utils/theming/with-server-theme.js +34 -0
- package/lib-module/DatePicker/DatePicker.js +132 -72
- package/lib-module/Image/Image.js +17 -41
- package/lib-module/Image/index.js +6 -1
- package/lib-module/Image/server.js +4 -0
- package/lib-module/OptimizeImage/OptimizeImage.js +1 -1
- package/lib-module/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/lib-module/Table/Cell.js +14 -5
- package/lib-module/baseExports.js +1 -1
- package/lib-module/index.js +3 -1
- package/lib-module/server.js +5 -0
- package/lib-module/utils/theming/get-theme-from-server.js +16 -0
- package/lib-module/utils/theming/with-client-theme.js +24 -0
- package/lib-module/utils/theming/with-server-theme.js +26 -0
- package/package.json +25 -4
- package/src/DatePicker/DatePicker.jsx +125 -63
- package/src/Image/Image.jsx +15 -24
- package/src/Image/index.js +6 -1
- package/src/Image/server.js +5 -0
- package/src/OptimizeImage/OptimizeImage.jsx +1 -1
- package/src/OptimizeImage/utils/getFallbackUrl.js +2 -2
- package/src/Table/Cell.jsx +9 -2
- package/src/baseExports.js +1 -0
- package/src/index.js +3 -1
- package/src/server.js +5 -0
- package/src/utils/theming/get-theme-from-server.js +22 -0
- package/src/utils/theming/with-client-theme.jsx +20 -0
- package/src/utils/theming/with-server-theme.jsx +21 -0
- package/types/WebVideo.d.ts +4 -3
package/package.json
CHANGED
|
@@ -5,18 +5,37 @@
|
|
|
5
5
|
],
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@gorhom/portal": "^1.0.14",
|
|
8
|
-
"@telus-uds/components-base": "1.
|
|
8
|
+
"@telus-uds/components-base": "1.73.0",
|
|
9
9
|
"@telus-uds/system-constants": "^1.3.0",
|
|
10
10
|
"fscreen": "^1.2.0",
|
|
11
11
|
"lodash.omit": "^4.5.0",
|
|
12
|
+
"moment": "2.29.4",
|
|
12
13
|
"react-dates": "^21.8.0",
|
|
13
14
|
"react-helmet-async": "^1.3.0",
|
|
14
15
|
"react-moment-proptypes": "^1.8.1",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
16
|
+
"@telus-uds/system-theme-tokens": "^2.49.0",
|
|
16
17
|
"prop-types": "^15.7.2",
|
|
17
18
|
"lodash.throttle": "^4.1.1",
|
|
18
19
|
"react-youtube": "^10.1.0",
|
|
19
|
-
"
|
|
20
|
+
"semver": "^7.5.4"
|
|
21
|
+
},
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./lib-module/index.js",
|
|
25
|
+
"require": "./lib/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./*": {
|
|
28
|
+
"import": "./lib-module/*/index.js",
|
|
29
|
+
"require": "./lib/*/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./server": {
|
|
32
|
+
"import": "./lib-module/server.js",
|
|
33
|
+
"require": "./lib/server.js"
|
|
34
|
+
},
|
|
35
|
+
"./server/*": {
|
|
36
|
+
"import": "./lib-module/*/server.js",
|
|
37
|
+
"require": "./lib/server/*/server.js"
|
|
38
|
+
}
|
|
20
39
|
},
|
|
21
40
|
"description": "UDS mult-brand web components",
|
|
22
41
|
"devDependencies": {
|
|
@@ -27,6 +46,8 @@
|
|
|
27
46
|
"assert": "^2.0.0",
|
|
28
47
|
"babel-plugin-react-native-web": "^0.18.7",
|
|
29
48
|
"babel-plugin-styled-components": "^2.0.6",
|
|
49
|
+
"eslint-import-resolver-alias": "^1.1.2",
|
|
50
|
+
"eslint-import-resolver-exports": "^1.0.0-beta.5",
|
|
30
51
|
"jest-axe": "^6.0.0",
|
|
31
52
|
"jest-styled-components": "^7.0.8",
|
|
32
53
|
"react-test-renderer": "~18.0.0",
|
|
@@ -62,5 +83,5 @@
|
|
|
62
83
|
"skip": true
|
|
63
84
|
},
|
|
64
85
|
"types": "types/index.d.ts",
|
|
65
|
-
"version": "2.
|
|
86
|
+
"version": "2.28.0"
|
|
66
87
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
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'
|
|
@@ -13,10 +13,12 @@ import {
|
|
|
13
13
|
useViewport,
|
|
14
14
|
useThemeTokens,
|
|
15
15
|
applyTextStyles,
|
|
16
|
-
getTokensPropType
|
|
16
|
+
getTokensPropType,
|
|
17
|
+
Portal,
|
|
18
|
+
useSafeLayoutEffect
|
|
17
19
|
} from '@telus-uds/components-base'
|
|
18
20
|
import moment from 'moment'
|
|
19
|
-
import { isUndefined } from 'lodash'
|
|
21
|
+
import { isUndefined, throttle } from 'lodash'
|
|
20
22
|
import CalendarContainer from './CalendarContainer'
|
|
21
23
|
import dictionary from './dictionary'
|
|
22
24
|
import { htmlAttrs } from '../utils'
|
|
@@ -48,6 +50,12 @@ const DateInputWrapper = styled.div({
|
|
|
48
50
|
flexDirection: 'column'
|
|
49
51
|
})
|
|
50
52
|
|
|
53
|
+
const PortalPositionedContainer = styled.div({
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
left: ({ left }) => `${left}px`,
|
|
56
|
+
top: ({ top }) => `${top}px`
|
|
57
|
+
})
|
|
58
|
+
|
|
51
59
|
/**
|
|
52
60
|
* Use DatePicker to select a date on a calendar.
|
|
53
61
|
*
|
|
@@ -97,6 +105,23 @@ const DatePicker = forwardRef(
|
|
|
97
105
|
const [inputText, setInputText] = useState(
|
|
98
106
|
date instanceof moment ? date.format(dateFormat) : ''
|
|
99
107
|
)
|
|
108
|
+
const textInputRef = useRef()
|
|
109
|
+
const [datePickerPosition, setDatePickerPosition] = useState({ left: 0, top: 0 })
|
|
110
|
+
|
|
111
|
+
useSafeLayoutEffect(() => {
|
|
112
|
+
const updateDimensions = () => {
|
|
113
|
+
if (inline) return
|
|
114
|
+
const { left, top } = textInputRef.current.getBoundingClientRect()
|
|
115
|
+
setDatePickerPosition({
|
|
116
|
+
left,
|
|
117
|
+
top: top + textInputRef.current.offsetHeight
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
const throttledUpdateDimensions = throttle(updateDimensions, 100, { leading: false })
|
|
121
|
+
updateDimensions()
|
|
122
|
+
window.addEventListener('resize', throttledUpdateDimensions)
|
|
123
|
+
return () => window.removeEventListener('resize', throttledUpdateDimensions)
|
|
124
|
+
}, [])
|
|
100
125
|
|
|
101
126
|
const [isFocused, setIsFocused] = useState(false)
|
|
102
127
|
const [isClickedInside, setIsClickedInside] = useState(false)
|
|
@@ -204,19 +229,7 @@ const DatePicker = forwardRef(
|
|
|
204
229
|
/>
|
|
205
230
|
)
|
|
206
231
|
return (
|
|
207
|
-
|
|
208
|
-
{...selectProps(rest)}
|
|
209
|
-
daySize={daySize}
|
|
210
|
-
validation={validation}
|
|
211
|
-
remainingTokens={{
|
|
212
|
-
...remainingTokens
|
|
213
|
-
}}
|
|
214
|
-
calendarDayDefaultHeight={circleSize}
|
|
215
|
-
calendarDayDefaultWidth={circleSize}
|
|
216
|
-
calendarMonthFontTokens={calendarMonthFontTokens}
|
|
217
|
-
calendarWeekFontTokens={calendarWeekFontTokens}
|
|
218
|
-
defaultFontTokens={defaultFontTokens}
|
|
219
|
-
>
|
|
232
|
+
<>
|
|
220
233
|
{inline ? (
|
|
221
234
|
<>
|
|
222
235
|
<HiddenInputFieldContainer
|
|
@@ -225,65 +238,30 @@ const DatePicker = forwardRef(
|
|
|
225
238
|
>
|
|
226
239
|
<input ref={ref} id={id} type="text" value={inputText} readOnly />
|
|
227
240
|
</HiddenInputFieldContainer>
|
|
228
|
-
<
|
|
229
|
-
|
|
230
|
-
onDateChange={onChange}
|
|
231
|
-
focused={isFocused}
|
|
232
|
-
onFocusChange={onFocusChange}
|
|
233
|
-
numberOfMonths={1}
|
|
234
|
-
hideKeyboardShortcutsPanel={true}
|
|
235
|
-
keepOpenOnDateSelect={false}
|
|
241
|
+
<CalendarContainer
|
|
242
|
+
{...selectProps(rest)}
|
|
236
243
|
daySize={daySize}
|
|
237
|
-
renderNavPrevButton={renderPrevButton}
|
|
238
|
-
renderNavNextButton={renderNextButton}
|
|
239
|
-
isOutsideRange={isDayDisabled}
|
|
240
|
-
phrases={getCopy()}
|
|
241
|
-
renderMonthElement={({ month }) => (
|
|
242
|
-
<MonthCenterContainer>
|
|
243
|
-
<div>
|
|
244
|
-
{dictionary[copy]
|
|
245
|
-
? dictionary[copy].months[month.month()]
|
|
246
|
-
: month.format('MMMM')}{' '}
|
|
247
|
-
{month.year()}
|
|
248
|
-
</div>
|
|
249
|
-
</MonthCenterContainer>
|
|
250
|
-
)}
|
|
251
|
-
renderWeekHeaderElement={(day) => (
|
|
252
|
-
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
253
|
-
)}
|
|
254
|
-
/>
|
|
255
|
-
</>
|
|
256
|
-
) : (
|
|
257
|
-
<DateInputWrapper onMouseDown={handleMouseDown} onFocus={handleFocus}>
|
|
258
|
-
<TextInput
|
|
259
|
-
copy={copy}
|
|
260
|
-
feedback={feedback}
|
|
261
|
-
hint={hint}
|
|
262
|
-
placeholder="DD / MM / YYYY"
|
|
263
|
-
onChange={onChangeInput}
|
|
264
|
-
tooltip={tooltip}
|
|
265
|
-
hintPosition={hintPosition}
|
|
266
|
-
label={dictionary[copy]?.roleDescription ?? label}
|
|
267
|
-
value={inputText}
|
|
268
244
|
validation={validation}
|
|
269
|
-
|
|
245
|
+
remainingTokens={remainingTokens}
|
|
246
|
+
calendarDayDefaultHeight={circleSize}
|
|
247
|
+
calendarDayDefaultWidth={circleSize}
|
|
248
|
+
calendarMonthFontTokens={calendarMonthFontTokens}
|
|
249
|
+
calendarWeekFontTokens={calendarWeekFontTokens}
|
|
250
|
+
defaultFontTokens={defaultFontTokens}
|
|
270
251
|
>
|
|
271
|
-
<
|
|
252
|
+
<DayPickerSingleDateController
|
|
272
253
|
date={inputDate}
|
|
273
|
-
disabled={disabled}
|
|
274
254
|
onDateChange={onChange}
|
|
275
255
|
focused={isFocused}
|
|
276
256
|
onFocusChange={onFocusChange}
|
|
277
257
|
numberOfMonths={1}
|
|
278
258
|
hideKeyboardShortcutsPanel={true}
|
|
279
|
-
keepOpenOnDateSelect={
|
|
259
|
+
keepOpenOnDateSelect={false}
|
|
280
260
|
daySize={daySize}
|
|
281
|
-
ref={ref}
|
|
282
261
|
renderNavPrevButton={renderPrevButton}
|
|
262
|
+
renderNavNextButton={renderNextButton}
|
|
283
263
|
isOutsideRange={isDayDisabled}
|
|
284
264
|
phrases={getCopy()}
|
|
285
|
-
id={id}
|
|
286
|
-
renderNavNextButton={renderNextButton}
|
|
287
265
|
renderMonthElement={({ month }) => (
|
|
288
266
|
<MonthCenterContainer>
|
|
289
267
|
<div>
|
|
@@ -298,10 +276,94 @@ const DatePicker = forwardRef(
|
|
|
298
276
|
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
299
277
|
)}
|
|
300
278
|
/>
|
|
279
|
+
</CalendarContainer>
|
|
280
|
+
</>
|
|
281
|
+
) : (
|
|
282
|
+
<DateInputWrapper onMouseDown={handleMouseDown} onFocus={handleFocus}>
|
|
283
|
+
<TextInput
|
|
284
|
+
copy={copy}
|
|
285
|
+
feedback={feedback}
|
|
286
|
+
hint={hint}
|
|
287
|
+
placeholder="DD / MM / YYYY"
|
|
288
|
+
onChange={onChangeInput}
|
|
289
|
+
tooltip={tooltip}
|
|
290
|
+
hintPosition={hintPosition}
|
|
291
|
+
label={dictionary[copy]?.roleDescription ?? label}
|
|
292
|
+
value={inputText}
|
|
293
|
+
validation={validation}
|
|
294
|
+
inactive={disabled}
|
|
295
|
+
ref={textInputRef}
|
|
296
|
+
>
|
|
297
|
+
<Portal>
|
|
298
|
+
{/* Because `SingleDatePicker` is an absolutely positioned element,
|
|
299
|
+
* putting it in a `Portal` breaks view heirarchy because it doesn't
|
|
300
|
+
* align with `TextInput`, but rather position itself with the nearest
|
|
301
|
+
* positioned ancestor.
|
|
302
|
+
*
|
|
303
|
+
* This means that the `Portal` needs to be positioned absolutely,
|
|
304
|
+
* but the `SingleDatePicker` needs to be positioned relative to the
|
|
305
|
+
* `Portal`.
|
|
306
|
+
*
|
|
307
|
+
* This is accomplished by wrapping the `SingleDatePicker` in a
|
|
308
|
+
* `PortalPositionedContainer` which positions the `SingleDatePicker`
|
|
309
|
+
* relative to the `Portal`. This container is then positioned absolutely
|
|
310
|
+
* relative to the `TextInput`.
|
|
311
|
+
*
|
|
312
|
+
* TODO: Using `floating-ui` or something like that is a more preferred and streamlined way
|
|
313
|
+
* to position popovers and overlays.
|
|
314
|
+
*/}
|
|
315
|
+
<PortalPositionedContainer
|
|
316
|
+
top={datePickerPosition.top}
|
|
317
|
+
left={datePickerPosition.left}
|
|
318
|
+
>
|
|
319
|
+
<CalendarContainer
|
|
320
|
+
{...selectProps(rest)}
|
|
321
|
+
daySize={daySize}
|
|
322
|
+
validation={validation}
|
|
323
|
+
remainingTokens={remainingTokens}
|
|
324
|
+
calendarDayDefaultHeight={circleSize}
|
|
325
|
+
calendarDayDefaultWidth={circleSize}
|
|
326
|
+
calendarMonthFontTokens={calendarMonthFontTokens}
|
|
327
|
+
calendarWeekFontTokens={calendarWeekFontTokens}
|
|
328
|
+
defaultFontTokens={defaultFontTokens}
|
|
329
|
+
>
|
|
330
|
+
<SingleDatePicker
|
|
331
|
+
date={inputDate}
|
|
332
|
+
disabled={disabled}
|
|
333
|
+
onDateChange={onChange}
|
|
334
|
+
focused={isFocused}
|
|
335
|
+
onFocusChange={onFocusChange}
|
|
336
|
+
numberOfMonths={1}
|
|
337
|
+
hideKeyboardShortcutsPanel={true}
|
|
338
|
+
keepOpenOnDateSelect={true}
|
|
339
|
+
daySize={daySize}
|
|
340
|
+
ref={ref}
|
|
341
|
+
renderNavPrevButton={renderPrevButton}
|
|
342
|
+
isOutsideRange={isDayDisabled}
|
|
343
|
+
phrases={getCopy()}
|
|
344
|
+
id={id}
|
|
345
|
+
renderNavNextButton={renderNextButton}
|
|
346
|
+
renderMonthElement={({ month }) => (
|
|
347
|
+
<MonthCenterContainer>
|
|
348
|
+
<div>
|
|
349
|
+
{dictionary[copy]
|
|
350
|
+
? dictionary[copy].months[month.month()]
|
|
351
|
+
: month.format('MMMM')}{' '}
|
|
352
|
+
{month.year()}
|
|
353
|
+
</div>
|
|
354
|
+
</MonthCenterContainer>
|
|
355
|
+
)}
|
|
356
|
+
renderWeekHeaderElement={(day) => (
|
|
357
|
+
<div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
|
|
358
|
+
)}
|
|
359
|
+
/>
|
|
360
|
+
</CalendarContainer>
|
|
361
|
+
</PortalPositionedContainer>
|
|
362
|
+
</Portal>
|
|
301
363
|
</TextInput>
|
|
302
364
|
</DateInputWrapper>
|
|
303
365
|
)}
|
|
304
|
-
|
|
366
|
+
</>
|
|
305
367
|
)
|
|
306
368
|
}
|
|
307
369
|
)
|
package/src/Image/Image.jsx
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { htmlAttrs, warn } from '../utils'
|
|
3
|
+
import { htmlAttrs, selectSystemProps, getTokensPropType } from '@telus-uds/components-base/server'
|
|
4
|
+
import { warn } from '../utils/logger'
|
|
6
5
|
|
|
7
6
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
8
7
|
|
|
9
|
-
const StyledImage = styled.img(({ height }) => {
|
|
10
|
-
return {
|
|
11
|
-
height: height ?? 'auto',
|
|
12
|
-
maxWidth: '100%'
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
const StyledRoundedImage = styled(StyledImage)`
|
|
16
|
-
border-radius: ${({ borderRadius }) => borderRadius}px;
|
|
17
|
-
`
|
|
18
|
-
const StyledCircularImage = styled(StyledImage)({
|
|
19
|
-
borderRadius: '50%'
|
|
20
|
-
})
|
|
21
|
-
|
|
22
8
|
const Image = ({
|
|
23
9
|
src,
|
|
24
10
|
width,
|
|
@@ -27,10 +13,11 @@ const Image = ({
|
|
|
27
13
|
rounded,
|
|
28
14
|
loading = 'eager',
|
|
29
15
|
tokens,
|
|
16
|
+
theme,
|
|
30
17
|
variant,
|
|
31
18
|
...rest
|
|
32
19
|
}) => {
|
|
33
|
-
|
|
20
|
+
let { borderRadius } = theme
|
|
34
21
|
const isCircle = rounded === 'circle'
|
|
35
22
|
const isCorners = rounded === 'corners'
|
|
36
23
|
const isSquare = width === height
|
|
@@ -42,19 +29,21 @@ const Image = ({
|
|
|
42
29
|
)
|
|
43
30
|
}
|
|
44
31
|
|
|
45
|
-
let ImageComponent
|
|
46
32
|
if (isCircle) {
|
|
47
|
-
|
|
33
|
+
borderRadius = '50%'
|
|
48
34
|
} else if (isCorners) {
|
|
49
|
-
|
|
50
|
-
} else {
|
|
51
|
-
ImageComponent = StyledImage
|
|
35
|
+
borderRadius = '4px'
|
|
52
36
|
}
|
|
53
37
|
|
|
38
|
+
const style = {
|
|
39
|
+
borderRadius,
|
|
40
|
+
height: height ?? 'auto',
|
|
41
|
+
maxWidth: '100%'
|
|
42
|
+
}
|
|
54
43
|
return (
|
|
55
|
-
<
|
|
44
|
+
<img
|
|
56
45
|
{...selectProps(rest)}
|
|
57
|
-
|
|
46
|
+
style={style}
|
|
58
47
|
src={src}
|
|
59
48
|
width={width}
|
|
60
49
|
height={height}
|
|
@@ -97,4 +86,6 @@ Image.propTypes = {
|
|
|
97
86
|
tokens: getTokensPropType('Image')
|
|
98
87
|
}
|
|
99
88
|
|
|
89
|
+
Image.displayName = 'Image'
|
|
90
|
+
|
|
100
91
|
export default Image
|
package/src/Image/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import Image from './Image'
|
|
2
|
+
import withClientTheme from '../utils/theming/with-client-theme'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
// Exporting the unwrapped component separately for react-docgen to extract info for docsite
|
|
5
|
+
export { Image as DefaultImage }
|
|
6
|
+
|
|
7
|
+
const ClientThemedImage = withClientTheme(Image)
|
|
8
|
+
export default ClientThemedImage
|
|
@@ -69,7 +69,7 @@ const OptimizeImage = ({
|
|
|
69
69
|
disableRetina,
|
|
70
70
|
supportsWebp
|
|
71
71
|
),
|
|
72
|
-
fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
|
|
72
|
+
fallbackSrc: getFallbackUrl(contentfulAssetUrl, dimension, xl, quality)
|
|
73
73
|
})
|
|
74
74
|
})
|
|
75
75
|
}, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs])
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import isSvgUrl from './isSvgUrl'
|
|
2
2
|
|
|
3
|
-
export default function getFallbackUrl(url,
|
|
3
|
+
export default function getFallbackUrl(url, dimension, size, quality) {
|
|
4
4
|
if (!isSvgUrl(url)) {
|
|
5
|
-
return `${url}
|
|
5
|
+
return `${url}?${dimension}=${size}&q=${quality}`
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
return url
|
package/src/Table/Cell.jsx
CHANGED
|
@@ -59,6 +59,11 @@ const createStyledCell = (htmlElement) => styled[htmlElement]`
|
|
|
59
59
|
? `inset 0 1px 0 ${cellBoxShadowColor}, inset 0 -1px 0 ${cellBoxShadowColor}`
|
|
60
60
|
: `inset 0 1px 0 ${cellBoxShadowColor}`
|
|
61
61
|
}};
|
|
62
|
+
${({ display }) =>
|
|
63
|
+
display &&
|
|
64
|
+
`*:not(:empty) {
|
|
65
|
+
display: ${display};
|
|
66
|
+
}`}
|
|
62
67
|
`
|
|
63
68
|
const StyledHeaderCell = createStyledCell('th')
|
|
64
69
|
const StyledDataCell = createStyledCell('td')
|
|
@@ -81,7 +86,8 @@ const Cell = ({ children, isFirstInRow, align = 'left', tokens: cellTokens, type
|
|
|
81
86
|
fontSize,
|
|
82
87
|
lineHeight,
|
|
83
88
|
stickyBackgroundColor,
|
|
84
|
-
fontColor
|
|
89
|
+
fontColor,
|
|
90
|
+
display
|
|
85
91
|
} = useThemeTokens('Table', themeTokens, { spacing, type, text })
|
|
86
92
|
|
|
87
93
|
const sharedProps = {
|
|
@@ -95,7 +101,8 @@ const Cell = ({ children, isFirstInRow, align = 'left', tokens: cellTokens, type
|
|
|
95
101
|
cellPaddingLeft,
|
|
96
102
|
cellPaddingBottom,
|
|
97
103
|
stickyBackgroundColor,
|
|
98
|
-
cellBoxShadowColor
|
|
104
|
+
cellBoxShadowColor,
|
|
105
|
+
display
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
const typographyTokens = {
|
package/src/baseExports.js
CHANGED
package/src/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
1
3
|
export { default as Badge } from './Badge'
|
|
2
4
|
export { default as OrderedList } from './OrderedList'
|
|
3
5
|
export { default as PreviewCard } from './PreviewCard'
|
|
@@ -13,6 +15,7 @@ export { default as PriceLockup } from './PriceLockup'
|
|
|
13
15
|
export { default as Footnote } from './Footnote'
|
|
14
16
|
export { default as QuantitySelector } from './QuantitySelector'
|
|
15
17
|
export { default as IconButton } from './IconButton'
|
|
18
|
+
export { default as Image, DefaultImage } from './Image'
|
|
16
19
|
export { transformGradient } from './utils'
|
|
17
20
|
export { default as Breadcrumbs } from './Breadcrumbs'
|
|
18
21
|
export { default as BlockQuote } from './BlockQuote'
|
|
@@ -20,7 +23,6 @@ export { default as OptimizeImage } from './OptimizeImage'
|
|
|
20
23
|
export { default as Testimonial } from './Testimonial'
|
|
21
24
|
export { default as Toast } from './Toast'
|
|
22
25
|
export { default as Table } from './Table'
|
|
23
|
-
export { default as Image } from './Image'
|
|
24
26
|
export { default as WebVideo } from './WebVideo'
|
|
25
27
|
export { default as WaffleGrid } from './WaffleGrid'
|
|
26
28
|
export { default as Spinner } from './Spinner'
|
package/src/server.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const cachedTheme = {}
|
|
2
|
+
const theme = process.env.UDS_THEME
|
|
3
|
+
|
|
4
|
+
async function importTheme(componentName) {
|
|
5
|
+
try {
|
|
6
|
+
cachedTheme[componentName] = await import(
|
|
7
|
+
`@telus-uds/theme-${theme}/build/rn/${componentName}.js`
|
|
8
|
+
)
|
|
9
|
+
} catch (_) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`An error occurred while trying to import theme-${process.env.UDS_THEME}. Please check that the theme has been installed in your app or that you are not importing a server component inside a client component.`
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default async function getTheme(componentName) {
|
|
17
|
+
if (cachedTheme[componentName]) {
|
|
18
|
+
return cachedTheme[componentName]
|
|
19
|
+
}
|
|
20
|
+
await importTheme(componentName)
|
|
21
|
+
return cachedTheme[componentName]
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { useThemeTokens } from '@telus-uds/components-base'
|
|
5
|
+
|
|
6
|
+
const withClientTheme = (Component) => {
|
|
7
|
+
const UdsStyledComponent = ({ tokens: tokenOverrides, variant, ...props }) => {
|
|
8
|
+
const theme = useThemeTokens(Component.displayName, variant, tokenOverrides)
|
|
9
|
+
return <Component theme={theme} {...props} />
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
UdsStyledComponent.propTypes = {
|
|
13
|
+
tokens: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
14
|
+
variant: PropTypes.string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return UdsStyledComponent
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default withClientTheme
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { getThemeTokens } from '@telus-uds/components-base/server'
|
|
4
|
+
|
|
5
|
+
import getTheme from './get-theme-from-server'
|
|
6
|
+
|
|
7
|
+
const withServerTheme = (Component, componentName) => {
|
|
8
|
+
const UdsStyledComponent = async ({ tokens: tokenOverrides, variant, ...props }) => {
|
|
9
|
+
const componentTheme = await getTheme(componentName)
|
|
10
|
+
const themeTokens = getThemeTokens(componentTheme, tokenOverrides, variant)
|
|
11
|
+
return <Component theme={themeTokens} {...props} />
|
|
12
|
+
}
|
|
13
|
+
UdsStyledComponent.propTypes = {
|
|
14
|
+
tokens: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
15
|
+
variant: PropTypes.string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return UdsStyledComponent
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default withServerTheme
|
package/types/WebVideo.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ComponentType } from 'react'
|
|
2
|
+
import { YouTubeEvent } from 'react-youtube'
|
|
2
3
|
import type { HTMLAttrs } from './common'
|
|
3
4
|
|
|
4
5
|
export interface WebVideoProps extends HTMLAttrs {
|
|
@@ -10,9 +11,9 @@ export interface WebVideoProps extends HTMLAttrs {
|
|
|
10
11
|
videoLength: number
|
|
11
12
|
copy?: 'en' | 'fr'
|
|
12
13
|
onStart?: () => void
|
|
13
|
-
onPlay?: () => void
|
|
14
|
-
onEnd?: () => void
|
|
15
|
-
onPause?: () => void
|
|
14
|
+
onPlay?: (event: YouTubeEvent<number>) => void
|
|
15
|
+
onEnd?: (event: YouTubeEvent<number>) => void
|
|
16
|
+
onPause?: (event: YouTubeEvent<number>) => void
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
declare const WebVideo: ComponentType<WebVideoProps>
|