@telus-uds/components-web 2.12.0 → 2.14.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 (65) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/component-docs.json +105 -43
  3. package/lib/Autocomplete/Loading.js +5 -10
  4. package/lib/Autocomplete/dictionary.js +2 -2
  5. package/lib/Badge/Badge.js +10 -1
  6. package/lib/DatePicker/DatePicker.js +13 -0
  7. package/lib/NavigationBar/NavigationSubMenu.js +4 -8
  8. package/lib/QuantitySelector/QuantitySelector.js +67 -66
  9. package/lib/QuantitySelector/SideButton.js +93 -0
  10. package/lib/QuantitySelector/styles.js +4 -20
  11. package/lib/Spinner/Spinner.js +10 -1
  12. package/lib/Spinner/SpinnerContent.js +8 -0
  13. package/lib/Table/Cell.js +62 -91
  14. package/lib/Table/Header.js +4 -1
  15. package/lib/Table/SubHeading.js +4 -1
  16. package/lib/Table/Table.js +2 -1
  17. package/lib/TermsAndConditions/ExpandCollapse.js +31 -13
  18. package/lib/TermsAndConditions/TermsAndConditions.js +42 -10
  19. package/lib/Testimonial/Testimonial.js +48 -12
  20. package/lib/VideoPicker/VideoPickerPlayer.js +4 -2
  21. package/lib/VideoPicker/VideoPickerThumbnail.js +103 -60
  22. package/lib/VideoPicker/VideoSlider.js +2 -2
  23. package/lib-module/Autocomplete/Loading.js +6 -12
  24. package/lib-module/Autocomplete/dictionary.js +2 -2
  25. package/lib-module/Badge/Badge.js +10 -1
  26. package/lib-module/DatePicker/DatePicker.js +13 -1
  27. package/lib-module/NavigationBar/NavigationSubMenu.js +5 -9
  28. package/lib-module/QuantitySelector/QuantitySelector.js +68 -67
  29. package/lib-module/QuantitySelector/SideButton.js +80 -0
  30. package/lib-module/QuantitySelector/styles.js +3 -15
  31. package/lib-module/Spinner/Spinner.js +10 -1
  32. package/lib-module/Spinner/SpinnerContent.js +8 -0
  33. package/lib-module/Table/Cell.js +65 -90
  34. package/lib-module/Table/Header.js +4 -1
  35. package/lib-module/Table/SubHeading.js +4 -1
  36. package/lib-module/Table/Table.js +2 -1
  37. package/lib-module/TermsAndConditions/ExpandCollapse.js +33 -15
  38. package/lib-module/TermsAndConditions/TermsAndConditions.js +42 -11
  39. package/lib-module/Testimonial/Testimonial.js +49 -13
  40. package/lib-module/VideoPicker/VideoPickerPlayer.js +4 -2
  41. package/lib-module/VideoPicker/VideoPickerThumbnail.js +103 -61
  42. package/lib-module/VideoPicker/VideoSlider.js +2 -2
  43. package/package.json +4 -4
  44. package/src/Autocomplete/Loading.jsx +2 -5
  45. package/src/Autocomplete/dictionary.js +2 -2
  46. package/src/Badge/Badge.jsx +14 -2
  47. package/src/DatePicker/DatePicker.jsx +14 -1
  48. package/src/NavigationBar/NavigationSubMenu.jsx +3 -4
  49. package/src/QuantitySelector/QuantitySelector.jsx +60 -76
  50. package/src/QuantitySelector/SideButton.jsx +74 -0
  51. package/src/QuantitySelector/styles.js +4 -70
  52. package/src/Spinner/Spinner.jsx +9 -1
  53. package/src/Spinner/SpinnerContent.jsx +13 -1
  54. package/src/Table/Cell.jsx +58 -78
  55. package/src/Table/Header.jsx +6 -1
  56. package/src/Table/SubHeading.jsx +4 -1
  57. package/src/Table/Table.jsx +10 -2
  58. package/src/TermsAndConditions/ExpandCollapse.jsx +36 -14
  59. package/src/TermsAndConditions/TermsAndConditions.jsx +48 -10
  60. package/src/Testimonial/Testimonial.jsx +73 -11
  61. package/src/VideoPicker/VideoPickerPlayer.jsx +2 -2
  62. package/src/VideoPicker/VideoPickerThumbnail.jsx +51 -30
  63. package/src/VideoPicker/VideoSlider.jsx +2 -2
  64. package/types/BaseProvider.d.ts +25 -0
  65. package/types/index.d.ts +1 -1
