@tcn/ui 0.16.0 → 0.17.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 (185) hide show
  1. package/dist/card.css +1 -0
  2. package/dist/column.css +1 -1
  3. package/dist/containers.css +1 -1
  4. package/dist/containers.module-BmICKsOK.js +5 -0
  5. package/dist/containers.module-BmICKsOK.js.map +1 -0
  6. package/dist/form/field/field.js +11 -8
  7. package/dist/form/field/field.js.map +1 -1
  8. package/dist/inputs/color_input/color_picker.js +5 -2
  9. package/dist/inputs/color_input/color_picker.js.map +1 -1
  10. package/dist/inputs/combo_box/combo_box.js +18 -15
  11. package/dist/inputs/combo_box/combo_box.js.map +1 -1
  12. package/dist/inputs/date_picker/date_picker.js +13 -10
  13. package/dist/inputs/date_picker/date_picker.js.map +1 -1
  14. package/dist/inputs/date_picker/date_picker_input.js +20 -17
  15. package/dist/inputs/date_picker/date_picker_input.js.map +1 -1
  16. package/dist/inputs/date_picker/date_picker_year_selector.js +5 -2
  17. package/dist/inputs/date_picker/date_picker_year_selector.js.map +1 -1
  18. package/dist/inputs/mask_input/key_capture_input.js +26 -23
  19. package/dist/inputs/mask_input/key_capture_input.js.map +1 -1
  20. package/dist/inputs/mask_input/mask_input.js +5 -2
  21. package/dist/inputs/mask_input/mask_input.js.map +1 -1
  22. package/dist/inputs/multiselect/multiselect.js +22 -19
  23. package/dist/inputs/multiselect/multiselect.js.map +1 -1
  24. package/dist/inputs/phone_number_input/phone_number_context.js +7 -4
  25. package/dist/inputs/phone_number_input/phone_number_context.js.map +1 -1
  26. package/dist/inputs/select/select.js +5 -2
  27. package/dist/inputs/select/select.js.map +1 -1
  28. package/dist/inputs/slider/slider.js +19 -16
  29. package/dist/inputs/slider/slider.js.map +1 -1
  30. package/dist/inputs/suggestions/suggestion_list.js +5 -2
  31. package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
  32. package/dist/inputs/switch/switch.js +18 -15
  33. package/dist/inputs/switch/switch.js.map +1 -1
  34. package/dist/inputs/unit_input/unit_input.js +15 -12
  35. package/dist/inputs/unit_input/unit_input.js.map +1 -1
  36. package/dist/layouts/containers/columns/columns.d.ts +6 -1
  37. package/dist/layouts/containers/columns/columns.d.ts.map +1 -1
  38. package/dist/layouts/containers/columns/columns.js +30 -7
  39. package/dist/layouts/containers/columns/columns.js.map +1 -1
  40. package/dist/layouts/containers/rail.d.ts +2 -5
  41. package/dist/layouts/containers/rail.d.ts.map +1 -1
  42. package/dist/layouts/containers/rail.js +17 -55
  43. package/dist/layouts/containers/rail.js.map +1 -1
  44. package/dist/layouts/containers/rows/index.d.ts +3 -0
  45. package/dist/layouts/containers/rows/index.d.ts.map +1 -0
  46. package/dist/layouts/containers/rows/index.js +7 -0
  47. package/dist/layouts/containers/rows/index.js.map +1 -0
  48. package/dist/layouts/containers/rows/row.d.ts +6 -0
  49. package/dist/layouts/containers/rows/row.d.ts.map +1 -0
  50. package/dist/layouts/containers/rows/row.js +20 -0
  51. package/dist/layouts/containers/rows/row.js.map +1 -0
  52. package/dist/layouts/containers/rows/rows.d.ts +11 -0
  53. package/dist/layouts/containers/rows/rows.d.ts.map +1 -0
  54. package/dist/layouts/containers/rows/rows.js +34 -0
  55. package/dist/layouts/containers/rows/rows.js.map +1 -0
  56. package/dist/layouts/containers/scaffold.d.ts +2 -5
  57. package/dist/layouts/containers/scaffold.d.ts.map +1 -1
  58. package/dist/layouts/containers/scaffold.js +17 -55
  59. package/dist/layouts/containers/scaffold.js.map +1 -1
  60. package/dist/layouts/index.d.ts +2 -0
  61. package/dist/layouts/index.d.ts.map +1 -1
  62. package/dist/layouts/index.js +26 -22
  63. package/dist/layouts/index.js.map +1 -1
  64. package/dist/mobile/inputs/date_picker/mobile_date_picker_header.js +5 -2
  65. package/dist/mobile/inputs/date_picker/mobile_date_picker_header.js.map +1 -1
  66. package/dist/mobile/inputs/date_picker/mobile_date_picker_input.js +5 -2
  67. package/dist/mobile/inputs/date_picker/mobile_date_picker_input.js.map +1 -1
  68. package/dist/mobile/inputs/date_picker/mobile_date_picker_year_selector.js +8 -5
  69. package/dist/mobile/inputs/date_picker/mobile_date_picker_year_selector.js.map +1 -1
  70. package/dist/navigation/tabs/state/link/tab_link.js +9 -6
  71. package/dist/navigation/tabs/state/link/tab_link.js.map +1 -1
  72. package/dist/overlay/menu/menu.js +3 -0
  73. package/dist/overlay/menu/menu.js.map +1 -1
  74. package/dist/overlay/popper/context_popper.js +8 -5
  75. package/dist/overlay/popper/context_popper.js.map +1 -1
  76. package/dist/overlay/popper/element_popper.js +9 -6
  77. package/dist/overlay/popper/element_popper.js.map +1 -1
  78. package/dist/overlay/popper/legacy/popper.js +13 -10
  79. package/dist/overlay/popper/legacy/popper.js.map +1 -1
  80. package/dist/overlay/popper/preview_popper.js +10 -7
  81. package/dist/overlay/popper/preview_popper.js.map +1 -1
  82. package/dist/overlay/tethered/tethered.js +11 -8
  83. package/dist/overlay/tethered/tethered.js.map +1 -1
  84. package/dist/resizable.css +1 -0
  85. package/dist/resizable.module-I6iyBAvM.js +5 -0
  86. package/dist/resizable.module-I6iyBAvM.js.map +1 -0
  87. package/dist/resize_handle.css +1 -0
  88. package/dist/row.css +1 -0
  89. package/dist/stacks/box/box.js +12 -9
  90. package/dist/stacks/box/box.js.map +1 -1
  91. package/dist/stacks/box/detect_resize_bounds.d.ts +1 -0
  92. package/dist/stacks/box/detect_resize_bounds.d.ts.map +1 -1
  93. package/dist/stacks/box/detect_resize_bounds.js +22 -20
  94. package/dist/stacks/box/detect_resize_bounds.js.map +1 -1
  95. package/dist/stacks/h_collapsible_box.js +17 -14
  96. package/dist/stacks/h_collapsible_box.js.map +1 -1
  97. package/dist/stacks/v_collapsible_box.js +19 -16
  98. package/dist/stacks/v_collapsible_box.js.map +1 -1
  99. package/dist/surfaces/card/card.d.ts.map +1 -1
  100. package/dist/surfaces/card/card.js +14 -6
  101. package/dist/surfaces/card/card.js.map +1 -1
  102. package/dist/surfaces/pop_confirm/pop_confirm.js +4 -2
  103. package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
  104. package/dist/test-setup.d.ts +2 -0
  105. package/dist/test-setup.d.ts.map +1 -0
  106. package/dist/test-setup.js +10 -0
  107. package/dist/test-setup.js.map +1 -0
  108. package/dist/themes/theme.d.ts.map +1 -1
  109. package/dist/themes/theme.js +17 -22
  110. package/dist/themes/theme.js.map +1 -1
  111. package/dist/themes/themes/ergo/ergo_theme.css +1 -1
  112. package/dist/themes/themes/ergo/ergo_theme.js +201 -21
  113. package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
  114. package/dist/utils/index.d.ts +1 -0
  115. package/dist/utils/index.d.ts.map +1 -1
  116. package/dist/utils/index.js +39 -26
  117. package/dist/utils/index.js.map +1 -1
  118. package/dist/utils/resize/context.d.ts +4 -0
  119. package/dist/utils/resize/context.d.ts.map +1 -0
  120. package/dist/utils/resize/context.js +10 -0
  121. package/dist/utils/resize/context.js.map +1 -0
  122. package/dist/utils/resize/handle_config.d.ts +32 -0
  123. package/dist/utils/resize/handle_config.d.ts.map +1 -0
  124. package/dist/utils/resize/handle_config.js +85 -0
  125. package/dist/utils/resize/handle_config.js.map +1 -0
  126. package/dist/utils/resize/index.d.ts +10 -0
  127. package/dist/utils/resize/index.d.ts.map +1 -0
  128. package/dist/utils/resize/index.js +16 -0
  129. package/dist/utils/resize/index.js.map +1 -0
  130. package/dist/utils/resize/resizable.d.ts +11 -0
  131. package/dist/utils/resize/resizable.d.ts.map +1 -0
  132. package/dist/utils/resize/resizable.js +52 -0
  133. package/dist/utils/resize/resizable.js.map +1 -0
  134. package/dist/utils/resize/resize_handle.d.ts +7 -0
  135. package/dist/utils/resize/resize_handle.d.ts.map +1 -0
  136. package/dist/utils/resize/resize_handle.js +100 -0
  137. package/dist/utils/resize/resize_handle.js.map +1 -0
  138. package/dist/utils/resize/resize_strategy.d.ts +47 -0
  139. package/dist/utils/resize/resize_strategy.d.ts.map +1 -0
  140. package/dist/utils/resize/resize_strategy.js +108 -0
  141. package/dist/utils/resize/resize_strategy.js.map +1 -0
  142. package/dist/utils/resize/types.d.ts +28 -0
  143. package/dist/utils/resize/types.d.ts.map +1 -0
  144. package/dist/utils/resize/types.js +2 -0
  145. package/dist/utils/resize/types.js.map +1 -0
  146. package/package.json +3 -3
  147. package/src/layouts/__stories__/columns.stories.tsx +31 -0
  148. package/src/layouts/__stories__/composed.stories.tsx +77 -8
  149. package/src/layouts/__stories__/rows.stories.tsx +77 -0
  150. package/src/layouts/__stories__/utils.tsx +2 -84
  151. package/src/layouts/containers/columns/column.module.css +3 -2
  152. package/src/layouts/containers/columns/columns.tsx +29 -3
  153. package/src/layouts/containers/containers.module.css +27 -29
  154. package/src/layouts/containers/rail.tsx +9 -51
  155. package/src/layouts/containers/rows/index.ts +2 -0
  156. package/src/layouts/containers/rows/row.module.css +15 -0
  157. package/src/layouts/containers/rows/row.tsx +22 -0
  158. package/src/layouts/containers/rows/rows.tsx +42 -0
  159. package/src/layouts/containers/scaffold.tsx +9 -49
  160. package/src/layouts/index.ts +2 -0
  161. package/src/stacks/box/detect_resize_bounds.ts +5 -1
  162. package/src/surfaces/card/card.module.css +5 -0
  163. package/src/surfaces/card/card.stories.tsx +66 -8
  164. package/src/surfaces/card/card.tsx +6 -2
  165. package/src/surfaces/page/page.stories.tsx +84 -4
  166. package/src/surfaces/panel/__stories__/panel.stories.tsx +84 -9
  167. package/src/test-setup.ts +11 -0
  168. package/src/themes/theme.tsx +6 -16
  169. package/src/themes/themes/ergo/ergo_theme.css +199 -19
  170. package/src/utils/index.ts +2 -0
  171. package/src/utils/resize/__stories__/resizable.stories.tsx +214 -0
  172. package/src/utils/resize/__stories__/resizable_stories.module.css +47 -0
  173. package/src/utils/resize/__tests__/handle_config.test.ts +269 -0
  174. package/src/utils/resize/__tests__/resize_strategy.test.ts +163 -0
  175. package/src/utils/resize/context.ts +9 -0
  176. package/src/utils/resize/handle_config.ts +142 -0
  177. package/src/utils/resize/index.ts +37 -0
  178. package/src/utils/resize/resizable.module.css +5 -0
  179. package/src/utils/resize/resizable.tsx +97 -0
  180. package/src/utils/resize/resize_handle.module.css +146 -0
  181. package/src/utils/resize/resize_handle.tsx +165 -0
  182. package/src/utils/resize/resize_strategy.ts +190 -0
  183. package/src/utils/resize/types.ts +64 -0
  184. package/dist/containers.module-DlGySre0.js +0 -5
  185. package/dist/containers.module-DlGySre0.js.map +0 -1
