@tcn/ui 0.7.0 → 0.8.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 (137) hide show
  1. package/dist/{Color-6BZIO3FS-CWWwv-fq.js → Color-6BZIO3FS-C9xkPWgz.js} +2 -2
  2. package/dist/{Color-6BZIO3FS-CWWwv-fq.js.map → Color-6BZIO3FS-C9xkPWgz.js.map} +1 -1
  3. package/dist/{WithTooltip-65CFNBJE-DvcUZizH.js → WithTooltip-65CFNBJE-DEnh547F.js} +2 -2
  4. package/dist/{WithTooltip-65CFNBJE-DvcUZizH.js.map → WithTooltip-65CFNBJE-DEnh547F.js.map} +1 -1
  5. package/dist/actions/__docs__/components/showcase.js +1 -1
  6. package/dist/actions/index.d.ts +1 -0
  7. package/dist/actions/index.d.ts.map +1 -1
  8. package/dist/actions/index.js +8 -6
  9. package/dist/actions/index.js.map +1 -1
  10. package/dist/body.css +1 -0
  11. package/dist/form/field_presenters/field_presenter.d.ts +2 -2
  12. package/dist/form/field_presenters/field_presenter.d.ts.map +1 -1
  13. package/dist/form/field_presenters/field_presenter.js.map +1 -1
  14. package/dist/formatter-EIJCOSYU-DWmgEY3b.js +6 -0
  15. package/dist/{formatter-EIJCOSYU-D6nmx63h.js.map → formatter-EIJCOSYU-DWmgEY3b.js.map} +1 -1
  16. package/dist/inputs/color_input/color_input.js +10 -9
  17. package/dist/inputs/color_input/color_input.js.map +1 -1
  18. package/dist/inputs/date_picker/date_picker_header.js +7 -6
  19. package/dist/inputs/date_picker/date_picker_header.js.map +1 -1
  20. package/dist/inputs/date_picker/date_picker_input.js +3 -2
  21. package/dist/inputs/date_picker/date_picker_input.js.map +1 -1
  22. package/dist/inputs/date_picker/date_picker_time_selector.js +3 -2
  23. package/dist/inputs/date_picker/date_picker_time_selector.js.map +1 -1
  24. package/dist/inputs/date_picker/date_picker_year_input.js +6 -5
  25. package/dist/inputs/date_picker/date_picker_year_input.js.map +1 -1
  26. package/dist/inputs/date_picker/date_picker_year_selector.js +3 -2
  27. package/dist/inputs/date_picker/date_picker_year_selector.js.map +1 -1
  28. package/dist/inputs/multiselect/multiselect_inline_values.js +8 -7
  29. package/dist/inputs/multiselect/multiselect_inline_values.js.map +1 -1
  30. package/dist/inputs/multiselect/multiselect_values.js +3 -2
  31. package/dist/inputs/multiselect/multiselect_values.js.map +1 -1
  32. package/dist/inputs/phone_number_input/phone_number_input.js +44 -43
  33. package/dist/inputs/phone_number_input/phone_number_input.js.map +1 -1
  34. package/dist/inputs/select/select.js +3 -2
  35. package/dist/inputs/select/select.js.map +1 -1
  36. package/dist/inputs/suggestions/suggestion_list.js +3 -2
  37. package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
  38. package/dist/layouts/body/body.d.ts +6 -0
  39. package/dist/layouts/body/body.d.ts.map +1 -0
  40. package/dist/layouts/body/body.js +21 -0
  41. package/dist/layouts/body/body.js.map +1 -0
  42. package/dist/layouts/index.d.ts +5 -0
  43. package/dist/layouts/index.d.ts.map +1 -1
  44. package/dist/layouts/index.js +38 -22
  45. package/dist/layouts/index.js.map +1 -1
  46. package/dist/layouts/rail/main/main.d.ts +6 -0
  47. package/dist/layouts/rail/main/main.d.ts.map +1 -0
  48. package/dist/layouts/rail/main/main.js +21 -0
  49. package/dist/layouts/rail/main/main.js.map +1 -0
  50. package/dist/layouts/rail/rail.d.ts +9 -0
  51. package/dist/layouts/rail/rail.d.ts.map +1 -0
  52. package/dist/layouts/rail/rail.js +55 -0
  53. package/dist/layouts/rail/rail.js.map +1 -0
  54. package/dist/layouts/rail/side/side.d.ts +6 -0
  55. package/dist/layouts/rail/side/side.d.ts.map +1 -0
  56. package/dist/layouts/rail/side/side.js +21 -0
  57. package/dist/layouts/rail/side/side.js.map +1 -0
  58. package/dist/layouts/rail/utility_strip/utility_strip.d.ts +9 -0
  59. package/dist/layouts/rail/utility_strip/utility_strip.d.ts.map +1 -0
  60. package/dist/layouts/rail/utility_strip/utility_strip.js +32 -0
  61. package/dist/layouts/rail/utility_strip/utility_strip.js.map +1 -0
  62. package/dist/layouts/scaffold/scaffold.js +31 -31
  63. package/dist/layouts/scaffold/scaffold.js.map +1 -1
  64. package/dist/layouts/table/table.d.ts +27 -0
  65. package/dist/layouts/table/table.d.ts.map +1 -0
  66. package/dist/layouts/table/table.js +70 -0
  67. package/dist/layouts/table/table.js.map +1 -0
  68. package/dist/main.css +1 -0
  69. package/dist/navigation/tabs/primitives/tabs_list.d.ts.map +1 -1
  70. package/dist/navigation/tabs/primitives/tabs_list.js +61 -21
  71. package/dist/navigation/tabs/primitives/tabs_list.js.map +1 -1
  72. package/dist/navigation/tabs/state/link/tab_link.d.ts.map +1 -1
  73. package/dist/navigation/tabs/state/link/tab_link.js +20 -17
  74. package/dist/navigation/tabs/state/link/tab_link.js.map +1 -1
  75. package/dist/navigation/tabs/state/tab.d.ts.map +1 -1
  76. package/dist/navigation/tabs/state/tab.js +8 -3
  77. package/dist/navigation/tabs/state/tab.js.map +1 -1
  78. package/dist/rail.css +1 -0
  79. package/dist/scaffold.css +1 -1
  80. package/dist/{showcase-DK557szS.js → showcase-y9D3_Y8T.js} +3413 -3396
  81. package/dist/showcase-y9D3_Y8T.js.map +1 -0
  82. package/dist/side.css +1 -0
  83. package/dist/stacks/box/box.d.ts +2 -2
  84. package/dist/stacks/box/box.d.ts.map +1 -1
  85. package/dist/stacks/box/box.js.map +1 -1
  86. package/dist/stacks/story_components/style_box.d.ts +1 -1
  87. package/dist/stacks/story_components/style_box.d.ts.map +1 -1
  88. package/dist/surfaces/alert/alert.js +3 -2
  89. package/dist/surfaces/alert/alert.js.map +1 -1
  90. package/dist/surfaces/pop_confirm/pop_confirm.js +13 -2
  91. package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
  92. package/dist/{syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js → syntaxhighlighter-ED5Y7EFY-CqInEOwQ.js} +2 -2
  93. package/dist/{syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js.map → syntaxhighlighter-ED5Y7EFY-CqInEOwQ.js.map} +1 -1
  94. package/dist/table.css +1 -0
  95. package/dist/table.module-BtSxOntS.js +5 -0
  96. package/dist/table.module-BtSxOntS.js.map +1 -0
  97. package/dist/themes/themes/ergo/ergo_theme.css +1 -1
  98. package/dist/themes/themes/ergo/ergo_theme.js +179 -44
  99. package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
  100. package/dist/utility_strip.css +1 -0
  101. package/package.json +2 -2
  102. package/src/actions/index.ts +1 -0
  103. package/src/form/field_presenters/field_presenter.ts +3 -3
  104. package/src/layouts/__stories__/composed.stories.tsx +113 -0
  105. package/src/layouts/__stories__/composed_stories.module.css +142 -0
  106. package/src/layouts/__stories__/utils.tsx +174 -0
  107. package/src/layouts/body/body.module.css +11 -0
  108. package/src/layouts/body/body.tsx +23 -0
  109. package/src/layouts/index.ts +10 -0
  110. package/src/layouts/rail/__stories__/rail.stories.tsx +64 -0
  111. package/src/layouts/rail/__stories__/rail_stories.module.css +25 -0
  112. package/src/layouts/rail/main/main.module.css +7 -0
  113. package/src/layouts/rail/main/main.tsx +26 -0
  114. package/src/layouts/rail/rail.module.css +10 -0
  115. package/src/layouts/rail/rail.tsx +62 -0
  116. package/src/layouts/rail/side/side.module.css +8 -0
  117. package/src/layouts/rail/side/side.tsx +25 -0
  118. package/src/layouts/rail/utility_strip/utility_strip.module.css +6 -0
  119. package/src/layouts/rail/utility_strip/utility_strip.tsx +40 -0
  120. package/src/layouts/scaffold/__stories__/scaffold.stories.tsx +53 -0
  121. package/src/layouts/scaffold/__stories__/scaffold_stories.module.css +31 -0
  122. package/src/layouts/scaffold/scaffold.module.css +4 -0
  123. package/src/layouts/table/__stories__/mock_data.ts +420 -0
  124. package/src/layouts/table/__stories__/table.stories.tsx +326 -0
  125. package/src/layouts/table/__stories__/table_stories.module.css +30 -0
  126. package/src/layouts/table/table.module.css +37 -0
  127. package/src/layouts/table/table.tsx +132 -0
  128. package/src/navigation/tabs/primitives/tabs_list.tsx +46 -2
  129. package/src/navigation/tabs/state/link/tab_link.tsx +4 -1
  130. package/src/navigation/tabs/state/tab.tsx +10 -0
  131. package/src/stacks/box/box.tsx +1 -1
  132. package/src/surfaces/modal/__stories__/modal.stories.tsx +5 -5
  133. package/src/surfaces/panel/__stories__/panel.stories.tsx +114 -1
  134. package/src/surfaces/pop_confirm/pop_confirm.stories.tsx +4 -2
  135. package/src/themes/themes/ergo/ergo_theme.css +178 -43
  136. package/dist/formatter-EIJCOSYU-D6nmx63h.js +0 -6
  137. package/dist/showcase-DK557szS.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { clsx } from 'clsx';