@@ -0,0 +1,74 @@
1
+ import { IconButton, useThemeTokensCallback } from '@telus-uds/components-base'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+
5
+ const SideButton = ({
6
+ isEnabled,
7
+ onPress,
8
+ onDoubleClick,
9
+ accessibilityLabel,
10
+ accessibilityDisabled,
11
+ tokens,
12
+ variant
13
+ }) => {
14
+ const getTokens = useThemeTokensCallback('QuantitySelectorSideButton', tokens, variant)
15
+ const getButtonTokens = ({ buttonState, disabled }) => {
16
+ const {
17
+ borderRadius,
18
+ borderTopLeftRadius,
19
+ borderTopRightRadius,
20
+ borderBottomLeftRadius,
21
+ borderBottomRightRadius,
22
+ ...rest
23
+ } = getTokens({ ...buttonState, disabled })
24
+
25
+ return {
26
+ ...rest,
27
+ borderRadius,
28
+ borderTopLeftRadius,
29
+ borderTopRightRadius,
30
+ borderBottomLeftRadius,
31
+ borderBottomRightRadius,
32
+ outerBorderRadius: borderRadius,
33
+ outerBorderTopLeftRadius: borderTopLeftRadius,
34
+ outerBorderTopRightRadius: borderTopRightRadius,
35
+ outerBorderBottomLeftRadius: borderBottomLeftRadius,
36
+ outerBorderBottomRightRadius: borderBottomRightRadius,
37
+ outerBorderGap: 0,
38
+ outerBorderWidth: 0
39
+ }
40
+ }
41
+
42
+ return (
43
+ <IconButton
44
+ tokens={(buttonState) => getButtonTokens({ disabled: !isEnabled, buttonState })}
45
+ onPress={onPress}
46
+ onDoubleClick={onDoubleClick}
47
+ accessibilityLabel={accessibilityLabel}
48
+ accessibilityDisabled={accessibilityDisabled}
49
+ />
50
+ )
51
+ }
52
+
53
+ SideButton.displayName = 'QuantitySelectorSideButton'
54
+
55
+ SideButton.defaultProps = {
56
+ isEnabled: true,
57
+ onPress: () => {},
58
+ onDoubleClick: () => {},
59
+ accessibilityLabel: '',
60
+ accessibilityDisabled: false,
61
+ tokens: {},
62
+ variant: {}
63
+ }
64
+
65
+ SideButton.propTypes = {
66
+ isEnabled: PropTypes.bool,
67
+ onPress: PropTypes.func,
68
+ onDoubleClick: PropTypes.func,
69
+ accessibilityLabel: PropTypes.string,
70
+ accessibilityDisabled: PropTypes.bool,
71
+ tokens: PropTypes.object,
72
+ variant: PropTypes.object
73
+ }
74
+ export default SideButton
@@ -1,83 +1,17 @@
1
1
  import styled from 'styled-components'
2
2
 
3
3
  export const InputField = styled.div`
4
- order: 2;
5
- min-width: 3.5rem;
6
- max-width: 5 rem;
7
- height: 28px;
8
- padding: 0;
9
- width: 64px;
4
+ order: 1;
10
5
  text-align: center;
11
6
  z-index: 10;
12
7
  input {
13
8
  text-align: center;
14
9
  }
15
-
16
- &.alternative {
17
- input {
18
- height: 40px;
19
- }
20
- }
21
- `
22
-
23
- const ButtonWrapper = styled.div`
24
- &.alternative {
25
- div[role='button'] {
26
- height: 42px;
27
- > div {
28
- height: 40px;
29
- > div {
30
- padding: 12px 16px;
31
- }
32
- }
33
- }
34
- }
35
- `
36
-
37
- export const LeftButtonWrapper = styled(ButtonWrapper)`
38
- order: 0;
39
- div[role='button'] {
40
- border-radius: 4px 0px 0px 4px !important;
41
- > div {
42
- border-right: none;
43
- border-radius: 4px 0px 0px 4px !important;
44
- }
45
- }
46
-
47
- &.alternative {
48
- div[role='button'] {
49
- border-radius: 36px 0px 0px 36px !important;
50
- > div {
51
- border-radius: 24px 0px 0px 24px !important;
52
- }
53
- }
54
- }
55
- `
56
-
57
- export const RightButtonWrapper = styled(ButtonWrapper)`
58
- order: 3;
59
- div[role='button'] {
60
- border-radius: 0px 4px 4px 0px !important;
61
- > div {
62
- border-left: none;
63
- border-radius: 0px 4px 4px 0px !important;
64
- }
65
- }
66
-
67
- &.alternative {
68
- div[role='button'] {
69
- border-radius: 0px 36px 36px 0px !important;
70
- > div {
71
- border-radius: 0px 36px 36px 0px !important;
72
- }
73
- }
74
- }
75
10
  `