@@ -6,7 +6,10 @@ import { Box, Spacer } from '../../stacks/index.js';
6
6
  import { Title } from '../../typography/title/title.js';
7
7
  import { Button } from '../../actions/index.js';
8
8
  import { Card } from './card.js';
9
- import { Scaffold } from '../../layouts/index.js';
9
+ import { Detail, Row, Rows, Scaffold } from '../../layouts/index.js';
10
+ import { Key } from '../../tokens/key/key.js';
11
+ import { Term } from '../../tokens/term/term.js';
12
+ import { Value } from '../../tokens/value/value.js';
10
13
 
11
14
  // Styles
12
15
  import styles from './card_stories.module.css';
@@ -52,13 +55,68 @@ export const Default = () => {
52
55
  <Box className={styles['content-box']} />
53
56
  <Box className={styles['content-box']} />
54
57
  </Scaffold>
55
- {/* Cards typically do not have a footer */}
56
- {/* <Footer>
57
- <Title>Footer</Title>
58
- <Spacer />
59
- <Button hierarchy="secondary">Secondary</Button>
60
- <Button hierarchy="primary">Primary</Button>
61
- </Footer> */}
58
+ </Card>
59
+ </div>
60
+ );
61
+ };
62
+
63
+ /**
64
+ * Rows inside a Card body. Fixed-height rows stack vertically with a
65
+ * fill row consuming remaining space — mirrors the Login Information
66
+ * card pattern from the app.
67
+ */
68
+ export const CardWithRows = () => {
69
+ return (
70
+ <div className={styles['stories-container']}>
71
+ <Card maxHeight="500px" maxWidth="400px">
72
+ <Header>
73
+ <Title>Login Information</Title>
74
+ </Header>
75
+ <Scaffold>
76
+ <Rows>
77
+ <Row>
78
+ <Detail>
79
+ <Term>
80
+ <Key>Username:</Key>
81
+ <Value>1026223MinhtestCreateAgent1</Value>
82
+ </Term>
83
+ <Term>
84
+ <Key>Email:</Key>
85
+ <Value severity="encouraged">jsmith@example.com</Value>
86
+ </Term>
87
+ </Detail>
88
+ </Row>
89
+
90
+ <Row>
91
+ <Detail>
92
+ <Term>
93
+ <Key>Force Password Reset:</Key>
94
+ <Value>No</Value>
95
+ </Term>
96
+ <Term>
97
+ <Key>Two-Factor Status:</Key>
98
+ <Value severity="encouraged">Enabled</Value>
99
+ </Term>
100
+ <Term>
101
+ <Key>Two-Factor Type:</Key>
102
+ <Value>Email</Value>
103
+ </Term>
104
+ </Detail>
105
+ </Row>
106
+ <Row>
107
+ <Detail>
108
+ <Term>
109
+ <Key>Access Token:</Key>
110
+ <Value>••••••••••••</Value>
111
+ </Term>
112
+ <Term>
113
+ <Key>Expiration Date:</Key>
114
+ <Value>02/27/2024</Value>
115
+ </Term>
116
+ </Detail>
117
+ </Row>
118
+ </Rows>
119
+ </Scaffold>
62
120
  </Card>
63
121
  </div>
64
122
  );
@@ -1,7 +1,7 @@
1
1
  import { clsx } from 'clsx';
2
2
  import React from 'react';
3
3
  import { Scaffold, type ScaffoldProps } from '../../layouts/containers/scaffold.js';
4
-
4
+ import styles from './card.module.css';
5
5
  export interface CardProps extends Omit<ScaffoldProps, 'as' | 'children'> {
6
6
  children?: React.ReactNode;
7
7
  }
@@ -11,7 +11,11 @@ export const Card = React.forwardRef<HTMLElement, CardProps>(function Card(
11
11
  ref
12
12
  ) {
13
13
  return (
14
- <Scaffold ref={ref} className={clsx(className, 'tcn-surface', 'tcn-card')} {...props}>
14
+ <Scaffold
15
+ ref={ref}
16
+ className={clsx(className, styles.card, 'tcn-surface', 'tcn-card')}
17
+ {...props}
18
+ >
15
19
  {children}
16
20
  </Scaffold>
17
21
  );
@@ -1,3 +1,4 @@
1
+ import { useState } from 'react';
1
2
  import { Header } from '../../layouts/header/header.js';
2
3
  import { Detail, Footer, Scaffold } from '../../layouts/index.js';
3
4
  import { Column } from '../../layouts/containers/columns/column.js';
@@ -7,6 +8,10 @@ import { Title } from '../../typography/title/title.js';
7
8
  import { Page } from './page.js';
8
9
  import { ZStack } from '../../stacks/z_stack.js';
9
10
  import { Panel } from '../panel/panel.js';
11
+ import { Card } from '../card/card.js';
12
+ import { SBContent } from '../../layouts/__stories__/utils.js';
13
+ import { Resizable } from '../../utils/resize/resizable.js';
14
+ import { ResizeHandle } from '../../utils/resize/resize_handle.js';
10
15
 
11
16
  export default {
12
17
  title: 'Surfaces/Page',
@@ -40,14 +45,38 @@ export const WithColumns = () => {
40
45
  <ZStack height="100%" width="100%" minHeight="600px" minWidth="600px">
41
46
  <Page>
42
47
  <Columns>
48
+ <Column minWidth="400px">
49
+ <Scaffold>
50
+ <Header>
51
+ <Title>Tooling Header</Title>
52
+ </Header>
53
+ <Scaffold>
54
+ <Detail>
55
+ <Card>
56
+ <Header>Tooling 1</Header>
57
+ <Scaffold>
58
+ <SBContent />
59
+ </Scaffold>
60
+ </Card>
61
+
62
+ <Card>
63
+ <Header>Tooling 2</Header>
64
+ <Scaffold>
65
+ <SBContent />
66
+ </Scaffold>
67
+ </Card>
68
+ </Detail>
69
+ </Scaffold>
70
+ </Scaffold>
71
+ </Column>
43
72
  <Column minWidth="400px" width="fill">
44
73
  <Panel>
45
74
  <Header>
46
- <Title>Left Panel</Title>
75
+ <Title>Primary</Title>
47
76
  </Header>
48
77
  <Scaffold>
49
78
  <Detail>
50
- <BodyText>Left panel content</BodyText>
79
+ <BodyText>Content</BodyText>
51
80
  </Detail>
52
81
  </Scaffold>
53
82
  </Panel>
@@ -55,15 +84,66 @@ export const WithColumns = () => {
55
84
  <Column minWidth="400px">
56
85
  <Panel>
57
86
  <Header>
58
- <Title>Right Panel</Title>
87
+ <Title>Secondary</Title>
88
+ </Header>
89
+ <Scaffold>
90
+ <Detail>
91
+ <BodyText>Content</BodyText>
92
+ </Detail>
93
+ </Scaffold>
94
+ </Panel>
95
+ </Column>
96
+ </Columns>
97
+ </Page>
98
+ </ZStack>
99
+ );
100
+ };
101
+
102
+ /** WIP: Testing Resizable + ResizeHandle with a two-column layout */
103
+ export const ResizableSecondaryColumn = () => {
104
+ const MIN_WIDTH = 200;
105
+ const MAX_WIDTH = 600;
106
+ const [secondaryWidth, setSecondaryWidth] = useState(350);
107
+
108
+ const atMin = secondaryWidth <= MIN_WIDTH;
109
+ const atMax = secondaryWidth >= MAX_WIDTH;
110
+ const constraint = atMin ? ' (At Min)' : atMax ? ' (At Max)' : '';
111
+
112
+ return (
113
+ <ZStack height="100%" width="100%" minHeight="600px" minWidth="600px">
114
+ <Page>
115
+ <Columns>
116
+ <Column width="fill">
117
+ <Panel>
118
+ <Header>
119
+ <Title>Primary</Title>
59
120
  </Header>
60
121
  <Scaffold>
61
122
  <Detail>
62
- <BodyText>Right panel content</BodyText>
123
+ <BodyText>Primary content fills remaining space.</BodyText>
63
124
  </Detail>
64
125
  </Scaffold>
65
126
  </Panel>
66
127
  </Column>
128
+ <Resizable onWidthResize={({ width }) => setSecondaryWidth(Math.round(width))}>
129
+ <Column
130
+ width={`${secondaryWidth}px`}
131
+ minWidth={`${MIN_WIDTH}px`}
132
+ maxWidth={`${MAX_WIDTH}px`}
133
+ >
134
+ <Panel>
135
+ <Header>
136
+ <Title>{`Secondary (${secondaryWidth}px)${constraint}`}</Title>
137
+ </Header>
138
+ <Scaffold>
139
+ <Detail>
140
+ <BodyText>Drag the left edge to resize this column.</BodyText>
141
+ </Detail>
142
+ </Scaffold>
143
+ </Panel>
144
+ </Column>
145
+ <ResizeHandle position="left" />
146
+ </Resizable>
67
147
  </Columns>
68
148
  </Page>
69
149
  </ZStack>
@@ -4,7 +4,7 @@ import { Footer } from '../../../layouts/footer/footer.js';
4
4
  import { Header } from '../../../layouts/header/header.js';
5
5
  import { Column } from '../../../layouts/containers/columns/column.js';
6
6
  import { Columns } from '../../../layouts/containers/columns/columns.js';
7
- import { Detail, Heading, Scaffold, Section } from '../../../layouts/index.js';
7
+ import { Detail, Heading, Row, Rows, Scaffold, Section } from '../../../layouts/index.js';
8
8
  import { UtilityBar } from '../../../layouts/utility_bar/utility_bar.js';
9
9
  import { Box, HStack, Spacer } from '../../../stacks/index.js';
10
10
  import { Title } from '../../../typography/title/title.js';
@@ -345,21 +345,19 @@ export const WithColumns = () => {
345
345
  <Heading>General</Heading>
346
346
  <Detail>
347
347
  <Term>
348
- <Key>Agent</Key>
349
- <Value>John Doe</Value>
348
+ <Key>Email</Key>
349
+ <Value>john.doe@example.com</Value>
350
350
  </Term>
351
351
  <Term>
352
- <Key>Queue</Key>
353
- <Value>Support</Value>
352
+ <Key>Phone</Key>
353
+ <Value>+1 555 000 1234</Value>
354
354
  </Term>
355
355
  <Term>
356
- <Key>Status</Key>
357
- <Value>Active</Value>
356
+ <Key>Start Date</Key>
357
+ <Value>05/27/2023</Value>
358
358
  </Term>
359
359
  </Detail>
360
360
  </Section>
361
- </Column>
362
- <Column minWidth="300px">
363
361
  <Section>
364
362
  <Heading>Contact</Heading>
365
363
  <Detail>
@@ -378,6 +376,83 @@ export const WithColumns = () => {
378
376
  </Detail>
379
377
  </Section>
380
378
  </Column>
379
+ <Column minWidth="300px">
380
+ <Rows>
381
+ <Row>
382
+ <Detail>
383
+ <Term>
384
+ <Key>Email</Key>
385
+ <Value>john.doe@example.com</Value>
386
+ </Term>
387
+ <Term>
388
+ <Key>Phone</Key>
389
+ <Value>+1 555 000 1234</Value>
390
+ </Term>
391
+ <Term>
392
+ <Key>Start Date</Key>
393
+ <Value>05/27/2023</Value>
394
+ </Term>
395
+ </Detail>
396
+ </Row>
397
+ <Row>
398
+ <Detail>
399
+ <Term>
400
+ <Key>Email</Key>
401
+ <Value>john.doe@example.com</Value>
402
+ </Term>
403
+ <Term>
404
+ <Key>Phone</Key>
405
+ <Value>+1 555 000 1234</Value>
406
+ </Term>
407
+ <Term>
408
+ <Key>Start Date</Key>
409
+ <Value>05/27/2023</Value>
410
+ </Term>
411
+ </Detail>
412
+ </Row>
413
+ </Rows>
414
+ </Column>
415
+ <Column minWidth="300px">
416
+ <Card>
417
+ <Header>General</Header>
418
+ <Scaffold>
419
+ <Detail>
420
+ <Term>
421
+ <Key>Email</Key>
422
+ <Value>john.doe@example.com</Value>
423
+ </Term>
424
+ <Term>
425
+ <Key>Phone</Key>
426
+ <Value>+1 555 000 1234</Value>
427
+ </Term>
428
+ <Term>
429
+ <Key>Start Date</Key>
430
+ <Value>05/27/2023</Value>
431
+ </Term>
432
+ </Detail>
433
+ </Scaffold>
434
+ </Card>
435
+
436
+ <Card>
437
+ <Header>Contact</Header>
438
+ <Scaffold>
439
+ <Detail>
440
+ <Term>
441
+ <Key>Email</Key>
442
+ <Value>john.doe@example.com</Value>
443
+ </Term>
444
+ <Term>
445
+ <Key>Phone</Key>
446
+ <Value>+1 555 000 1234</Value>
447
+ </Term>
448
+ <Term>
449
+ <Key>Start Date</Key>
450
+ <Value>05/27/2023</Value>
451
+ </Term>
452
+ </Detail>
453
+ </Scaffold>
454
+ </Card>
455
+ </Column>
381
456
  </Columns>
382
457
  </Scaffold>
383
458
  <Footer>
@@ -0,0 +1,11 @@
1
+ // ResizeObserver is not available in vitest's jsdom environment.
2
+ // `use_resize_observer.ts` instantiates a registry singleton at module load
3
+ // time, so this stub must be in place before any imports run.
4
+ globalThis.ResizeObserver = class ResizeObserver {
5
+ observe() {}
6
+ unobserve() {}
7
+ disconnect() {}
8
+ };
9
+
10
+ // Required for React's act() to work correctly in jsdom tests.
11
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
@@ -5,7 +5,6 @@ import { clsx } from 'clsx';
5
5
  // Styles
6
6
  import './stylesheets/reset.css';
7
7
  import styles from './theme_provider.module.css';
8
- import layers from '../css/layers.css?raw';
9
8
 
10
9
  export interface ThemeProps extends BoxProps {
11
10
  styleSheets: CSSStyleSheet[];
@@ -14,27 +13,18 @@ export interface ThemeProps extends BoxProps {
14
13
  }
15
14
 
16
15
  export function Theme({ styleSheets, children, className, ...boxProps }: ThemeProps) {
17
- useLayoutEffect(() => {
18
- document.adoptedStyleSheets = styleSheets;
19
- }, [styleSheets]);
16
+ const ref = React.useRef<HTMLElement>(null);
20
17
 
21
- // I used this approach instead to guarantee the order of the stylesheets
22
18
  useLayoutEffect(() => {
23
- if (document.getElementById('critical-css')) return;
24
-
25
- const style = document.createElement('style');
26
- style.id = 'critical-css';
27
- style.textContent = layers;
19
+ const root = ref.current?.getRootNode();
20
+ if (!root || !('adoptedStyleSheets' in root)) return;
28
21
 
29
- document.head.prepend(style);
30
-
31
- return () => {
32
- document.getElementById('critical-css')?.remove();
33
- };
34
- }, []);
22
+ (root as Document | ShadowRoot).adoptedStyleSheets = styleSheets;
23
+ }, [styleSheets]);
35
24
 
36
25
  return (
37
26
  <Box
27
+ ref={ref}
38
28
  className={clsx('tcn-theme-root', styles['tcn-theme-provider'], className)}
39
29
  {...boxProps}
40
30
  >