@telus-uds/components-web 1.4.0 → 1.6.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +25 -2
  2. package/lib/Image/Image.js +126 -0
  3. package/lib/Image/index.js +13 -0
  4. package/lib/Modal/Modal.js +142 -0
  5. package/lib/Modal/ModalContent.js +195 -0
  6. package/lib/Modal/index.js +13 -0
  7. package/lib/Paragraph/Paragraph.js +107 -0
  8. package/lib/Paragraph/index.js +13 -0
  9. package/lib/Table/Body.js +29 -0
  10. package/lib/Table/Cell.js +200 -0
  11. package/lib/Table/Header.js +39 -0
  12. package/lib/Table/Row.js +35 -0
  13. package/lib/Table/SubHeading.js +37 -0
  14. package/lib/Table/Table.js +121 -0
  15. package/lib/Table/index.js +28 -0
  16. package/lib/Toast/Toast.js +136 -0
  17. package/lib/Toast/index.js +13 -0
  18. package/lib/WaffleGrid/WaffleGrid.js +176 -0
  19. package/lib/WaffleGrid/index.js +13 -0
  20. package/lib/baseExports.js +0 -6
  21. package/lib/index.js +55 -1
  22. package/lib-module/Image/Image.js +108 -0
  23. package/lib-module/Image/index.js +2 -0
  24. package/lib-module/Modal/Modal.js +128 -0
  25. package/lib-module/Modal/ModalContent.js +174 -0
  26. package/lib-module/Modal/index.js +2 -0
  27. package/lib-module/Paragraph/Paragraph.js +89 -0
  28. package/lib-module/Paragraph/index.js +2 -0
  29. package/lib-module/Table/Body.js +17 -0
  30. package/lib-module/Table/Cell.js +176 -0
  31. package/lib-module/Table/Header.js +22 -0
  32. package/lib-module/Table/Row.js +19 -0
  33. package/lib-module/Table/SubHeading.js +20 -0
  34. package/lib-module/Table/Table.js +93 -0
  35. package/lib-module/Table/index.js +12 -0
  36. package/lib-module/Toast/Toast.js +117 -0
  37. package/lib-module/Toast/index.js +2 -0
  38. package/lib-module/WaffleGrid/WaffleGrid.js +155 -0
  39. package/lib-module/WaffleGrid/index.js +2 -0
  40. package/lib-module/baseExports.js +1 -1
  41. package/lib-module/index.js +6 -0
  42. package/package.json +4 -3
  43. package/src/Image/Image.jsx +95 -0
  44. package/src/Image/index.js +3 -0
  45. package/src/Modal/Modal.jsx +111 -0
  46. package/src/Modal/ModalContent.jsx +161 -0
  47. package/src/Modal/index.js +3 -0
  48. package/src/Paragraph/Paragraph.jsx +79 -0
  49. package/src/Paragraph/index.js +3 -0
  50. package/src/Table/Body.jsx +12 -0
  51. package/src/Table/Cell.jsx +148 -0
  52. package/src/Table/Header.jsx +17 -0
  53. package/src/Table/Row.jsx +18 -0
  54. package/src/Table/SubHeading.jsx +17 -0
  55. package/src/Table/Table.jsx +90 -0
  56. package/src/Table/index.js +14 -0
  57. package/src/Toast/Toast.jsx +151 -0
  58. package/src/Toast/index.js +3 -0
  59. package/src/WaffleGrid/WaffleGrid.jsx +137 -0
  60. package/src/WaffleGrid/index.js +3 -0
  61. package/src/baseExports.js +0 -1
  62. package/src/index.js +6 -0
  63. package/types/Cell.d.ts +13 -0
  64. package/types/Table.d.ts +12 -0