3
+ import { VStack, type VStackProps } from '../../../stacks/v_stack.js';
4
+
5
+ import styles from './side.module.css';
6
+
7
+ // UtilityBar
8
+ export interface SideProps extends Omit<VStackProps, 'as'> {}
9
+
10
+ export const Side = React.forwardRef<HTMLElement, SideProps>(function UtilityStrip(
11
+ { children, className, width = 'auto', ...props }: SideProps,
12
+ ref
13
+ ) {
14
+ return (
15
+ <VStack
16
+ ref={ref}
17
+ className={clsx(styles['side'], 'tcn-side', className)}
18
+ as="section"
19
+ width={width}
20
+ {...props}
21
+ >
22
+ {children}
23
+ </VStack>
24
+ );
25
+ });
@@ -0,0 +1,6 @@
1
+ @layer tcn-system {
2
+ :where(.utility-strip) {
3
+ height: 100%;
4
+ min-width: 0;
5
+ }
6
+ }
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { clsx } from 'clsx';
3
+ import type { Hierarchy, Size } from '../../../utils/index.js';
4
+ import { VStack, type VStackProps } from '../../../stacks/v_stack.js';
5
+
6
+ import styles from './utility_strip.module.css';
7
+
8
+ // UtilityBar
9
+ export interface UtilityStripProps extends Omit<VStackProps, 'as'> {
10
+ hierarchy?: Hierarchy;
11
+ size?: Size;
12
+ }
13
+
14
+ export const UtilityStrip = React.forwardRef<HTMLElement, UtilityStripProps>(
15
+ function UtilityStrip(
16
+ {
17
+ children,
18
+ className,
19
+ width = 'auto',
20
+ hierarchy = 'secondary',
21
+ size = 'md',
22
+ ...props
23
+ }: UtilityStripProps,
24
+ ref
25
+ ) {
26
+ return (
27
+ <VStack
28
+ ref={ref}
29
+ as="header"
30
+ className={clsx(styles['utility-strip'], 'tcn-utility-strip', className)}
31
+ data-hierarchy={hierarchy}
32
+ data-size={size}
33
+ width={width}
34
+ {...props}
35
+ >
36
+ {children}
37
+ </VStack>
38
+ );
39
+ }
40
+ );
@@ -0,0 +1,53 @@
1
+ import { Scaffold } from '../scaffold.js';
2
+ import { Header } from '../../header/header.js';
3
+ import { UtilityBar } from '../../utility_bar/utility_bar.js';
4
+ import { VBody } from '../../body/v_body.js';
5
+ import { Footer } from '../../footer/footer.js';
6
+ import type { Meta, StoryObj } from '@storybook/react-vite';
7
+ import { HStack } from '../../../stacks/h_stack.js';
8
+
9
+ import styles from './scaffold_stories.module.css';
10
+
11
+ const meta: Meta<typeof Scaffold> = {
12
+ title: 'Layouts/Scaffold',
13
+ component: Scaffold,
14
+ tags: ['autodocs'],
15
+ parameters: {
16
+ docs: {
17
+ description: {
18
+ component: 'A scaffold component that lays out content in a vertical hierarchy.',
19
+ },
20
+ },
21
+ },
22
+ };
23
+
24
+ export default meta;
25
+
26
+ type Story = StoryObj<typeof Scaffold>;
27
+
28
+ const Content = () => {
29
+ return <HStack className={styles.content} />;
30
+ };
31
+
32
+ export const Baseline: Story = {
33
+ args: {
34
+ height: '100vh',
35
+ },
36
+ render: () => (
37
+ <Scaffold height="100vh">
38
+ <Header className={styles.header}>Header</Header>
39
+ <UtilityBar className={styles.utilityBar}>Utility Bar</UtilityBar>
40
+ <VBody className={styles.body}>
41
+ <p>(V)Body</p>
42
+ <p>Fills available space</p>
43
+ <p>Scrolls vertically</p>
44
+ <Content />
45
+ <Content />
46
+ <Content />
47
+ <Content />
48
+ <Content />
49
+ </VBody>
50
+ <Footer className={styles.footer}>Footer</Footer>
51
+ </Scaffold>
52
+ ),
53
+ };
@@ -0,0 +1,31 @@
1
+ .header {
2
+ height: 56px;
3
+ background-color: #3b82f6;
4
+ color: white;
5
+ }
6
+
7
+ .utilityBar {
8
+ height: 40px;
9
+ background-color: #8b5cf6;
10
+ color: white;
11
+ }
12
+
13
+ .body {
14
+ background-color: #f1f5f9;
15
+ }
16
+
17
+ .footer {
18
+ height: 48px;
19
+ background-color: #10b981;
20
+ color: white;
21
+ }
22
+
23
+ .level {
24
+ background-color: #0ab4d2;
25
+ color: white;
26
+ }
27
+
28
+ .content {
29
+ background-color: #e5e7eb;
30
+ height: 100px;
31
+ }
@@ -3,5 +3,9 @@
3
3
  width: 100%;