76
11
 
77
12
  export const InputWrapper = styled.div`
78
- textalign: start;
13
+ text-align: start;
79
14
  display: flex;
80
- flexdirection: row;
81
- flexwrap: nowrap;
82
- justifycontent: center;
15
+ flex-direction: row;
16
+ flex-wrap: nowrap;
83
17
  `
@@ -64,6 +64,7 @@ const Spinner = ({
64
64
  fullScreen = false,
65
65
  inline = false,
66
66
  label,
67
+ labelPosition,
67
68
  show = false,
68
69
  isStatic = false,
69
70
  tokens,
@@ -97,6 +98,7 @@ const Spinner = ({
97
98
  >
98
99
  <SpinnerContent
99
100
  label={label}
101
+ labelPosition={labelPosition}
100
102
  overlay={true}
101
103
  size={size}
102
104
  thickness={thickness}
@@ -115,6 +117,7 @@ const Spinner = ({
115
117
  <SpinnerContainer inline={inline} aria-live="assertive" {...selectProps(rest)}>
116
118
  <SpinnerContent
117
119
  label={label}
120
+ labelPosition={labelPosition}
118
121
  overlay={true}
119
122
  size={size}
120
123
  thickness={thickness}
@@ -141,6 +144,7 @@ const Spinner = ({
141
144
  <SpinnerContainer {...selectProps(rest)}>
142
145
  <SpinnerContent
143
146
  label={label}
147
+ labelPosition={labelPosition}
144
148
  size={size}
145
149
  thickness={thickness}
146
150
  sizeVariant={sizeVariant}
@@ -183,7 +187,11 @@ Spinner.propTypes = {
183
187
  /**
184
188
  * If true, it should render a static spinner
185
189
  */
186
- isStatic: PropTypes.bool
190
+ isStatic: PropTypes.bool,
191
+ /**
192
+ * Determine where the label of the spinner should be placed, left, right, bottom or top.
193
+ */
194
+ labelPosition: PropTypes.string
187
195
  }
188
196
 
189
197
  export default Spinner
@@ -27,6 +27,7 @@ const Container = styled.div(({ overlay }) => ({
27
27
 
28
28
  const SpinnerContent = ({
29
29
  label,
30
+ labelPosition,
30
31
  overlay = false,
31
32
  sizeVariant,
32
33
  size,
@@ -34,9 +35,20 @@ const SpinnerContent = ({
34
35
  isStatic,
35
36
  ...rest
36
37
  }) => {
38
+ const labelMapping = {
39
+ top: 'column-reverse',
40
+ bottom: 'column',
41
+ left: 'row-reverse',
42
+ right: 'row'
43
+ }
44
+
37
45
  return (
38
46
  <Container overlay={overlay}>
39
- <StackView space={3} tokens={{ alignItems: 'center' }}>
47
+ <StackView
48
+ space={3}
49
+ tokens={{ alignItems: 'center' }}
50
+ direction={labelMapping[labelPosition]}
51
+ >
40
52
  <ActivityIndicator
41
53
  label={label}
42
54
  tokens={{ size, thickness }}
@@ -1,19 +1,28 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled, { css } from 'styled-components'
4
- import { Typography, useThemeTokens } from '@telus-uds/components-base'
4
+ import { Typography, useThemeTokens, applyShadowToken } from '@telus-uds/components-base'
5
5
  import { useTableContext } from './Table'
6
6
 
7
- const stickyStyles = css`
7
+ const HEADER_TYPE = {
8
+ HEADING: 'heading',
9
+ SUBHEADING: 'subHeading',
10
+ ROWHEADING: 'rowHeading'
11
+ }
12
+
13
+ const stickyStyles = ({ cellStickyShadow, stickyBackgroundColor, type }) => css`
8
14
  position: sticky;
9
15
  left: 0; // needed for sticky to work
10
16
  z-index: 2;
11
17
  clip-path: inset(0 -8px 0 0); // use clip path to cut off the shadow rendered below
12
-
18
+ // Override default cell background with stickyBackgroundColor with an exception to subheading and heading
19
+ ${type !== HEADER_TYPE.SUBHEADING && type !== HEADER_TYPE.HEADING
20
+ ? `background-color: ${stickyBackgroundColor};`
21
+ : undefined}
13
22
  &::before {
14
23
  // use a pseudo element for the sticky shadow, since we already use shadows for inner cells border
15
24
  content: '';
16
- box-shadow: ${({ cellStickyShadow }) => cellStickyShadow};
25
+ box-shadow: ${cellStickyShadow};
17
26
  position: absolute;
18
27
  top: 0;
19
28
  left: 0;
@@ -25,55 +34,43 @@ const stickyStyles = css`
25
34
  const sharedStyles = css`
26
35
  ${({
27
36
  isSticky,
28
- cellBoxShadowColor,
29
37
  align,
30
38
  cellPaddingTop,
31
39
  cellPaddingRight,
32
40
  cellPaddingBottom,
33
41
  cellPaddingLeft,
34
- cellMinWidth
42
+ cellMinWidth,
43
+ cellBackground,
44
+ cellStickyShadow,
45
+ stickyBackgroundColor,
46
+ type
35
47
  }) => css`
36
- ${isSticky ? stickyStyles : undefined};
37
- box-shadow: inset 0 -1px 0 ${cellBoxShadowColor};
38
48
  text-align: ${align};
39
49
  min-width: ${cellMinWidth}px;
40
50
  padding: ${cellPaddingTop}px ${cellPaddingRight}px ${cellPaddingBottom}px ${cellPaddingLeft}px;
51
+ background-color: ${cellBackground};
52
+ ${isSticky && stickyStyles({ type, cellStickyShadow, stickyBackgroundColor })};
41
53
  `}
42
54
  `
43
- const StyledHeading = styled.th`
44
- ${sharedStyles};
45
- ${({ cellHeadingBackground, cellHeadingBoxShadowColor }) => `
46
- background-color: ${cellHeadingBackground};
47
- box-shadow: inset 0 1px 0 ${cellHeadingBoxShadowColor}, inset 0 -1px 0 ${cellHeadingBoxShadowColor};`}
48
- `
49
-
50
- const StyledSubHeading = styled.th`
51
- ${sharedStyles};
52
- background-color: ${({ cellSubheadingBackground }) => cellSubheadingBackground};
53
- `
54
-
55
- const StyledCell = styled.td`
56
- ${sharedStyles};
57
- background-color: ${({ cellBackground }) => cellBackground};
58
- `
59
-
60
- const StyledRowHeading = styled.th`
55
+ const createStyledCell = (htmlElement) => styled[htmlElement]`
61
56
  ${sharedStyles};
62
- background-color: ${({ cellRowHeadingBackground }) => cellRowHeadingBackground};
57
+ box-shadow: ${({ cellBoxShadowColor, type }) => {
58
+ return type === HEADER_TYPE.HEADING
59
+ ? `inset 0 1px 0 ${cellBoxShadowColor}, inset 0 -1px 0 ${cellBoxShadowColor}`
60
+ : `inset 0 1px 0 ${cellBoxShadowColor}`
61
+ }};
63
62
  `
63
+ const StyledHeaderCell = createStyledCell('th')
64
+ const StyledDataCell = createStyledCell('td')
64
65
 
65
- const Cell = ({ children, type = 'default', isFirstInRow, align = 'left', tokens: cellTokens }) => {
66
- const { text, isScrollable: isTableScrollable, variant, tokens: tableTokens } = useTableContext()
66
+ const Cell = ({ children, isFirstInRow, align = 'left', tokens: cellTokens, type }) => {
67
+ const { text, isScrollable: isTableScrollable, tokens: tableTokens, spacing } = useTableContext()
67
68
  const themeTokens = { ...tableTokens, ...cellTokens }
68
69
 
69
70
  const {
70
71
  cellMinWidth,
71
- cellHeadingBackground,
72
- cellHeadingBoxShadowColor,
73
72
  cellBoxShadowColor,
74
- cellSubheadingBackground,
75
73
  cellBackground,
76
- cellRowHeadingBackground,
77
74
  cellStickyShadow,
78
75
  cellPaddingTop,
79
76
  cellPaddingRight,
@@ -81,84 +78,67 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left', tokens
81
78
  cellPaddingBottom,
82
79
  fontName,
83
80
  fontWeight,
84
- fontSize
85
- } = useThemeTokens('Table', themeTokens, variant)
81
+ fontSize,
82
+ lineHeight,
83
+ stickyBackgroundColor
84
+ } = useThemeTokens('Table', themeTokens, { spacing, type, text })
86
85
 
87
86
  const sharedProps = {
88
87
  align,
89
88
  isSticky: isTableScrollable && isFirstInRow,
89
+ cellBackground,
90
90
  cellMinWidth,
91
- cellStickyShadow,
91
+ cellStickyShadow: applyShadowToken(cellStickyShadow).boxShadow,
92
92
  cellPaddingTop,
93
93
  cellPaddingRight,
94
94
  cellPaddingLeft,
95
95
  cellPaddingBottom,
96
+ stickyBackgroundColor,
96
97
  cellBoxShadowColor
97
98
  }
98
-
99
99
  const typographyTokens = {
100
100
  fontName,
101
101
  fontWeight,
102
- fontSize
102
+ fontSize,
103
+ lineHeight
103
104
  }
104
105
 
105
106
  switch (type) {
106
- case 'heading':
107
+ case HEADER_TYPE.HEADING:
107
108
  return (
108
- <StyledHeading
109
- scope="col"
110
- cellHeadingBackground={cellHeadingBackground}
111
- cellHeadingBoxShadowColor={cellHeadingBoxShadowColor}
112
- {...sharedProps}
113
- >
114
- <Typography tokens={typographyTokens} variant={{ size: 'h4' }}>
115
- {children}
116
- </Typography>
117
- </StyledHeading>
109
+ <StyledHeaderCell scope="col" {...sharedProps} type={type}>
110
+ <Typography tokens={typographyTokens}>{children}</Typography>
111
+ </StyledHeaderCell>
118
112
  )
119
- case 'subHeading':
113
+
114
+ case HEADER_TYPE.SUBHEADING:
120
115
  return (
121
- <StyledSubHeading
122
- scope="col"
123
- cellSubheadingBackground={cellSubheadingBackground}
124
- {...sharedProps}
125
- >
126
- <Typography tokens={typographyTokens} variant={{ size: 'h5' }}>
127
- {children}
128
- </Typography>
129
- </StyledSubHeading>
116
+ <StyledHeaderCell scope="col" {...sharedProps} type={type}>
117
+ <Typography tokens={typographyTokens}>{children}</Typography>
118
+ </StyledHeaderCell>
130
119
  )
131
- case 'rowHeading':
120
+
121
+ case HEADER_TYPE.ROWHEADING:
132
122
  return (
133
- <StyledRowHeading
134
- scope="row"
135
- cellRowHeadingBackground={cellRowHeadingBackground}
136
- {...sharedProps}
137
- >
138
- <Typography tokens={typographyTokens} variant={{ size: text === 'small' ? 'h5' : 'h4' }}>
139
- {children}
140
- </Typography>
141
- </StyledRowHeading>
123
+ <StyledHeaderCell scope="row" {...sharedProps} type={type}>
124
+ <Typography tokens={typographyTokens}>{children}</Typography>
125
+ </StyledHeaderCell>
142
126
  )
143
127
 
144
128
  default:
145
129
  return (
146
- <StyledCell cellBackground={cellBackground} {...sharedProps}>
147
- <Typography tokens={{ fontSize }} variant={{ size: text }}>
148
- {children}
149
- </Typography>
150
- </StyledCell>
130
+ <StyledDataCell {...sharedProps}>
131
+ <Typography tokens={typographyTokens}>{children}</Typography>
132
+ </StyledDataCell>
151
133
  )
152
134
  }
153
135
  }
154
136
 
155
137
  Cell.propTypes = {
138
+ type: PropTypes.oneOf(['default', 'heading', 'subHeading', 'rowHeading']),
156
139
  tokens: PropTypes.object,
157
140
  children: PropTypes.node,
158
- /**
159
- * Defines the visual styles of a cell, and whether it should be a `td` or `th` element
160
- */
161
- type: PropTypes.oneOf(['default', 'heading', 'subHeading', 'rowHeading']),
141
+
162
142
  /**
163
143
  * @ignore
164
144
  * Used internally for making the first column sticky
@@ -5,7 +5,12 @@ import Row from './Row'
5
5
  const Header = ({ children }) => {
6
6
  return (
7
7
  <thead>
8
- <Row>{React.Children.map(children, (child) => cloneElement(child, { type: 'heading' }))}</Row>
8
+ <Row>
9
+ {React.Children.map(children, (child) =>
10
+ // TO DO: pass type as a variant instead of prop
11
+ cloneElement(child, { type: 'heading' })
12
+ )}
13
+ </Row>
9
14
  </thead>
10
15
  )
11
16
  }
@@ -5,7 +5,10 @@ import Row from './Row'
5
5
  const Header = ({ children }) => {
6
6
  return (
7
7
  <Row>
8
- {React.Children.map(children, (child) => cloneElement(child, { type: 'subHeading' }))}
8
+ {React.Children.map(children, (child) =>
9
+ // TO DO: pass type as a variant instead of prop
10
+ cloneElement(child, { type: 'subHeading' })
11
+ )}
9
12
  </Row>
10
13
  )
11
14
  }
@@ -36,7 +36,15 @@ export const useTableContext = () => useContext(TableContext)
36
36
  * - Use `Table.Row` and `Table.Cell` to build up the tabular data
37
37
  * - Use `Cell`'s `type` prop to visually mark it as a row heading (`type="rowHeading"`)
38
38
  */
39
- const Table = ({ children, fullWidth = true, text = 'medium', tokens, variant, ...rest }) => {
39
+ const Table = ({
40
+ children,
41
+ spacing = 'default',
42
+ fullWidth = true,
43
+ text = 'medium',
44
+ tokens,
45
+ variant,
46
+ ...rest
47
+ }) => {
40
48
  const { tablePaddingBottom } = useThemeTokens('Table', tokens, variant)
41
49
  const containerRef = useRef()
42
50
  const tableRef = useRef()
@@ -75,7 +83,7 @@ const Table = ({ children, fullWidth = true, text = 'medium', tokens, variant, .
75
83
  tablePaddingBottom={`${tablePaddingBottom}px`}
76
84
  {...selectProps(rest)}
77
85
  >
78
- <TableContext.Provider value={{ text, isScrollable, tokens, variant }}>
86
+ <TableContext.Provider value={{ text, isScrollable, tokens, spacing }}>
79
87
  <StyledTable tableWidth={tableWidth} cellSpacing={0} ref={tableRef}>
80
88
  {children}
81
89
  </StyledTable>
@@ -1,8 +1,8 @@
1
- import React, { forwardRef } from 'react'
1
+ import React, { forwardRef, useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
4
  ExpandCollapse as ExpandCollapseBase,
5
- Icon,
5
+ IconButton,
6
6
  useThemeTokensCallback
7
7
  } from '@telus-uds/components-base'
8
8
  import styled from 'styled-components'
@@ -17,18 +17,15 @@ const ExpandCollapseControl = styled.div({
17
17
 
18
18
  const ExpandCollapseIconContainer = styled.div(({ tokens }) => ({
19
19
  alignItems: tokens.expandIconContainerAlignItems,
20
- border: `${tokens.expandIconContainerBorder}px solid ${tokens.expandIconContainerBorderColor}`,
21
- borderRadius: '50%',
22
- display: 'flex',
23
- height: tokens.expandIconContainerHeight,
24
20
  justifyContent: tokens.expandIconContainerJustifyContent,
25
- margin: `${tokens.expandIconContainerMarginX}px ${tokens.expandIconContainerMarginY}px`,
21
+ marginLeft: `${tokens.expandIconContainerMarginY}px`,
22
+ marginRight: `${tokens.expandIconContainerMarginY}px`,
26
23
  width: tokens.expandIconContainerWidth
27
24
  }))
28
25
 
29
26
  const ExpandCollapseTitle = styled.h4(({ tokens }) => ({
30
27
  color: tokens.expandTitleColor,
31
- fontFamily: `${tokens.listFontName}${tokens.listFontWeight}normal`,
28
+ fontFamily: `${tokens.expandTitleFontName}${tokens.expandTitleFontWeight}normal`,
32
29
  fontSize: tokens.expandTitleFontSize,
33
30
  lineHeight: tokens.expandTitleLineHeight,
34
31
  margin: `${tokens.expandTitleMarginX}px ${tokens.expandTitleMarginY}px`
@@ -42,8 +39,20 @@ const ExpandCollapse = forwardRef(
42
39
  expandContentPaddingBottom,
43
40
  expandContentPaddingLeft,
44
41
  expandContentPaddingRight,
45
- expandContentPaddingTop
42
+ expandContentPaddingTop,
43
+ contentBorderColor,
44
+ contentMarginBottom,
45
+ expandTitlePaddingLeft,
46
+ expandTitleBorder,
47
+ expandTitleBorderColor,
48
+ expandTitleUnderline
46
49
  } = getTokens()
50
+ const [expand, setExpand] = useState(false)
51
+
52
+ const handleExpandToggle = (expandProps, event, expanded) => {
53
+ expandProps.onToggle('ExpandCollapsePanel', event)
54
+ setExpand(!expanded)
55
+ }
47
56
 
48
57
  return (
49
58
  <ExpandCollapseBase
@@ -55,7 +64,14 @@ const ExpandCollapse = forwardRef(
55
64
  <ExpandCollapseBase.Panel
56
65
  {...expandProps}
57
66
  panelId="ExpandCollapsePanel"
58
- controlTokens={{ icon: null }}
67
+ controlTokens={{
68
+ icon: null,
69
+ backgroundColor: 'transparent',
70
+ paddingLeft: expandTitlePaddingLeft,
71
+ borderColor: expandTitleBorderColor,
72
+ borderWidth: expandTitleBorder,
73
+ textLine: expandTitleUnderline
74
+ }}
59
75
  // TODO refactor
60
76
  // eslint-disable-next-line react/no-unstable-nested-components
61
77
  control={(pressableState) => {
@@ -64,11 +80,15 @@ const ExpandCollapse = forwardRef(
64
80
 
65
81
  return (
66
82
  <ExpandCollapseControl
67
- onClick={(event) => expandProps.onToggle('ExpandCollapsePanel', event)}
83
+ onClick={(event) => handleExpandToggle(expandProps, event, expanded)}
68
84
  ref={ref}
69
85
  >
70
86
  <ExpandCollapseIconContainer tokens={getTokens()}>
71
- <Icon icon={icon} variant={{ size: 'small' }} />
87
+ <IconButton
88
+ icon={icon}
89
+ variant={{ size: 'small' }}
90
+ onClick={(event) => handleExpandToggle(expandProps, event, expanded)}
91
+ />
72
92
  </ExpandCollapseIconContainer>
73
93
  <ExpandCollapseTitle tokens={getTokens()}>
74
94
  {expanded ? expandTitle : collapseTitle}
@@ -80,10 +100,12 @@ const ExpandCollapse = forwardRef(
80
100
  contentPaddingBottom: expandContentPaddingBottom,
81
101
  contentPaddingLeft: expandContentPaddingLeft,
82
102
  contentPaddingRight: expandContentPaddingRight,
83
- contentPaddingTop: expandContentPaddingTop
103
+ contentPaddingTop: expandContentPaddingTop,
104
+ borderColor: contentBorderColor,
105
+ marginBottom: contentMarginBottom
84
106
  }}
85
107
  >
86
- {children}
108
+ {expand ? children : null}
87
109
  </ExpandCollapseBase.Panel>
88
110
  )}
89
111
  </ExpandCollapseBase>