@@ -0,0 +1,151 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import {
4
+ ChevronLink,
5
+ selectSystemProps,
6
+ useThemeTokens,
7
+ Typography,
8
+ withLinkRouter
9
+ } from '@telus-uds/components-base'
10
+ import styled, { keyframes, css } from 'styled-components'
11
+ import { htmlAttrs } from '../utils'
12
+
13
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
14
+
15
+ const transform = (property) => (from, to) =>
16
+ keyframes`
17
+ from {
18
+ ${property}: ${from};
19
+ }
20
+ to {
21
+ ${property}: ${to};
22
+ }
23
+ `
24
+
25
+ const slideDown =
26
+ (property) =>
27
+ (from, to, end = to) =>
28
+ keyframes`
29
+ 0% {
30
+ ${property}: ${from};
31
+ }
32
+ 99% {
33
+ ${property}: ${to};
34
+ }
35
+ 100% {
36
+ ${property}: ${end};
37
+ }
38
+ `
39
+
40
+ const animation = (props) => css`
41
+ ${slideDown('height')(
42
+ `${props.animationHeightBefore}px`,
43
+ `${props.animationHeightAfter}px`,
44
+ 'auto'
45
+ )} 1s ease-in-out 2s forwards,
46
+ ${transform('padding-bottom')(
47
+ `${props.animationPaddingBottomBefore}px`,
48
+ `${props.animationPaddingBottomAfter}px`
49
+ )} 1s ease-in-out 2s forwards,
50
+ ${transform('padding-top')(
51
+ `${props.animationPaddingTopBefore}px`,
52
+ `${props.animationPaddingTopAfter}px`
53
+ )} 1s ease-in-out 2s forwards,
54
+ ${transform('background')(
55
+ props.animationBackgroundColorBefore,
56
+ props.animationBackgroundColorAfter
57
+ )} 1s ease-in-out 3.2s forwards;
58
+ & * {
59
+ animation: ${transform('color')(props.animationColorBefore, props.animationColorAfter)} 1s
60
+ ease-in-out 3s forwards;
61
+ }
62
+ & > a div {
63
+ animation: ${transform('color')(props.animationDivColorBefore, props.animationDivColorAfter)} 1s
64
+ ease-in-out 3s forwards;
65
+ }
66
+ & > a svg {
67
+ animation: ${transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter)}
68
+ 1s ease-in-out 3s forwards;
69
+ }
70
+ `
71
+
72
+ const ToastContainer = styled.div`
73
+ display: flex;
74
+ justify-content: center;
75
+ background: ${({ containerBackgroundColor }) => containerBackgroundColor};
76
+ gap: ${({ containerGap }) => containerGap};
77
+ height: 0;
78
+ overflow: hidden;
79
+ animation: ${animation};
80
+ `
81
+
82
+ const Toast = ({ toast, copy, headline, link, tokens, variant = {}, ...rest }) => {
83
+ const {
84
+ containerBackgroundColor,
85
+ containerGap,
86
+ animationHeightBefore,
87
+ animationHeightAfter,
88
+ animationPaddingBottomBefore,
89
+ animationPaddingBottomAfter,
90
+ animationPaddingTopBefore,
91
+ animationPaddingTopAfter,
92
+ animationBackgroundColorBefore,
93
+ animationBackgroundColorAfter,
94
+ animationColorBefore,
95
+ animationColorAfter,
96
+ animationFillColorBefore,
97
+ animationFillColorAfter
98
+ } = useThemeTokens('Toast', tokens, variant)
99
+
100
+ if (!toast) {
101
+ return null
102
+ }
103
+
104
+ return (
105
+ <ToastContainer
106
+ containerBackgroundColor={containerBackgroundColor}
107
+ containerGap={containerGap}
108
+ animationHeightBefore={animationHeightBefore}
109
+ animationHeightAfter={animationHeightAfter}
110
+ animationPaddingBottomBefore={animationPaddingBottomBefore}
111
+ animationPaddingBottomAfter={animationPaddingBottomAfter}
112
+ animationPaddingTopBefore={animationPaddingTopBefore}
113
+ animationPaddingTopAfter={animationPaddingTopAfter}
114
+ animationBackgroundColorBefore={animationBackgroundColorBefore}
115
+ animationBackgroundColorAfter={animationBackgroundColorAfter}
116
+ animationColorBefore={animationColorBefore}
117
+ animationColorAfter={animationColorAfter}
118
+ animationFillColorBefore={animationFillColorBefore}
119
+ animationFillColorAfter={animationFillColorAfter}
120
+ {...selectProps(rest)}
121
+ >
122
+ {headline && <Typography variant={{ bold: true, inverse: true }}>{headline}</Typography>}
123
+ <Typography variant={{ inverse: true }}>{copy}</Typography>
124
+ {link && (
125
+ <ChevronLink
126
+ variant={{ inverse: true }}
127
+ href={link.href}
128
+ LinkRouter={link.LinkRouter}
129
+ linkRouterProps={link.linkRouterProps}
130
+ >
131
+ {link.text}
132
+ </ChevronLink>
133
+ )}
134
+ </ToastContainer>
135
+ )
136
+ }
137
+
138
+ Toast.propTypes = {
139
+ ...selectedSystemPropTypes,
140
+ toast: PropTypes.bool,
141
+ copy: PropTypes.string.isRequired,
142
+ headline: PropTypes.string,
143
+ link: PropTypes.shape({
144
+ href: PropTypes.string.isRequired,
145
+ text: PropTypes.string.isRequired,
146
+ LinkRouter: withLinkRouter.propTypes?.LinkRouter,
147
+ linkRouterProps: withLinkRouter.propTypes?.linkRouterProps
148
+ })
149
+ }
150
+
151
+ export default Toast
@@ -0,0 +1,3 @@
1
+ import Toast from './Toast'
2
+
3
+ export default Toast
@@ -0,0 +1,137 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import styled from 'styled-components'
4
+ import {
5
+ Link,
6
+ responsiveProps,
7
+ selectSystemProps,
8
+ useResponsiveProp,
9
+ useThemeTokens,
10
+ withLinkRouter
11
+ } from '@telus-uds/components-base'
12
+ import OrderedListBase from '../OrderedList/OrderedListBase'
13
+ import ItemBase from '../OrderedList/ItemBase'
14
+ import Image from '../Image'
15
+ import { htmlAttrs } from '../utils'
16
+
17
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
18
+
19
+ const DEFAULT_ROW_SIZE = { sm: 2, lg: 3, xl: 6 }
20
+
21
+ const row = (rowSize, rowBorderSize) => ({
22
+ flexBasis: `calc(100% / ${rowSize})`,
23
+ [`:not(:nth-of-type(${rowSize}n + 1))`]: {
24
+ borderLeftWidth: `${rowBorderSize}px`
25
+ },
26
+ [`:nth-of-type(n+${rowSize + 1})`]: {
27
+ borderTopWidth: `${rowBorderSize}px`
28
+ }
29
+ })
30
+
31
+ const Container = styled(OrderedListBase)({
32
+ display: 'flex',
33
+ flexDirection: 'row',
34
+ flexWrap: 'wrap',
35
+ justifyContent: 'flex-start'
36
+ })
37
+
38
+ const Item = styled(ItemBase)(({ rowSize, itemPadding, itemBorderColor, rowBorderWidth }) => ({
39
+ display: 'flex',
40
+ flexDirection: 'column',
41
+ flexGrow: 0,
42
+ flexShrink: 0,
43
+ padding: `${itemPadding}px`,
44
+ boxSizing: 'border-box',
45
+ borderStyle: 'solid',
46
+ borderColor: itemBorderColor,
47
+ borderWidth: 0,
48
+ '& > a': {
49
+ alignSelf: 'center'
50
+ },
51
+ ...row(rowSize, rowBorderWidth)
52
+ }))
53
+
54
+ const Center = styled('div')({
55
+ display: 'flex',
56
+ flexDirection: 'column',
57
+ alignItems: 'center',
58
+ textAlign: 'center'
59
+ })
60
+
61
+ /**
62
+ * The WaffleGrid is used to show items in a waffle like manner with borders surrounding the element
63
+ */
64
+ const WaffleGrid = ({
65
+ items,
66
+ rowSize = DEFAULT_ROW_SIZE,
67
+ LinkRouter,
68
+ tokens,
69
+ variant,
70
+ linkRouterProps,
71
+ ...rest
72
+ }) => {
73
+ const themeTokens = useThemeTokens('WaffleGrid', tokens, variant)
74
+ const currentRowSize = useResponsiveProp(rowSize)
75
+
76
+ return (
77
+ <Container {...selectProps(rest)}>
78
+ {items.map((child) => (
79
+ <Item {...themeTokens} key={child.href} rowSize={currentRowSize}>
80
+ <Link
81
+ href={child.href}
82
+ variant={{ alternative: true }}
83
+ LinkRouter={child.LinkRouter || LinkRouter}
84
+ linkRouterProps={{ ...linkRouterProps, ...child.linkRouterProps }}
85
+ >
86
+ <Center>
87
+ {typeof child.image === 'string' ? (
88
+ // Assuming that string passed is the image URL
89
+ <Image src={child.image} alt={child.imageAltText} width={64} height={64} />
90
+ ) : (
91
+ // Otherwise it must be an arbitrary content, which we just display by itself
92
+ child.image
93
+ )}
94
+ <span>{child.text}</span>
95
+ </Center>
96
+ </Link>
97
+ </Item>
98
+ ))}
99
+ </Container>
100
+ )
101
+ }
102
+
103
+ WaffleGrid.propTypes = {
104
+ ...selectedSystemPropTypes,
105
+ /**
106
+ * The image and the link to display. `items` should be an array of objects with the following keys:
107
+ */
108
+ items: PropTypes.arrayOf(
109
+ PropTypes.shape({
110
+ /**
111
+ * The src attribute for the HTML img element or custom JSX content to render instead
112
+ */
113
+ image: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
114
+ /**
115
+ * The alt attribute for the HTML img element (note that this is ignored if a custom
116
+ * JSX content is used instead of an image URL)
117
+ */
118
+ imageAltText: PropTypes.string,
119
+ /**
120
+ * The text displayed under the image
121
+ */
122
+ text: PropTypes.string,
123
+ /**
124
+ * Target URL
125
+ */
126
+ href: PropTypes.string,
127
+ ...withLinkRouter.propTypes
128
+ })
129
+ ).isRequired,
130
+ /**
131
+ * Row size, optionally depending on the viewport
132
+ */
133
+ rowSize: responsiveProps.getTypeOptionallyByViewport(PropTypes.number),
134
+ ...withLinkRouter.propTypes
135
+ }
136
+
137
+ export default WaffleGrid
@@ -0,0 +1,3 @@
1
+ import WaffleGrid from './WaffleGrid'
2
+
3
+ export default WaffleGrid
@@ -31,7 +31,6 @@ export {
31
31
  InputLabel,
32
32
  InputSupports,
33
33
  Link,
34
- Modal,
35
34
  MultiSelectFilter,
36
35
  Notification,
37
36
  Pagination,
package/src/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  export { default as Badge } from './Badge'
2
+ export { default as Modal } from './Modal'
2
3
  export { default as OrderedList } from './OrderedList'
3
4
  export { default as PreviewCard } from './PreviewCard'
4
5
  export { default as ResponsiveImage } from './ResponsiveImage'
5
6
  export { default as Ribbon } from './Ribbon'
6
7
  export { default as DatePicker } from './DatePicker'
8
+ export { default as Paragraph } from './Paragraph'
7
9
  export { default as Span } from './Span'
8
10
  export { default as ExpandCollapseMini } from './ExpandCollapseMini'
9
11
  export { default as Callout } from './Callout'
@@ -11,5 +13,9 @@ export { default as PriceLockup } from './PriceLockup'
11
13
  export { default as Footnote } from './Footnote'
12
14
  export { transformGradient } from './utils'
13
15
  export { default as Breadcrumbs } from './Breadcrumbs'
16
+ export { default as Toast } from './Toast'
17
+ export { default as Table } from './Table'
18
+ export { default as Image } from './Image'
19
+ export { default as WaffleGrid } from './WaffleGrid'
14
20
 
15
21
  export * from './baseExports'
@@ -0,0 +1,13 @@
1
+ import type { ComponentType, ReactNode } from 'react'
2
+ import type { HTMLAttrs } from './common'
3
+
4
+ export interface CellProps extends HTMLAttrs {
5
+ children?: ReactNode
6
+ type?: 'default' | 'heading' | 'subHeading' | 'rowHeading'
7
+ isFirstInRow?: boolean
8
+ align: 'left' | 'center' | 'right'
9
+ }
10
+
11
+ declare const Cell: ComponentType<CellProps>
12
+
13
+ export default Cell
@@ -0,0 +1,12 @@
1
+ import type { ComponentType, ReactNode } from 'react'
2
+ import type { HTMLAttrs, Variant } from './common'
3
+
4
+ export interface TableProps extends HTMLAttrs {
5
+ children?: ReactNode
6
+ variant?: Variant
7
+ text?: 'small' | 'medium'
8
+ }
9
+
10
+ declare const Table: ComponentType<TableProps>
11
+
12
+ export default Table