@indico-data/design-system 1.0.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.
Files changed (161) hide show
  1. package/.babelrc +27 -0
  2. package/.eslintignore +6 -0
  3. package/.eslintrc.js +63 -0
  4. package/.husky/pre-commit +4 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +6 -0
  7. package/.stackblitzrc +4 -0
  8. package/.storybook/indico-data-logo.svg +1 -0
  9. package/.storybook/main.ts +36 -0
  10. package/.storybook/preview-head.html +19 -0
  11. package/.storybook/preview.ts +24 -0
  12. package/.storybook/themes.js +24 -0
  13. package/.yarn/releases/yarn-classic.cjs +179386 -0
  14. package/.yarnrc.yml +1 -0
  15. package/README.md +30 -0
  16. package/package.json +79 -0
  17. package/src/components/Accordion/Accordion.stories.tsx +47 -0
  18. package/src/components/Accordion/Accordion.styles.ts +35 -0
  19. package/src/components/Accordion/Accordion.tsx +30 -0
  20. package/src/components/Accordion/index.ts +1 -0
  21. package/src/components/Icon/Icon.stories.tsx +60 -0
  22. package/src/components/Icon/Icon.tsx +75 -0
  23. package/src/components/Icon/faIcons.tsx +168 -0
  24. package/src/components/Icon/index.ts +2 -0
  25. package/src/components/Icon/indicons.tsx +699 -0
  26. package/src/components/Icon/storyHelpers.tsx +87 -0
  27. package/src/components/ListTable/Header/Header.styles.ts +62 -0
  28. package/src/components/ListTable/Header/Header.tsx +67 -0
  29. package/src/components/ListTable/Header/index.ts +1 -0
  30. package/src/components/ListTable/ListTable.stories.tsx +301 -0
  31. package/src/components/ListTable/ListTable.styles.ts +76 -0
  32. package/src/components/ListTable/ListTable.tsx +135 -0
  33. package/src/components/ListTable/index.ts +1 -0
  34. package/src/components/ListTable/mock-data/index.ts +1 -0
  35. package/src/components/ListTable/mock-data/mock-data.ts +291 -0
  36. package/src/components/Pagination/Pagination.stories.tsx +45 -0
  37. package/src/components/Pagination/Pagination.styles.ts +51 -0
  38. package/src/components/Pagination/Pagination.tsx +118 -0
  39. package/src/components/Pagination/index.ts +1 -0
  40. package/src/components/basic-section/Section/Section.stories.tsx +14 -0
  41. package/src/components/basic-section/Section/Section.styles.ts +8 -0
  42. package/src/components/basic-section/Section/Section.tsx +30 -0
  43. package/src/components/basic-section/Section/index.ts +1 -0
  44. package/src/components/basic-section/SectionBlock/SectionBlock.styles.ts +15 -0
  45. package/src/components/basic-section/SectionBlock/SectionBlock.tsx +37 -0
  46. package/src/components/basic-section/SectionBlock/index.ts +1 -0
  47. package/src/components/basic-section/SectionBody/SectionBody.stories.tsx +16 -0
  48. package/src/components/basic-section/SectionBody/SectionBody.styles.ts +18 -0
  49. package/src/components/basic-section/SectionBody/SectionBody.tsx +30 -0
  50. package/src/components/basic-section/SectionBody/index.ts +1 -0
  51. package/src/components/basic-section/SectionHeader/SectionHeader.stories.tsx +17 -0
  52. package/src/components/basic-section/SectionHeader/SectionHeader.styles.ts +5 -0
  53. package/src/components/basic-section/SectionHeader/SectionHeader.tsx +35 -0
  54. package/src/components/basic-section/SectionHeader/index.ts +1 -0
  55. package/src/components/basic-section/SectionTable/SectionTable.styles.ts +237 -0
  56. package/src/components/basic-section/SectionTable/SectionTable.tsx +229 -0
  57. package/src/components/basic-section/SectionTable/index.ts +1 -0
  58. package/src/components/basic-section/index.ts +5 -0
  59. package/src/components/buttons/Button/Button.stories.tsx +80 -0
  60. package/src/components/buttons/Button/Button.styles.ts +99 -0
  61. package/src/components/buttons/Button/Button.tsx +74 -0
  62. package/src/components/buttons/Button/index.ts +1 -0
  63. package/src/components/buttons/IconButton/IconButton.stories.tsx +96 -0
  64. package/src/components/buttons/IconButton/IconButton.styles.ts +78 -0
  65. package/src/components/buttons/IconButton/IconButton.tsx +109 -0
  66. package/src/components/buttons/IconButton/index.ts +1 -0
  67. package/src/components/buttons/commonStyles.ts +108 -0
  68. package/src/components/buttons/index.ts +2 -0
  69. package/src/components/buttons/types.ts +2 -0
  70. package/src/components/dropdowns/BorderSelect/BorderSelect.stories.tsx +22 -0
  71. package/src/components/dropdowns/BorderSelect/BorderSelect.styles.ts +73 -0
  72. package/src/components/dropdowns/BorderSelect/BorderSelect.tsx +85 -0
  73. package/src/components/dropdowns/BorderSelect/index.ts +1 -0
  74. package/src/components/dropdowns/MultiCombobox/MultiCombobox.stories.tsx +146 -0
  75. package/src/components/dropdowns/MultiCombobox/MultiCombobox.styles.ts +89 -0
  76. package/src/components/dropdowns/MultiCombobox/MultiCombobox.tsx +123 -0
  77. package/src/components/dropdowns/MultiCombobox/index.ts +1 -0
  78. package/src/components/dropdowns/Select/Select.stories.tsx +54 -0
  79. package/src/components/dropdowns/Select/Select.styles.ts +73 -0
  80. package/src/components/dropdowns/Select/Select.tsx +69 -0
  81. package/src/components/dropdowns/Select/index.ts +1 -0
  82. package/src/components/dropdowns/SingleCombobox/SingleCombobox.stories.tsx +61 -0
  83. package/src/components/dropdowns/SingleCombobox/SingleCombobox.styles.ts +56 -0
  84. package/src/components/dropdowns/SingleCombobox/SingleCombobox.tsx +103 -0
  85. package/src/components/dropdowns/SingleCombobox/index.ts +1 -0
  86. package/src/components/dropdowns/commonStyles.ts +65 -0
  87. package/src/components/dropdowns/index.ts +4 -0
  88. package/src/components/dropdowns/types.ts +45 -0
  89. package/src/components/dropdowns/useCombobox.ts +32 -0
  90. package/src/components/dropdowns/utils.tsx +25 -0
  91. package/src/components/index.ts +9 -0
  92. package/src/components/inputs/EditableInput/EditableInput.stories.tsx +26 -0
  93. package/src/components/inputs/EditableInput/EditableInput.styles.ts +21 -0
  94. package/src/components/inputs/EditableInput/EditableInput.tsx +103 -0
  95. package/src/components/inputs/EditableInput/index.ts +1 -0
  96. package/src/components/inputs/NumberInput/NumberInput.stories.tsx +72 -0
  97. package/src/components/inputs/NumberInput/NumberInput.styles.ts +66 -0
  98. package/src/components/inputs/NumberInput/NumberInput.tsx +153 -0
  99. package/src/components/inputs/NumberInput/index.ts +1 -0
  100. package/src/components/inputs/SearchInput/SearchInput.stories.tsx +17 -0
  101. package/src/components/inputs/SearchInput/SearchInput.styles.ts +25 -0
  102. package/src/components/inputs/SearchInput/SearchInput.tsx +47 -0
  103. package/src/components/inputs/SearchInput/index.ts +1 -0
  104. package/src/components/inputs/TextInput/TextInput.stories.tsx +104 -0
  105. package/src/components/inputs/TextInput/TextInput.styles.ts +74 -0
  106. package/src/components/inputs/TextInput/TextInput.tsx +116 -0
  107. package/src/components/inputs/TextInput/index.ts +1 -0
  108. package/src/components/inputs/index.ts +4 -0
  109. package/src/components/inputs/inputsCommon.styles.ts +61 -0
  110. package/src/components/loading-indicators/BarSpinner/BarSpinner.stories.tsx +14 -0
  111. package/src/components/loading-indicators/BarSpinner/BarSpinner.styles.ts +53 -0
  112. package/src/components/loading-indicators/BarSpinner/BarSpinner.tsx +21 -0
  113. package/src/components/loading-indicators/BarSpinner/index.ts +1 -0
  114. package/src/components/loading-indicators/CirclePulse/CirclePulse.stories.tsx +22 -0
  115. package/src/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +81 -0
  116. package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +61 -0
  117. package/src/components/loading-indicators/CirclePulse/index.ts +1 -0
  118. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.stories.tsx +16 -0
  119. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.tsx +37 -0
  120. package/src/components/loading-indicators/CircleSpinner/index.ts +1 -0
  121. package/src/components/loading-indicators/LoadingList/LoadingList.stories.tsx +14 -0
  122. package/src/components/loading-indicators/LoadingList/LoadingList.styles.ts +42 -0
  123. package/src/components/loading-indicators/LoadingList/LoadingList.tsx +9 -0
  124. package/src/components/loading-indicators/LoadingList/index.ts +1 -0
  125. package/src/components/loading-indicators/PercentageRing/PercentageRing.stories.tsx +18 -0
  126. package/src/components/loading-indicators/PercentageRing/PercentageRing.styles.ts +27 -0
  127. package/src/components/loading-indicators/PercentageRing/PercentageRing.tsx +76 -0
  128. package/src/components/loading-indicators/PercentageRing/index.ts +1 -0
  129. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.stories.tsx +16 -0
  130. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.tsx +18 -0
  131. package/src/components/loading-indicators/RandomLoadingMessage/index.ts +1 -0
  132. package/src/components/loading-indicators/RandomLoadingMessage/random-messages.js +67 -0
  133. package/src/components/loading-indicators/index.ts +6 -0
  134. package/src/components/user-feedback/Shrug/Shrug.stories.tsx +38 -0
  135. package/src/components/user-feedback/Shrug/Shrug.styles.ts +23 -0
  136. package/src/components/user-feedback/Shrug/Shrug.tsx +44 -0
  137. package/src/components/user-feedback/Shrug/index.ts +1 -0
  138. package/src/components/user-feedback/index.ts +1 -0
  139. package/src/index.tsx +18 -0
  140. package/src/styles/globals/buttons.ts +154 -0
  141. package/src/styles/globals/forms.ts +103 -0
  142. package/src/styles/globals/index.tsx +25 -0
  143. package/src/styles/globals/layout.ts +25 -0
  144. package/src/styles/globals/lists.ts +23 -0
  145. package/src/styles/globals/margin-padding.ts +33 -0
  146. package/src/styles/globals/media.ts +13 -0
  147. package/src/styles/globals/tables.ts +34 -0
  148. package/src/styles/globals/typography.ts +95 -0
  149. package/src/styles/globals/utility-classes.ts +76 -0
  150. package/src/tokens/animation.ts +6 -0
  151. package/src/tokens/breakpoints.ts +11 -0
  152. package/src/tokens/colors.ts +279 -0
  153. package/src/tokens/index.ts +20 -0
  154. package/src/tokens/margin.ts +5 -0
  155. package/src/tokens/numbers.js +41 -0
  156. package/src/tokens/padding.ts +5 -0
  157. package/src/tokens/spacings.ts +5 -0
  158. package/src/tokens/typography.ts +37 -0
  159. package/src/types.ts +6 -0
  160. package/tsconfig.json +13 -0
  161. package/webpack.config.js +35 -0