4
4
  height: 100%;
5
5
  overflow: auto;
6
+ :where(.tcn-main) {
7
+ height: auto;
8
+ background: black !important;
9
+ }
6
10
  }
7
11
  }
@@ -0,0 +1,420 @@
1
+ export enum SBTableDataStatus {
2
+ COMPLETED = 'completed',
3
+ IN_PROGRESS = 'in_progress',
4
+ NOT_STARTED = 'not_started',
5
+ FAILED = 'failed',
6
+ }
7
+
8
+ export const sb_tableStatusLabels: Record<SBTableDataStatus, string> = {
9
+ [SBTableDataStatus.NOT_STARTED]: 'Not Started',
10
+ [SBTableDataStatus.IN_PROGRESS]: 'In Progress',
11
+ [SBTableDataStatus.COMPLETED]: 'Completed',
12
+ [SBTableDataStatus.FAILED]: 'Failed',
13
+ };
14
+
15
+ export const sb_tableStatusColors: Record<SBTableDataStatus, string> = {
16
+ [SBTableDataStatus.COMPLETED]: 'var(--async-color-success)',
17
+ [SBTableDataStatus.IN_PROGRESS]: 'var(--async-color-pending)',
18
+ [SBTableDataStatus.NOT_STARTED]: 'var(--async-color-initial)',
19
+ [SBTableDataStatus.FAILED]: 'var(--async-color-failed)',
20
+ };
21
+
22
+ export interface SBTableData {
23
+ name: string;
24
+ description: string;
25
+ age: number;
26
+ date: Date;
27
+ status: SBTableDataStatus;
28
+ selected?: boolean;
29
+ }
30
+
31
+ export const sb_tableMockData: SBTableData[] = [
32
+ {
33
+ name: 'Project 1',
34
+ description: 'Description 1',
35
+ age: 10,
36
+ date: new Date('2021-01-01'),
37
+ status: SBTableDataStatus.COMPLETED,
38
+ },
39
+ {
40
+ name: 'Project 2',
41
+ description: 'Description 2',
42
+ age: 22,
43
+ date: new Date('2021-02-15'),
44
+ status: SBTableDataStatus.IN_PROGRESS,
45
+ },
46
+ {
47
+ name: 'Project 3',
48
+ description: 'Description 3',
49
+ age: 34,
50
+ date: new Date('2021-03-20'),
51
+ status: SBTableDataStatus.FAILED,
52
+ },
53
+ {
54
+ name: 'Project 4',
55
+ description: 'Description 4',
56
+ age: 18,
57
+ date: new Date('2021-04-10'),
58
+ status: SBTableDataStatus.COMPLETED,
59
+ selected: true,
60
+ },
61
+ {
62
+ name: 'Project 5',
63
+ description: 'Description 5',
64
+ age: 45,
65
+ date: new Date('2021-05-05'),
66
+ status: SBTableDataStatus.IN_PROGRESS,
67
+ },
68
+ {
69
+ name: 'Project 6',
70
+ description: 'Description 6',
71
+ age: 29,
72
+ date: new Date('2021-06-22'),
73
+ status: SBTableDataStatus.NOT_STARTED,
74
+ },
75
+ {
76
+ name: 'Project 7',
77
+ description: 'Description 7',
78
+ age: 31,
79
+ date: new Date('2021-07-14'),
80
+ status: SBTableDataStatus.IN_PROGRESS,
81
+ },
82
+ {
83
+ name: 'Project 8',
84
+ description: 'Description 8',
85
+ age: 27,
86
+ date: new Date('2021-08-30'),
87
+ status: SBTableDataStatus.FAILED,
88
+ },
89
+ {
90
+ name: 'Project 9',
91
+ description: 'Description 9',
92
+ age: 52,
93
+ date: new Date('2021-09-01'),
94
+ status: SBTableDataStatus.NOT_STARTED,
95
+ },
96
+ {
97
+ name: 'Project 10',
98
+ description: 'Description 10',
99
+ age: 19,
100
+ date: new Date('2021-10-12'),
101
+ status: SBTableDataStatus.IN_PROGRESS,
102
+ },
103
+ {
104
+ name: 'Project 11',
105
+ description: 'Description 11',
106
+ age: 38,
107
+ date: new Date('2021-11-08'),
108
+ status: SBTableDataStatus.IN_PROGRESS,
109
+ },
110
+ {
111
+ name: 'Project 12',
112
+ description: 'Description 12',
113
+ age: 41,
114
+ date: new Date('2021-12-25'),
115
+ status: SBTableDataStatus.NOT_STARTED,
116
+ },
117
+ {
118
+ name: 'Project 13',
119
+ description: 'Description 13',
120
+ age: 24,
121
+ date: new Date('2022-01-03'),
122
+ status: SBTableDataStatus.IN_PROGRESS,
123
+ },
124
+ {
125
+ name: 'Project 14',
126
+ description: 'Description 14',
127
+ age: 33,
128
+ date: new Date('2022-02-18'),
129
+ status: SBTableDataStatus.FAILED,
130
+ },
131
+ {
132
+ name: 'Project 15',
133
+ description: 'Description 15',
134
+ age: 56,
135
+ date: new Date('2022-03-09'),
136
+ status: SBTableDataStatus.NOT_STARTED,
137
+ },
138
+ {
139
+ name: 'Project 16',
140
+ description: 'Description 16',
141
+ age: 21,
142
+ date: new Date('2022-04-27'),
143
+ status: SBTableDataStatus.COMPLETED,
144
+ },
145
+ {
146
+ name: 'Project 17',
147
+ description: 'Description 17',
148
+ age: 47,
149
+ date: new Date('2022-05-11'),
150
+ status: SBTableDataStatus.IN_PROGRESS,
151
+ },
152
+ {
153
+ name: 'Project 18',
154
+ description: 'Description 18',
155
+ age: 30,
156
+ date: new Date('2022-06-06'),
157
+ status: SBTableDataStatus.NOT_STARTED,
158
+ },
159
+ {
160
+ name: 'Project 19',
161
+ description: 'Description 19',
162
+ age: 25,
163
+ date: new Date('2022-07-19'),
164
+ status: SBTableDataStatus.COMPLETED,
165
+ },
166
+ {
167
+ name: 'Project 20',
168
+ description: 'Description 20',
169
+ age: 39,
170
+ date: new Date('2022-08-02'),
171
+ status: SBTableDataStatus.IN_PROGRESS,
172
+ },
173
+ {
174
+ name: 'Project 21',
175
+ description: 'Description 21',
176
+ age: 43,
177
+ date: new Date('2022-09-14'),
178
+ status: SBTableDataStatus.FAILED,
179
+ },
180
+ {
181
+ name: 'Project 22',
182
+ description: 'Description 22',
183
+ age: 28,
184
+ date: new Date('2022-10-31'),
185
+ status: SBTableDataStatus.COMPLETED,
186
+ },
187
+ {
188
+ name: 'Project 23',
189
+ description: 'Description 23',
190
+ age: 35,
191
+ date: new Date('2022-11-20'),
192
+ status: SBTableDataStatus.IN_PROGRESS,
193
+ },
194
+ {
195
+ name: 'Project 24',
196
+ description: 'Description 24',
197
+ age: 50,
198
+ date: new Date('2022-12-01'),
199
+ status: SBTableDataStatus.NOT_STARTED,
200
+ },
201
+ {
202
+ name: 'Project 25',
203
+ description: 'Description 25',
204
+ age: 26,
205
+ date: new Date('2023-01-17'),
206
+ status: SBTableDataStatus.COMPLETED,
207
+ },
208
+ {
209
+ name: 'Project 26',
210
+ description: 'Description 26',
211
+ age: 44,
212
+ date: new Date('2023-02-28'),
213
+ status: SBTableDataStatus.IN_PROGRESS,
214
+ },
215
+ {
216
+ name: 'Project 27',
217
+ description: 'Description 27',
218
+ age: 37,
219
+ date: new Date('2023-03-12'),
220
+ status: SBTableDataStatus.FAILED,
221
+ },
222
+ {
223
+ name: 'Project 28',
224
+ description: 'Description 28',
225
+ age: 23,
226
+ date: new Date('2023-04-05'),
227
+ status: SBTableDataStatus.COMPLETED,
228
+ },
229
+ {
230
+ name: 'Project 29',
231
+ description: 'Description 29',
232
+ age: 48,
233
+ date: new Date('2023-05-22'),
234
+ status: SBTableDataStatus.IN_PROGRESS,
235
+ },
236
+ {
237
+ name: 'Project 30',
238
+ description: 'Description 30',
239
+ age: 32,
240
+ date: new Date('2023-06-15'),
241
+ status: SBTableDataStatus.NOT_STARTED,
242
+ },
243
+ ];
244
+
245
+ /** Row shape for tables with grouped headers (e.g. Personal Info, Employment, Performance + Actions) */
246
+ export interface SBTableGroupedRow {
247
+ firstName: string;
248
+ lastName: string;
249
+ department: string;
250
+ branch: string;
251
+ role: string;
252
+ q1: number;
253
+ q2: number;
254
+ q3: number;
255
+ q4: number;
256
+ score: number;
257
+ lastReview: string;
258
+ }
259
+
260
+ export const sb_tableGroupedMockData: SBTableGroupedRow[] = [
261
+ {
262
+ firstName: 'Jordan',
263
+ lastName: 'Lee',
264
+ branch: 'San Francisco',
265
+ department: 'Engineering',
266
+ role: 'Software Engineer',
267
+ q1: 92,
268
+ q2: 88,
269
+ q3: 95,
270
+ q4: 85,
271
+ score: (92 + 88 + 95 + 85) / 4,
272
+ lastReview: '2024-01-15',
273
+ },
274
+ {
275
+ firstName: 'Sam',
276
+ lastName: 'Kim',
277
+ branch: 'Seattle',
278
+ department: 'Product',
279
+ role: 'Product Manager',
280
+ q1: 88,
281
+ q2: 92,
282
+ q3: 85,
283
+ q4: 90,
284
+ score: (88 + 92 + 85 + 90) / 4,
285
+ lastReview: '2024-02-01',
286
+ },
287
+ {
288
+ firstName: 'Alex',
289
+ lastName: 'Chen',
290
+ branch: 'San Francisco',
291
+ department: 'Engineering',
292
+ role: 'Staff Engineer',
293
+ q1: 95,
294
+ q2: 90,
295
+ q3: 88,
296
+ q4: 92,
297
+ score: (95 + 90 + 88 + 92) / 4,
298
+ lastReview: '2024-01-20',
299
+ },
300
+ {
301
+ firstName: 'Morgan',
302
+ lastName: 'Taylor',
303
+ branch: 'Seattle',
304
+ department: 'Design',
305
+ role: 'UX Designer',
306
+ q1: 85,
307
+ q2: 90,
308
+ q3: 88,
309
+ q4: 92,
310
+ score: (85 + 90 + 88 + 92) / 4,
311
+ lastReview: '2023-12-10',
312
+ },
313
+ {
314
+ firstName: 'Riley',
315
+ lastName: 'Brown',
316
+ branch: 'San Francisco',
317
+ department: 'Engineering',
318
+ role: 'QA Engineer',
319
+ q1: 79,
320
+ q2: 82,
321
+ q3: 85,
322
+ q4: 88,
323
+ score: (79 + 82 + 85 + 88) / 4,
324
+ lastReview: '2024-02-15',
325
+ },
326
+ {
327
+ firstName: 'Casey',
328
+ lastName: 'Davis',
329
+ branch: 'Seattle',
330
+ department: 'Product',
331
+ role: 'Analyst',
332
+ q1: 82,
333
+ q2: 85,
334
+ q3: 88,
335
+ q4: 90,
336
+ score: (82 + 85 + 88 + 90) / 4,
337
+ lastReview: '2024-01-05',
338
+ },
339
+ {
340
+ firstName: 'Jamie',
341
+ lastName: 'Wilson',
342
+ branch: 'San Francisco',
343
+ department: 'Design',
344
+ role: 'Design Lead',
345
+ q1: 90,
346
+ q2: 92,
347
+ q3: 88,
348
+ q4: 90,
349
+ score: (90 + 92 + 88 + 90) / 4,
350
+ lastReview: '2024-02-20',
351
+ },
352
+ {
353
+ firstName: 'Quinn',
354
+ lastName: 'Martinez',
355
+ branch: 'Seattle',
356
+ department: 'Engineering',
357
+ role: 'DevOps',
358
+ q1: 87,
359
+ q2: 88,
360
+ q3: 89,
361
+ q4: 90,
362
+ score: (87 + 88 + 89 + 90) / 4,
363
+ lastReview: '2024-01-28',
364
+ },
365
+ {
366
+ firstName: 'Reese',
367
+ lastName: 'Anderson',
368
+ branch: 'San Francisco',
369
+ department: 'Product',
370
+ role: 'Intern',
371
+ q1: 76,
372
+ q2: 80,
373
+ q3: 84,
374
+ q4: 88,
375
+ score: (76 + 80 + 84 + 88) / 4,
376
+ lastReview: '2024-02-01',
377
+ },
378
+ {
379
+ firstName: 'Skyler',
380
+ lastName: 'Thomas',
381
+ branch: 'Seattle',
382
+ department: 'Design',
383
+ role: 'Researcher',
384
+ q1: 84,
385
+ q2: 88,
386
+ q3: 86,
387
+ q4: 89,
388
+ score: (84 + 88 + 86 + 89) / 4,
389
+ lastReview: '2023-11-30',
390
+ },
391
+ ];
392
+
393
+ function buildStats(data: SBTableGroupedRow[]) {
394
+ const totals = data.reduce(
395
+ (acc, curr) => {
396
+ return {
397
+ q1: acc.q1 + curr.q1,
398
+ q2: acc.q2 + curr.q2,
399
+ q3: acc.q3 + curr.q3,
400
+ q4: acc.q4 + curr.q4,
401
+ };
402
+ },
403
+ { q1: 0, q2: 0, q3: 0, q4: 0 }
404
+ );
405
+
406
+ const averages = {
407
+ q1: totals.q1 / data.length,
408
+ q2: totals.q2 / data.length,
409
+ q3: totals.q3 / data.length,
410
+ q4: totals.q4 / data.length,
411
+ };
412
+
413
+ const year = averages.q1 + averages.q2 + averages.q3 + averages.q4;
414
+
415
+ const mean = year / 4;
416
+
417
+ return { totals, averages, year, mean };
418
+ }
419
+
420
+ export const sb_tableGroupedStats = buildStats(sb_tableGroupedMockData);