@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.
- package/CHANGELOG.md +25 -2
- package/lib/Image/Image.js +126 -0
- package/lib/Image/index.js +13 -0
- package/lib/Modal/Modal.js +142 -0
- package/lib/Modal/ModalContent.js +195 -0
- package/lib/Modal/index.js +13 -0
- package/lib/Paragraph/Paragraph.js +107 -0
- package/lib/Paragraph/index.js +13 -0
- package/lib/Table/Body.js +29 -0
- package/lib/Table/Cell.js +200 -0
- package/lib/Table/Header.js +39 -0
- package/lib/Table/Row.js +35 -0
- package/lib/Table/SubHeading.js +37 -0
- package/lib/Table/Table.js +121 -0
- package/lib/Table/index.js +28 -0
- package/lib/Toast/Toast.js +136 -0
- package/lib/Toast/index.js +13 -0
- package/lib/WaffleGrid/WaffleGrid.js +176 -0
- package/lib/WaffleGrid/index.js +13 -0
- package/lib/baseExports.js +0 -6
- package/lib/index.js +55 -1
- package/lib-module/Image/Image.js +108 -0
- package/lib-module/Image/index.js +2 -0
- package/lib-module/Modal/Modal.js +128 -0
- package/lib-module/Modal/ModalContent.js +174 -0
- package/lib-module/Modal/index.js +2 -0
- package/lib-module/Paragraph/Paragraph.js +89 -0
- package/lib-module/Paragraph/index.js +2 -0
- package/lib-module/Table/Body.js +17 -0
- package/lib-module/Table/Cell.js +176 -0
- package/lib-module/Table/Header.js +22 -0
- package/lib-module/Table/Row.js +19 -0
- package/lib-module/Table/SubHeading.js +20 -0
- package/lib-module/Table/Table.js +93 -0
- package/lib-module/Table/index.js +12 -0
- package/lib-module/Toast/Toast.js +117 -0
- package/lib-module/Toast/index.js +2 -0
- package/lib-module/WaffleGrid/WaffleGrid.js +155 -0
- package/lib-module/WaffleGrid/index.js +2 -0
- package/lib-module/baseExports.js +1 -1
- package/lib-module/index.js +6 -0
- package/package.json +4 -3
- package/src/Image/Image.jsx +95 -0
- package/src/Image/index.js +3 -0
- package/src/Modal/Modal.jsx +111 -0
- package/src/Modal/ModalContent.jsx +161 -0
- package/src/Modal/index.js +3 -0
- package/src/Paragraph/Paragraph.jsx +79 -0
- package/src/Paragraph/index.js +3 -0
- package/src/Table/Body.jsx +12 -0
- package/src/Table/Cell.jsx +148 -0
- package/src/Table/Header.jsx +17 -0
- package/src/Table/Row.jsx +18 -0
- package/src/Table/SubHeading.jsx +17 -0
- package/src/Table/Table.jsx +90 -0
- package/src/Table/index.js +14 -0
- package/src/Toast/Toast.jsx +151 -0
- package/src/Toast/index.js +3 -0
- package/src/WaffleGrid/WaffleGrid.jsx +137 -0
- package/src/WaffleGrid/index.js +3 -0
- package/src/baseExports.js +0 -1
- package/src/index.js +6 -0
- package/types/Cell.d.ts +13 -0
- package/types/Table.d.ts +12 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* eslint-disable react/jsx-filename-extension */
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { Box, Button, Spacer, TextButton, Typography, useThemeTokens, useViewport } from '@telus-uds/components-base';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
const StyledModalContent = /*#__PURE__*/styled.div.withConfig({
|
|
9
|
+
displayName: "ModalContent__StyledModalContent",
|
|
10
|
+
componentId: "components-web__sc-k40cwb-0"
|
|
11
|
+
})(["display:flex;flex-direction:column;min-height:100%;"]);
|
|
12
|
+
const StyledHeading = /*#__PURE__*/styled.header.withConfig({
|
|
13
|
+
displayName: "ModalContent__StyledHeading",
|
|
14
|
+
componentId: "components-web__sc-k40cwb-1"
|
|
15
|
+
})(["display:flex;flex-direction:column;padding-right:", "px;"], _ref => {
|
|
16
|
+
let {
|
|
17
|
+
paddingRight
|
|
18
|
+
} = _ref;
|
|
19
|
+
return paddingRight;
|
|
20
|
+
});
|
|
21
|
+
const StyledSubHeading = /*#__PURE__*/styled.div.withConfig({
|
|
22
|
+
displayName: "ModalContent__StyledSubHeading",
|
|
23
|
+
componentId: "components-web__sc-k40cwb-2"
|
|
24
|
+
})(["margin-top:", "px;"], _ref2 => {
|
|
25
|
+
let {
|
|
26
|
+
marginTop
|
|
27
|
+
} = _ref2;
|
|
28
|
+
return marginTop;
|
|
29
|
+
});
|
|
30
|
+
const StyledFooter = /*#__PURE__*/styled.footer.withConfig({
|
|
31
|
+
displayName: "ModalContent__StyledFooter",
|
|
32
|
+
componentId: "components-web__sc-k40cwb-3"
|
|
33
|
+
})(_ref3 => {
|
|
34
|
+
let {
|
|
35
|
+
hasBorder,
|
|
36
|
+
viewport,
|
|
37
|
+
paddingLeft,
|
|
38
|
+
paddingRight,
|
|
39
|
+
paddingTop,
|
|
40
|
+
marginLeft,
|
|
41
|
+
marginRight,
|
|
42
|
+
borderColor,
|
|
43
|
+
gap
|
|
44
|
+
} = _ref3;
|
|
45
|
+
return {
|
|
46
|
+
display: 'flex',
|
|
47
|
+
flexDirection: viewport === 'xs' || viewport === 'sm' ? 'column' : 'row',
|
|
48
|
+
alignItems: 'center',
|
|
49
|
+
gap: `${gap}px`,
|
|
50
|
+
marginLeft: `calc(-1 * ${marginLeft}px)`,
|
|
51
|
+
marginRight: `calc(-1 * ${marginRight}px)`,
|
|
52
|
+
paddingLeft: `${paddingLeft}px`,
|
|
53
|
+
paddingRight: `${paddingRight}px`,
|
|
54
|
+
paddingTop: `${paddingTop}px`,
|
|
55
|
+
borderTop: hasBorder ? `1px solid ${borderColor}` : 'none'
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const ModalContent = _ref4 => {
|
|
60
|
+
let {
|
|
61
|
+
heading,
|
|
62
|
+
headingLevel = 'h3',
|
|
63
|
+
subHeading,
|
|
64
|
+
subHeadingSize = 'medium',
|
|
65
|
+
bodyText,
|
|
66
|
+
confirmButtonText,
|
|
67
|
+
confirmButtonVariant = {
|
|
68
|
+
priority: 'high'
|
|
69
|
+
},
|
|
70
|
+
onConfirm,
|
|
71
|
+
tokens,
|
|
72
|
+
variant,
|
|
73
|
+
cancelButtonText,
|
|
74
|
+
cancelButtonType: CancelButton = TextButton,
|
|
75
|
+
onCancel
|
|
76
|
+
} = _ref4;
|
|
77
|
+
const {
|
|
78
|
+
headingColor,
|
|
79
|
+
cancelButtonColor,
|
|
80
|
+
...themeTokens
|
|
81
|
+
} = useThemeTokens('Modal', tokens, variant);
|
|
82
|
+
const [scrollContainerHeight, setScrollContainerHeight] = useState(0);
|
|
83
|
+
const [scrollContentHeight, setScrollContentHeight] = useState(0);
|
|
84
|
+
const viewport = useViewport();
|
|
85
|
+
|
|
86
|
+
const handleContainerLayout = _ref5 => {
|
|
87
|
+
let {
|
|
88
|
+
nativeEvent: {
|
|
89
|
+
layout: {
|
|
90
|
+
height
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} = _ref5;
|
|
94
|
+
return setScrollContainerHeight(height);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const onContentSizeChange = (_, height) => setScrollContentHeight(height);
|
|
98
|
+
|
|
99
|
+
const isContentOverflowing = scrollContentHeight > scrollContainerHeight;
|
|
100
|
+
const hasConfirmButton = confirmButtonText !== undefined && onConfirm !== undefined;
|
|
101
|
+
const hasCancelButton = cancelButtonText !== undefined && onCancel !== undefined;
|
|
102
|
+
const hasHeadingSection = Boolean(heading || subHeading);
|
|
103
|
+
return /*#__PURE__*/_jsxs(StyledModalContent, {
|
|
104
|
+
children: [hasHeadingSection && /*#__PURE__*/_jsxs(StyledHeading, {
|
|
105
|
+
paddingRight: themeTokens.headingPaddingRight,
|
|
106
|
+
children: [heading && /*#__PURE__*/_jsx(Typography, {
|
|
107
|
+
variant: {
|
|
108
|
+
size: headingLevel
|
|
109
|
+
},
|
|
110
|
+
tokens: {
|
|
111
|
+
color: headingColor
|
|
112
|
+
},
|
|
113
|
+
heading: headingLevel,
|
|
114
|
+
children: heading
|
|
115
|
+
}), subHeading && /*#__PURE__*/_jsx(StyledSubHeading, {
|
|
116
|
+
marginTop: themeTokens.subHeadingMarginTop,
|
|
117
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
118
|
+
variant: {
|
|
119
|
+
size: subHeadingSize
|
|
120
|
+
},
|
|
121
|
+
children: subHeading
|
|
122
|
+
})
|
|
123
|
+
}), Boolean(bodyText && hasHeadingSection) && /*#__PURE__*/_jsx(Spacer, {
|
|
124
|
+
space: 3
|
|
125
|
+
})]
|
|
126
|
+
}), bodyText && /*#__PURE__*/_jsx(Box, {
|
|
127
|
+
scroll: {
|
|
128
|
+
onContentSizeChange,
|
|
129
|
+
showsVerticalScrollIndicator: true
|
|
130
|
+
},
|
|
131
|
+
onLayout: handleContainerLayout,
|
|
132
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
133
|
+
children: bodyText
|
|
134
|
+
})
|
|
135
|
+
}), (hasConfirmButton || hasCancelButton) && /*#__PURE__*/_jsxs(StyledFooter, { ...themeTokens,
|
|
136
|
+
hasBorder: isContentOverflowing,
|
|
137
|
+
viewport: viewport,
|
|
138
|
+
children: [hasConfirmButton && /*#__PURE__*/_jsx(Button, {
|
|
139
|
+
variant: confirmButtonVariant,
|
|
140
|
+
tokens: {
|
|
141
|
+
width: viewport === 'xs' || viewport === 'sm' ? '100%' : undefined
|
|
142
|
+
},
|
|
143
|
+
onPress: onConfirm,
|
|
144
|
+
children: confirmButtonText
|
|
145
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
146
|
+
children: hasCancelButton && /*#__PURE__*/_jsx(CancelButton, {
|
|
147
|
+
tokens: {
|
|
148
|
+
color: cancelButtonColor
|
|
149
|
+
},
|
|
150
|
+
onPress: onCancel,
|
|
151
|
+
children: cancelButtonText
|
|
152
|
+
})
|
|
153
|
+
})]
|
|
154
|
+
})]
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
ModalContent.propTypes = {
|
|
159
|
+
tokens: PropTypes.object,
|
|
160
|
+
variant: PropTypes.object,
|
|
161
|
+
heading: PropTypes.string,
|
|
162
|
+
headingLevel: PropTypes.oneOf(['h3', 'h4']),
|
|
163
|
+
subHeading: PropTypes.string,
|
|
164
|
+
subHeadingSize: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
165
|
+
bodyText: PropTypes.string,
|
|
166
|
+
confirmButtonText: PropTypes.string,
|
|
167
|
+
confirmButtonVariant: PropTypes.object,
|
|
168
|
+
onConfirm: PropTypes.func,
|
|
169
|
+
cancelButtonText: PropTypes.string,
|
|
170
|
+
cancelButtonType: PropTypes.elementType,
|
|
171
|
+
// TODO: figure out a way of passing an icon to the TextButton
|
|
172
|
+
onCancel: PropTypes.func
|
|
173
|
+
};
|
|
174
|
+
export default ModalContent;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { selectSystemProps } from '@telus-uds/components-base';
|
|
5
|
+
import { htmlAttrs, useTypographyTheme } from '../utils';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
8
|
+
const StyledParagraph = /*#__PURE__*/styled.p.withConfig({
|
|
9
|
+
displayName: "Paragraph__StyledParagraph",
|
|
10
|
+
componentId: "components-web__sc-1bg9r8p-0"
|
|
11
|
+
})(["", " ", " &:first-child{margin-block-start:0em;}&:last-child{margin-block-end:0em;}"], _ref => {
|
|
12
|
+
let {
|
|
13
|
+
align
|
|
14
|
+
} = _ref;
|
|
15
|
+
return align ? `text-align: ${align};` : '';
|
|
16
|
+
}, _ref2 => {
|
|
17
|
+
let {
|
|
18
|
+
linesBetween
|
|
19
|
+
} = _ref2;
|
|
20
|
+
return `
|
|
21
|
+
margin-block-start: ${linesBetween}em;
|
|
22
|
+
margin-block-end: ${linesBetween}em;
|
|
23
|
+
`;
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Block text as an HTML ```<p>``` element.
|
|
27
|
+
*
|
|
28
|
+
* ##Usage criteria
|
|
29
|
+
*
|
|
30
|
+
* - All body text should be contained in a **Paragraph**, regardless of length.
|
|
31
|
+
* - If the Paragraph is on a dark background, variant **{ invert: true }** must be used to maintain sufficient colour
|
|
32
|
+
contrast.
|
|
33
|
+
* - All Allium Typography variants other than header size variants are supported.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
const Paragraph = _ref3 => {
|
|
37
|
+
let {
|
|
38
|
+
children,
|
|
39
|
+
variant,
|
|
40
|
+
tokens,
|
|
41
|
+
testID,
|
|
42
|
+
align,
|
|
43
|
+
linesBetween = 1,
|
|
44
|
+
...rest
|
|
45
|
+
} = _ref3;
|
|
46
|
+
const style = useTypographyTheme(variant, tokens);
|
|
47
|
+
return /*#__PURE__*/_jsx(StyledParagraph, {
|
|
48
|
+
linesBetween: linesBetween,
|
|
49
|
+
"data-testid": testID,
|
|
50
|
+
align: align,
|
|
51
|
+
style: style,
|
|
52
|
+
...selectProps(rest),
|
|
53
|
+
children: children
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
Paragraph.propTypes = { ...selectedSystemPropTypes,
|
|
58
|
+
children: PropTypes.node.isRequired,
|
|
59
|
+
testID: PropTypes.string,
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sets the alignment style for the paragraph. Same options as Typography's `align` prop.
|
|
63
|
+
* 'justify' should be avoided as it usually reduces ease of reading.
|
|
64
|
+
*/
|
|
65
|
+
align: PropTypes.oneOf(['auto', 'left', 'right', 'center', 'justify']),
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* How much space between consecutive paragraphs, or between a paragraph and its siblings, in CSS
|
|
69
|
+
* `em` units: 1 gives space equal to one line of paragraph text, 0.5 would be half a line, etc.
|
|
70
|
+
* @default 1
|
|
71
|
+
*/
|
|
72
|
+
linesBetween: PropTypes.number,
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Paragraph takes the same tokens overrides as Typography
|
|
76
|
+
*/
|
|
77
|
+
tokens: PropTypes.oneOf([PropTypes.object, PropTypes.func]),
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Paragraph takes any of Typography's theme variants except for header sizes
|
|
81
|
+
*/
|
|
82
|
+
variant: PropTypes.exact({
|
|
83
|
+
bold: PropTypes.bool,
|
|
84
|
+
colour: PropTypes.oneOf(['secondary', 'tertiary']),
|
|
85
|
+
inverse: PropTypes.bool,
|
|
86
|
+
size: PropTypes.oneOf(['micro', 'small', 'large'])
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
export default Paragraph;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
const Body = _ref => {
|
|
6
|
+
let {
|
|
7
|
+
children
|
|
8
|
+
} = _ref;
|
|
9
|
+
return /*#__PURE__*/_jsx("tbody", {
|
|
10
|
+
children: children
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
Body.propTypes = {
|
|
15
|
+
children: PropTypes.node
|
|
16
|
+
};
|
|
17
|
+
export default Body;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled, { css } from 'styled-components';
|
|
4
|
+
import { Typography, useThemeTokens } from '@telus-uds/components-base';
|
|
5
|
+
import { useTableContext } from './Table';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const stickyStyles = /*#__PURE__*/css(["position:sticky;left:0;z-index:2;clip-path:inset(0 -8px 0 0);&::before{content:'';box-shadow:", ";position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:none;}"], _ref => {
|
|
8
|
+
let {
|
|
9
|
+
cellStickyShadow
|
|
10
|
+
} = _ref;
|
|
11
|
+
return cellStickyShadow;
|
|
12
|
+
});
|
|
13
|
+
const sharedStyles = /*#__PURE__*/css(["", ""], _ref2 => {
|
|
14
|
+
let {
|
|
15
|
+
isSticky,
|
|
16
|
+
cellBoxShadowColor,
|
|
17
|
+
align,
|
|
18
|
+
cellPaddingTop,
|
|
19
|
+
cellPaddingRight,
|
|
20
|
+
cellPaddingBottom,
|
|
21
|
+
cellPaddingLeft
|
|
22
|
+
} = _ref2;
|
|
23
|
+
return css(["", ";box-shadow:inset 0 -1px 0 ", ";text-align:", ";padding:", "px ", "px ", "px ", "px;"], isSticky ? stickyStyles : undefined, cellBoxShadowColor, align, cellPaddingTop, cellPaddingRight, cellPaddingBottom, cellPaddingLeft);
|
|
24
|
+
});
|
|
25
|
+
const StyledHeading = /*#__PURE__*/styled.th.withConfig({
|
|
26
|
+
displayName: "Cell__StyledHeading",
|
|
27
|
+
componentId: "components-web__sc-ltgfic-0"
|
|
28
|
+
})(["", ";", ""], sharedStyles, _ref3 => {
|
|
29
|
+
let {
|
|
30
|
+
cellHeadingBackground,
|
|
31
|
+
cellHeadingBoxShadowColor
|
|
32
|
+
} = _ref3;
|
|
33
|
+
return `
|
|
34
|
+
background-color: ${cellHeadingBackground};
|
|
35
|
+
box-shadow: inset 0 1px 0 ${cellHeadingBoxShadowColor}, inset 0 -1px 0 ${cellHeadingBoxShadowColor};`;
|
|
36
|
+
});
|
|
37
|
+
const StyledSubHeading = /*#__PURE__*/styled.th.withConfig({
|
|
38
|
+
displayName: "Cell__StyledSubHeading",
|
|
39
|
+
componentId: "components-web__sc-ltgfic-1"
|
|
40
|
+
})(["", ";background-color:", ";"], sharedStyles, _ref4 => {
|
|
41
|
+
let {
|
|
42
|
+
cellSubheadingBackground
|
|
43
|
+
} = _ref4;
|
|
44
|
+
return cellSubheadingBackground;
|
|
45
|
+
});
|
|
46
|
+
const StyledCell = /*#__PURE__*/styled.td.withConfig({
|
|
47
|
+
displayName: "Cell__StyledCell",
|
|
48
|
+
componentId: "components-web__sc-ltgfic-2"
|
|
49
|
+
})(["", ";background-color:", ";"], sharedStyles, _ref5 => {
|
|
50
|
+
let {
|
|
51
|
+
cellBackground
|
|
52
|
+
} = _ref5;
|
|
53
|
+
return cellBackground;
|
|
54
|
+
});
|
|
55
|
+
const StyledRowHeading = /*#__PURE__*/styled.th.withConfig({
|
|
56
|
+
displayName: "Cell__StyledRowHeading",
|
|
57
|
+
componentId: "components-web__sc-ltgfic-3"
|
|
58
|
+
})(["", ";background-color:", ";"], sharedStyles, _ref6 => {
|
|
59
|
+
let {
|
|
60
|
+
cellRowHeadingBackground
|
|
61
|
+
} = _ref6;
|
|
62
|
+
return cellRowHeadingBackground;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const Cell = _ref7 => {
|
|
66
|
+
let {
|
|
67
|
+
children,
|
|
68
|
+
type = 'default',
|
|
69
|
+
isFirstInRow,
|
|
70
|
+
align = 'left'
|
|
71
|
+
} = _ref7;
|
|
72
|
+
const {
|
|
73
|
+
text,
|
|
74
|
+
isScrollable: isTableScrollable,
|
|
75
|
+
variant,
|
|
76
|
+
tokens
|
|
77
|
+
} = useTableContext();
|
|
78
|
+
const {
|
|
79
|
+
cellHeadingBackground,
|
|
80
|
+
cellHeadingBoxShadowColor,
|
|
81
|
+
cellBoxShadowColor,
|
|
82
|
+
cellSubheadingBackground,
|
|
83
|
+
cellBackground,
|
|
84
|
+
cellRowHeadingBackground,
|
|
85
|
+
cellStickyShadow,
|
|
86
|
+
cellPaddingTop,
|
|
87
|
+
cellPaddingRight,
|
|
88
|
+
cellPaddingLeft,
|
|
89
|
+
cellPaddingBottom
|
|
90
|
+
} = useThemeTokens('Table', tokens, variant);
|
|
91
|
+
const sharedProps = {
|
|
92
|
+
align,
|
|
93
|
+
isSticky: isTableScrollable && isFirstInRow,
|
|
94
|
+
cellStickyShadow,
|
|
95
|
+
cellPaddingTop,
|
|
96
|
+
cellPaddingRight,
|
|
97
|
+
cellPaddingLeft,
|
|
98
|
+
cellPaddingBottom,
|
|
99
|
+
cellBoxShadowColor
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
switch (type) {
|
|
103
|
+
case 'heading':
|
|
104
|
+
return /*#__PURE__*/_jsx(StyledHeading, {
|
|
105
|
+
scope: "col",
|
|
106
|
+
cellHeadingBackground: cellHeadingBackground,
|
|
107
|
+
cellHeadingBoxShadowColor: cellHeadingBoxShadowColor,
|
|
108
|
+
...sharedProps,
|
|
109
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
110
|
+
variant: {
|
|
111
|
+
size: 'h4'
|
|
112
|
+
},
|
|
113
|
+
children: children
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
case 'subHeading':
|
|
118
|
+
return /*#__PURE__*/_jsx(StyledSubHeading, {
|
|
119
|
+
scope: "col",
|
|
120
|
+
cellSubheadingBackground: cellSubheadingBackground,
|
|
121
|
+
...sharedProps,
|
|
122
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
123
|
+
variant: {
|
|
124
|
+
size: 'h5'
|
|
125
|
+
},
|
|
126
|
+
children: children
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
case 'rowHeading':
|
|
131
|
+
return /*#__PURE__*/_jsx(StyledRowHeading, {
|
|
132
|
+
scope: "row",
|
|
133
|
+
cellRowHeadingBackground: cellRowHeadingBackground,
|
|
134
|
+
...sharedProps,
|
|
135
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
136
|
+
variant: {
|
|
137
|
+
size: text === 'small' ? 'h5' : 'h4'
|
|
138
|
+
},
|
|
139
|
+
children: children
|
|
140
|
+
})
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
default:
|
|
144
|
+
return /*#__PURE__*/_jsx(StyledCell, {
|
|
145
|
+
cellBackground: cellBackground,
|
|
146
|
+
...sharedProps,
|
|
147
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
148
|
+
variant: {
|
|
149
|
+
size: text
|
|
150
|
+
},
|
|
151
|
+
children: children
|
|
152
|
+
})
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
Cell.propTypes = {
|
|
158
|
+
children: PropTypes.node,
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Defines the visual styles of a cell, and whether it should be a `td` or `th` element
|
|
162
|
+
*/
|
|
163
|
+
type: PropTypes.oneOf(['default', 'heading', 'subHeading', 'rowHeading']),
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @ignore
|
|
167
|
+
* Used internally for making the first column sticky
|
|
168
|
+
*/
|
|
169
|
+
isFirstInRow: PropTypes.bool,
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Defines the text alignment within the cell
|
|
173
|
+
*/
|
|
174
|
+
align: PropTypes.oneOf(['left', 'center', 'right'])
|
|
175
|
+
};
|
|
176
|
+
export default Cell;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { cloneElement } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Row from './Row';
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
const Header = _ref => {
|
|
7
|
+
let {
|
|
8
|
+
children
|
|
9
|
+
} = _ref;
|
|
10
|
+
return /*#__PURE__*/_jsx("thead", {
|
|
11
|
+
children: /*#__PURE__*/_jsx(Row, {
|
|
12
|
+
children: React.Children.map(children, child => /*#__PURE__*/cloneElement(child, {
|
|
13
|
+
type: 'heading'
|
|
14
|
+
}))
|
|
15
|
+
})
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Header.propTypes = {
|
|
20
|
+
children: PropTypes.node
|
|
21
|
+
};
|
|
22
|
+
export default Header;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React, { cloneElement } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
const Row = _ref => {
|
|
6
|
+
let {
|
|
7
|
+
children
|
|
8
|
+
} = _ref;
|
|
9
|
+
return /*#__PURE__*/_jsx("tr", {
|
|
10
|
+
children: React.Children.map(children, (child, index) => /*#__PURE__*/cloneElement(child, {
|
|
11
|
+
isFirstInRow: index === 0
|
|
12
|
+
}))
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
Row.propTypes = {
|
|
17
|
+
children: PropTypes.node
|
|
18
|
+
};
|
|
19
|
+
export default Row;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React, { cloneElement } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Row from './Row';
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
const Header = _ref => {
|
|
7
|
+
let {
|
|
8
|
+
children
|
|
9
|
+
} = _ref;
|
|
10
|
+
return /*#__PURE__*/_jsx(Row, {
|
|
11
|
+
children: React.Children.map(children, child => /*#__PURE__*/cloneElement(child, {
|
|
12
|
+
type: 'subHeading'
|
|
13
|
+
}))
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Header.propTypes = {
|
|
18
|
+
children: PropTypes.node
|
|
19
|
+
};
|
|
20
|
+
export default Header;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { useContext, useRef, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { selectSystemProps, useSafeLayoutEffect, useThemeTokens } from '@telus-uds/components-base';
|
|
5
|
+
import throttle from 'lodash.throttle';
|
|
6
|
+
import { htmlAttrs } from '../utils';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
9
|
+
const StyledContainer = /*#__PURE__*/styled.div.withConfig({
|
|
10
|
+
displayName: "Table__StyledContainer",
|
|
11
|
+
componentId: "components-web__sc-10d9q3m-0"
|
|
12
|
+
})(["overflow:auto;padding-bottom:", ";"], props => props.isScrollable ? props.tablePaddingBottom : 0);
|
|
13
|
+
const StyledTable = /*#__PURE__*/styled.table.withConfig({
|
|
14
|
+
displayName: "Table__StyledTable",
|
|
15
|
+
componentId: "components-web__sc-10d9q3m-1"
|
|
16
|
+
})(["margin:0;padding:0;"]);
|
|
17
|
+
const TableContext = /*#__PURE__*/React.createContext({});
|
|
18
|
+
export const useTableContext = () => useContext(TableContext);
|
|
19
|
+
/**
|
|
20
|
+
* Use `Table` to display tabular data.
|
|
21
|
+
*
|
|
22
|
+
* - Takes an optional `spacing` variant (compact)
|
|
23
|
+
* - Available in 2 text styles (medium, small)
|
|
24
|
+
* - When `Table` exceeds viewport, the first column becomes sticky, enabling horizontal scrolling
|
|
25
|
+
* - Right-align prices and numbers that display decimal points
|
|
26
|
+
*
|
|
27
|
+
* ### Building up a `Table`
|
|
28
|
+
* - Use `Table.Header` and `Table.Body` as direct children of `Table`
|
|
29
|
+
* - Use `Table.SubHeading` to render an intermediate data heading row
|
|
30
|
+
* - Use `Table.Row` and `Table.Cell` to build up the tabular data
|
|
31
|
+
* - Use `Cell`'s `type` prop to visually mark it as a row heading (`type="rowHeading"`)
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const Table = _ref => {
|
|
35
|
+
let {
|
|
36
|
+
children,
|
|
37
|
+
text = 'medium',
|
|
38
|
+
tokens,
|
|
39
|
+
variant,
|
|
40
|
+
...rest
|
|
41
|
+
} = _ref;
|
|
42
|
+
const {
|
|
43
|
+
tablePaddingBottom
|
|
44
|
+
} = useThemeTokens('Table', tokens, variant);
|
|
45
|
+
const containerRef = useRef();
|
|
46
|
+
const tableRef = useRef();
|
|
47
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
48
|
+
const [tableWidth, setTableWidth] = useState(0);
|
|
49
|
+
useSafeLayoutEffect(() => {
|
|
50
|
+
const updateDimensions = () => {
|
|
51
|
+
setContainerWidth(containerRef.current.clientWidth);
|
|
52
|
+
setTableWidth(tableRef.current.clientWidth);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const throttledUpdateDimensions = throttle(updateDimensions, 100, {
|
|
56
|
+
leading: false
|
|
57
|
+
});
|
|
58
|
+
updateDimensions(); // a pretty naive way of repeating the measurement after the fonts are loaded
|
|
59
|
+
|
|
60
|
+
window.addEventListener('load', updateDimensions);
|
|
61
|
+
window.addEventListener('resize', throttledUpdateDimensions);
|
|
62
|
+
return () => {
|
|
63
|
+
window.removeEventListener('load', updateDimensions);
|
|
64
|
+
window.removeEventListener('resize', throttledUpdateDimensions);
|
|
65
|
+
};
|
|
66
|
+
}, []);
|
|
67
|
+
const isScrollable = tableWidth > containerWidth;
|
|
68
|
+
return /*#__PURE__*/_jsx(StyledContainer, {
|
|
69
|
+
ref: containerRef,
|
|
70
|
+
isScrollable: isScrollable,
|
|
71
|
+
tablePaddingBottom: `${tablePaddingBottom}px`,
|
|
72
|
+
...selectProps(rest),
|
|
73
|
+
children: /*#__PURE__*/_jsx(TableContext.Provider, {
|
|
74
|
+
value: {
|
|
75
|
+
text,
|
|
76
|
+
isScrollable,
|
|
77
|
+
tokens,
|
|
78
|
+
variant
|
|
79
|
+
},
|
|
80
|
+
children: /*#__PURE__*/_jsx(StyledTable, {
|
|
81
|
+
cellSpacing: 0,
|
|
82
|
+
ref: tableRef,
|
|
83
|
+
children: children
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
Table.propTypes = { ...selectedSystemPropTypes,
|
|
90
|
+
children: PropTypes.node,
|
|
91
|
+
text: PropTypes.oneOf(['medium', 'small'])
|
|
92
|
+
};
|
|
93
|
+
export default Table;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Table from './Table';
|
|
2
|
+
import Header from './Header';
|
|
3
|
+
import Body from './Body';
|
|
4
|
+
import Row from './Row';
|
|
5
|
+
import SubHeading from './SubHeading';
|
|
6
|
+
import Cell from './Cell';
|
|
7
|
+
Table.Header = Header;
|
|
8
|
+
Table.Body = Body;
|
|
9
|
+
Table.Row = Row;
|
|
10
|
+
Table.SubHeading = SubHeading;
|
|
11
|
+
Table.Cell = Cell;
|
|
12
|
+
export default Table;
|