@@ -0,0 +1,30 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+
5
+ import classNames from 'classnames';
6
+
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledSection } from './Section.styles';
10
+
11
+ type Props = PermafrostComponent & {
12
+ style?: object;
13
+ children: React.ReactNode;
14
+ };
15
+
16
+ export const Section = (props: Props) => {
17
+ const { className, style = {}, children, id, ...restOfProps } = props;
18
+
19
+ return (
20
+ <StyledSection
21
+ className={classNames('Section', className)}
22
+ data-cy={props['data-cy']}
23
+ id={id}
24
+ style={style}
25
+ {...restOfProps}
26
+ >
27
+ {children}
28
+ </StyledSection>
29
+ );
30
+ };
@@ -0,0 +1 @@
1
+ export { Section } from './Section';
@@ -0,0 +1,15 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS } from '@/tokens';
4
+
5
+ export const StyledSectionBlock = styled.div`
6
+ h3 {
7
+ margin: 24px 0 31px;
8
+ }
9
+
10
+ hr {
11
+ width: 100%;
12
+ border-bottom: 1px solid ${COLORS.ebony};
13
+ margin: 27px 0 1px;
14
+ }
15
+ `;
@@ -0,0 +1,37 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+
5
+ import classNames from 'classnames';
6
+
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledSectionBlock } from './SectionBlock.styles';
10
+
11
+ type Props = PermafrostComponent & {
12
+ title?: string;
13
+ style?: object;
14
+ children: React.ReactNode;
15
+ };
16
+
17
+ export const SectionBlock = (props: Props) => {
18
+ const { title, className, children, id, style = {}, ...restOfProps } = props;
19
+
20
+ return (
21
+ <StyledSectionBlock
22
+ className={classNames('SectionBlock', className)}
23
+ data-cy={props['data-cy']}
24
+ id={id}
25
+ style={style}
26
+ {...restOfProps}
27
+ >
28
+ {title ? (
29
+ <header>
30
+ <h3>{title}</h3>
31
+ </header>
32
+ ) : null}
33
+ {children}
34
+ <hr className="section-bottom-border" />
35
+ </StyledSectionBlock>
36
+ );
37
+ };
@@ -0,0 +1 @@
1
+ export { SectionBlock } from './SectionBlock';
@@ -0,0 +1,16 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { SectionBody } from './SectionBody';
4
+
5
+ const meta = {
6
+ component: SectionBody,
7
+ title: 'Basic Section/SectionBody',
8
+ argTypes: {},
9
+ } satisfies Meta<typeof SectionBody>;
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof SectionBody>;
13
+
14
+ export const Normal: Story = {
15
+ args: {},
16
+ };
@@ -0,0 +1,18 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS } from '@/tokens';
4
+
5
+ const sectionSidePadding = '19px';
6
+
7
+ export const StyledSectionBody = styled.div`
8
+ background: ${COLORS.clay};
9
+ border-radius: 4px;
10
+ border: 1px solid #333d4c;
11
+ padding: 0 ${sectionSidePadding};
12
+
13
+ .SectionBody:last-of-type {
14
+ .section-bottom-border {
15
+ border-bottom: none;
16
+ }
17
+ }
18
+ `;
@@ -0,0 +1,30 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+
5
+ import classNames from 'classnames';
6
+
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledSectionBody } from './SectionBody.styles';
10
+
11
+ export type SectionBodyProps = PermafrostComponent & {
12
+ style?: object;
13
+ children: React.ReactNode;
14
+ };
15
+
16
+ export const SectionBody = (props: SectionBodyProps) => {
17
+ const { className, style = {}, children, id, ...restOfProps } = props;
18
+
19
+ return (
20
+ <StyledSectionBody
21
+ className={classNames('SectionBody', className)}
22
+ data-cy={props['data-cy']}
23
+ id={id}
24
+ style={style}
25
+ {...restOfProps}
26
+ >
27
+ {children}
28
+ </StyledSectionBody>
29
+ );
30
+ };
@@ -0,0 +1 @@
1
+ export { SectionBody } from './SectionBody';
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+
4
+ import { SectionHeader } from './SectionHeader';
5
+
6
+ const meta = {
7
+ component: SectionHeader,
8
+ title: 'Basic Section/SectionHeader',
9
+ argTypes: {},
10
+ } satisfies Meta<typeof SectionHeader>;
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof SectionHeader>;
14
+
15
+ export const Normal: Story = {
16
+ args: { children: <div>Section Header</div> },
17
+ };
@@ -0,0 +1,5 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const StyledSectionHeader = styled.header`
4
+ padding: 23px 0 18px;
5
+ `;
@@ -0,0 +1,35 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+
5
+ import classNames from 'classnames';
6
+
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledSectionHeader } from './SectionHeader.styles';
10
+
11
+ type Props = PermafrostComponent & {
12
+ style?: object;
13
+ children?: React.ReactNode;
14
+ };
15
+
16
+ export const SectionHeader = (props: Props) => {
17
+ const { className, style, children, id, ...restOfProps } = props;
18
+
19
+ return (
20
+ <StyledSectionHeader
21
+ className={classNames('SectionHeader', className)}
22
+ data-cy={props['data-cy']}
23
+ id={id}
24
+ style={style}
25
+ {...restOfProps}
26
+ >
27
+ {children}
28
+ </StyledSectionHeader>
29
+ );
30
+ };
31
+
32
+ SectionHeader.defaultProps = {
33
+ className: '',
34
+ style: {},
35
+ };
@@ -0,0 +1 @@
1
+ export { SectionHeader } from './SectionHeader';
@@ -0,0 +1,237 @@
1
+ import styled, { keyframes } from 'styled-components';
2
+
3
+ import { colorUtils } from '@indico-data/utils';
4
+
5
+ import { MEDIA_QUERIES, COLORS } from '@/tokens';
6
+
7
+ const cardTableLoading = keyframes`
8
+ 25% {
9
+ left: -50px;
10
+ }
11
+ 50% {
12
+ left: calc(100% + 50px);
13
+ }
14
+ 75% {
15
+ left: calc(100% + 50px);
16
+ }
17
+ 100% {
18
+ left: calc(100% + 50px);
19
+ }
20
+ `;
21
+
22
+ export const StyledSectionTable = styled.div`
23
+ .mobile-sort {
24
+ @media ${MEDIA_QUERIES.mediumScreen} {
25
+ display: none;
26
+ }
27
+
28
+ select {
29
+ max-width: none;
30
+ }
31
+ }
32
+
33
+ .outer-hover {
34
+ @media ${MEDIA_QUERIES.mediumScreen} {
35
+ &:hover {
36
+ cursor: pointer;
37
+ }
38
+ }
39
+ }
40
+
41
+ &.loading {
42
+ margin-top: 50px;
43
+
44
+ table {
45
+ overflow: hidden;
46
+ }
47
+ }
48
+
49
+ .SectionTable--tbody-loading {
50
+ tr {
51
+ margin: 10px 0;
52
+ border-bottom: 10px solid transparent;
53
+ }
54
+
55
+ td {
56
+ position: relative;
57
+ border-bottom: none;
58
+ height: 73px;
59
+ background: ${COLORS.mirage};
60
+
61
+ &:before {
62
+ position: absolute;
63
+ display: block;
64
+ top: 0;
65
+ left: -50px;
66
+ content: '';
67
+ height: 100%;
68
+ width: 50px;
69
+ background: linear-gradient(90deg, ${COLORS.mirage}, #232e3d, ${COLORS.mirage});
70
+ animation: ${cardTableLoading} 2s infinite;
71
+ animation-timing-function: linear;
72
+ }
73
+ }
74
+ }
75
+
76
+ tbody > tr {
77
+ @media ${MEDIA_QUERIES.mediumScreen} {
78
+ &.hover:hover {
79
+ background: ${COLORS.oxfordBlue};
80
+ cursor: pointer;
81
+ }
82
+ }
83
+ }
84
+
85
+ .action-column {
86
+ display: none;
87
+ text-align: center;
88
+ width: 20px;
89
+ padding: 20px 5px;
90
+
91
+ @media ${MEDIA_QUERIES.mediumScreen} {
92
+ display: table-cell;
93
+ }
94
+ }
95
+
96
+ table,
97
+ thead,
98
+ tbody,
99
+ th,
100
+ td,
101
+ tr {
102
+ display: block;
103
+
104
+ @media ${MEDIA_QUERIES.mediumScreen} {
105
+ display: table;
106
+ }
107
+
108
+ .no-link {
109
+ cursor: default;
110
+ }
111
+ }
112
+
113
+ thead {
114
+ display: block;
115
+
116
+ @media ${MEDIA_QUERIES.mediumScreen} {
117
+ display: table-header-group;
118
+ }
119
+ }
120
+
121
+ th {
122
+ padding-bottom: 10px;
123
+ border-bottom: 1px solid #535d6d;
124
+ }
125
+
126
+ th:hover {
127
+ cursor: pointer;
128
+ }
129
+
130
+ th.not-sortable:hover {
131
+ cursor: default;
132
+ }
133
+
134
+ tbody {
135
+ display: block;
136
+
137
+ @media ${MEDIA_QUERIES.mediumScreen} {
138
+ display: table-row-group;
139
+ }
140
+ }
141
+
142
+ th,
143
+ td {
144
+ display: block;
145
+
146
+ @media ${MEDIA_QUERIES.mediumScreen} {
147
+ display: table-cell;
148
+ }
149
+ }
150
+
151
+ tr {
152
+ display: block;
153
+ padding-bottom: 10px;
154
+
155
+ @media ${MEDIA_QUERIES.mediumScreen} {
156
+ display: table-row;
157
+
158
+ border-bottom: 0.5px solid ${colorUtils.hexToRgb(COLORS.defaultFontColor, 0.1)};
159
+ }
160
+ }
161
+
162
+ /* Hide table headers (but not display: none;, for accessibility) */
163
+ thead tr {
164
+ position: absolute;
165
+ top: -9999px;
166
+ left: -9999px;
167
+
168
+ @media ${MEDIA_QUERIES.mediumScreen} {
169
+ position: static;
170
+ }
171
+ }
172
+
173
+ tr:nth-child(odd) {
174
+ background: ${COLORS.oxfordBlue};
175
+
176
+ @media ${MEDIA_QUERIES.mediumScreen} {
177
+ background: transparent;
178
+ }
179
+ }
180
+
181
+ td {
182
+ /* Behave like a "row" */
183
+ border: none;
184
+ position: relative;
185
+ padding-left: 50%;
186
+ padding-top: 10px;
187
+ padding-bottom: 5px;
188
+
189
+ @media ${MEDIA_QUERIES.mediumScreen} {
190
+ position: static;
191
+ // border-bottom: 0.5px solid ${colorUtils.hexToRgb(COLORS.defaultFontColor, 0.1)};
192
+ padding: 20px 15px;
193
+ }
194
+ }
195
+
196
+ td:before {
197
+ /* Now like a table header */
198
+ position: absolute;
199
+ /* Top/left values mimic padding */
200
+ left: 6px;
201
+ width: 45%;
202
+ padding-right: 10px;
203
+ white-space: nowrap;
204
+ content: attr(data-heading);
205
+
206
+ @media ${MEDIA_QUERIES.mediumScreen} {
207
+ display: none;
208
+ }
209
+ }
210
+
211
+ td.inner-table-cell {
212
+ padding-top: 0;
213
+ padding-bottom: 0;
214
+ padding-left: 5px;
215
+ border: none;
216
+
217
+ &:before {
218
+ display: none;
219
+ }
220
+ }
221
+
222
+ tr.row-option {
223
+ display: none;
224
+
225
+ &.open {
226
+ display: table-row;
227
+ }
228
+ }
229
+
230
+ .outer-hover tr {
231
+ border: none;
232
+ }
233
+
234
+ .outer-hover .hover {
235
+ border-bottom: 0.5px solid ${colorUtils.hexToRgb(COLORS.defaultFontColor, 0.1)};
236
+ }
237
+ `;
@@ -0,0 +1,229 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React, { useState } from 'react';
4
+ import classNames from 'classnames';
5
+
6
+ import { Icon, BorderSelect, IconName } from '@/components';
7
+
8
+ import { StyledSectionTable } from './SectionTable.styles';
9
+
10
+ const createTitle = (item) => {
11
+ return typeof item === 'string' || typeof item === 'number' ? item : null;
12
+ };
13
+
14
+ export const SectionTable = (props) => {
15
+ const [openRowOptions, changeOpenRowOptions] = useState([]);
16
+
17
+ const handleRowClick = (link) => {
18
+ if (!link) {
19
+ return null;
20
+ }
21
+ return (e) => {
22
+ e.stopPropagation();
23
+ props.history.push(link);
24
+ };
25
+ };
26
+
27
+ const handleRowOptionToggleClick = (id) => {
28
+ if (openRowOptions.indexOf(id) === -1) {
29
+ changeOpenRowOptions([].concat(openRowOptions, id));
30
+ } else {
31
+ changeOpenRowOptions(openRowOptions.filter((option) => option !== id));
32
+ }
33
+ if (props.openRowOptionHandler) {
34
+ props.openRowOptionHandler(id);
35
+ }
36
+ };
37
+
38
+ const headers = Object.keys(props.tableObjects[0].content);
39
+ return (
40
+ <StyledSectionTable
41
+ className={classNames('SectionTable', props.className, { loading: props.loading })}
42
+ data-cy={props['data-cy']}
43
+ id={props.id}
44
+ >
45
+ {props.sortColumnHandler && props.sortedColumn && (
46
+ <div className="mobile-sort">
47
+ <BorderSelect
48
+ onChange={(e) => props.sortColumnHandler(e.target.value)}
49
+ value={props.sortedColumn}
50
+ options={[].concat(
51
+ { name: 'Choose Sorting Option', value: '' },
52
+ headers.map((item) => {
53
+ return { name: item, value: item };
54
+ }),
55
+ )}
56
+ />
57
+ </div>
58
+ )}
59
+ <table {...props.tableProps}>
60
+ <thead>
61
+ <tr>
62
+ {props.tableObjects[0].rowAccordionContent ? <th className="action-column" /> : null}
63
+ {headers.map((header, i) => {
64
+ return (
65
+ <th
66
+ className={classNames({
67
+ 'not-sortable':
68
+ props.sortableHeaders && props.sortableHeaders.indexOf(header) === -1,
69
+ })}
70
+ onClick={() => {
71
+ if (props.sortColumnHandler) {
72
+ if (props.sortableHeaders) {
73
+ if (props.sortableHeaders.indexOf(header) !== -1) {
74
+ props.sortColumnHandler(header);
75
+ }
76
+ } else {
77
+ props.sortColumnHandler(header);
78
+ }
79
+ }
80
+ }}
81
+ key={i}
82
+ >
83
+ {props.headersContent ? props.headersContent[header] : header}{' '}
84
+ {props.sortedColumn === header && (
85
+ <Icon name={`fa-caret-${props.sortDirection}` as IconName} />
86
+ )}
87
+ </th>
88
+ );
89
+ })}
90
+ </tr>
91
+ </thead>
92
+ <tbody className={classNames({ 'SectionTable--tbody-loading': props.loading })}>
93
+ {props.loading
94
+ ? Array.from({ length: 5 }, (x, i) => (
95
+ <tr key={i}>
96
+ {props.tableObjects[0].rowAccordionContent ? (
97
+ <td colSpan={headers.length + 1} />
98
+ ) : (
99
+ <td colSpan={headers.length} />
100
+ )}
101
+ </tr>
102
+ ))
103
+ : props.tableObjects.map((obj, i) => {
104
+ let rowStyle = obj.rowStyleCondition;
105
+
106
+ if (rowStyle) {
107
+ rowStyle = { [rowStyle.className]: rowStyle.condition };
108
+ }
109
+
110
+ if (obj.rowAccordionContent) {
111
+ return (
112
+ <tr key={i} className={classNames(rowStyle)} {...props.rowProps}>
113
+ <td
114
+ colSpan={headers.length + 1}
115
+ style={{ padding: '0' }}
116
+ className="outer-hover"
117
+ >
118
+ <table>
119
+ <thead>
120
+ <tr>
121
+ <th
122
+ className="action-column"
123
+ style={{
124
+ padding: '0',
125
+ height: '1px',
126
+ border: 'none',
127
+ }}
128
+ />
129
+ {headers.map((e, i) => {
130
+ return (
131
+ <th
132
+ key={i}
133
+ style={{
134
+ padding: '0',
135
+ height: '1px',
136
+ border: 'none',
137
+ }}
138
+ />
139
+ );
140
+ })}
141
+ </tr>
142
+ </thead>
143
+ <tbody>
144
+ <tr onClick={() => handleRowOptionToggleClick(obj.id)}>
145
+ <td style={{ borderBottom: 'none' }} className="action-column">
146
+ <Icon
147
+ name="chevron-down"
148
+ style={{
149
+ transform:
150
+ openRowOptions.indexOf(obj.id) !== -1 ? 'rotate(180deg)' : '',
151
+ }}
152
+ />
153
+ </td>
154
+ {Object.keys(obj.content).map((key, i) => {
155
+ return (
156
+ <td
157
+ key={i}
158
+ style={{
159
+ borderBottom: 'none',
160
+ }}
161
+ data-heading={headers[i]}
162
+ title={createTitle(obj.content[key])}
163
+ {...props?.headingProps?.[headers?.[i]]}
164
+ >
165
+ {obj.content[key]}
166
+ </td>
167
+ );
168
+ })}
169
+ </tr>
170
+ <tr
171
+ className={classNames('row-option', {
172
+ open: openRowOptions.indexOf(obj.id) !== -1,
173
+ })}
174
+ >
175
+ <td className="inner-table-cell" colSpan={headers.length + 1}>
176
+ {obj.rowAccordionContent}
177
+ </td>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+ </td>
182
+ </tr>
183
+ );
184
+ } else if (obj.lineItemLink) {
185
+ return (
186
+ <tr
187
+ key={i}
188
+ onClick={handleRowClick(obj.lineItemLink)}
189
+ className={classNames('hover', rowStyle)}
190
+ {...props.rowProps}
191
+ >
192
+ {Object.keys(obj.content).map((key, i) => {
193
+ return (
194
+ <td
195
+ key={i}
196
+ data-heading={headers[i]}
197
+ title={createTitle(obj.content[key])}
198
+ {...props?.headingProps?.[headers?.[i]]}
199
+ >
200
+ {obj.content[key]}
201
+ </td>
202
+ );
203
+ })}
204
+ </tr>
205
+ );
206
+ } else {
207
+ return (
208
+ <tr key={i} className={classNames(rowStyle)} {...props.rowProps}>
209
+ {Object.keys(obj.content).map((key, i) => {
210
+ return (
211
+ <td
212
+ key={i}
213
+ data-heading={headers[i]}
214
+ title={createTitle(obj.content[key])}
215
+ {...props?.headingProps?.[headers?.[i]]}
216
+ >
217
+ {obj.content[key]}
218
+ </td>
219
+ );
220
+ })}
221
+ </tr>
222
+ );
223
+ }
224
+ })}
225
+ </tbody>
226
+ </table>
227
+ </StyledSectionTable>
228
+ );
229
+ };
@@ -0,0 +1 @@
1
+ export { SectionTable } from './SectionTable';
@@ -0,0 +1,5 @@
1
+ export { Section } from './Section';
2
+ export { SectionBlock } from './SectionBlock';
3
+ export { SectionBody } from './SectionBody';
4
+ export { SectionHeader } from './SectionHeader';
5
+ export { SectionTable } from './SectionTable';